From 20e4567babc79546ec826707368eb736c128a8fe Mon Sep 17 00:00:00 2001 From: Diego Sueiro Date: Fri, 7 Dec 2018 10:00:46 +0000 Subject: [PATCH] shell: Add initial code for Character Framebuffer shell module This adds the config option and files of the Character Framebuffer shell module Signed-off-by: Diego Sueiro --- subsys/fb/CMakeLists.txt | 1 + subsys/fb/Kconfig | 17 ++ subsys/fb/cfb_shell.c | 470 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 488 insertions(+) create mode 100644 subsys/fb/cfb_shell.c diff --git a/subsys/fb/CMakeLists.txt b/subsys/fb/CMakeLists.txt index 1d92f7e9496..398a00d9b6b 100644 --- a/subsys/fb/CMakeLists.txt +++ b/subsys/fb/CMakeLists.txt @@ -1,2 +1,3 @@ zephyr_sources_ifdef(CONFIG_CHARACTER_FRAMEBUFFER cfb.c) zephyr_sources_ifdef(CONFIG_CHARACTER_FRAMEBUFFER_USE_DEFAULT_FONTS cfb_fonts.c) +zephyr_sources_ifdef(CONFIG_CHARACTER_FRAMEBUFFER_SHELL cfb_shell.c) diff --git a/subsys/fb/Kconfig b/subsys/fb/Kconfig index 9adaf10395e..e94a044a01e 100644 --- a/subsys/fb/Kconfig +++ b/subsys/fb/Kconfig @@ -21,6 +21,23 @@ config CHARACTER_FRAMEBUFFER_USE_DEFAULT_FONTS help Use default fonts. +config CHARACTER_FRAMEBUFFER_SHELL + bool "Character Framebuffer shell" + depends on SHELL + help + Activate shell module that provides Framebuffer commands to the + console. + +if CHARACTER_FRAMEBUFFER_SHELL + config CHARACTER_FRAMEBUFFER_SHELL_DRIVER_NAME + string + default "SSD1673" if SSD1673 + default "SSD1306" if SSD1306 + help + Character Framebuffer Display Driver Name + +endif + module = CFB module-str = cfb source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/fb/cfb_shell.c b/subsys/fb/cfb_shell.c new file mode 100644 index 00000000000..699f40510f1 --- /dev/null +++ b/subsys/fb/cfb_shell.c @@ -0,0 +1,470 @@ +/** @file + * @brief Monochrome Character Framebuffer shell module + * + * Provide some Character Framebuffer shell commands that can be useful for + * testing. + */ + +/* + * Copyright (c) 2018 Diego Sueiro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define HELP_NONE "[none]" +#define HELP_INIT "call \"cfb init\" first" +#define HELP_PRINT " \"\"" + +#define DISPLAY_DRIVER CONFIG_CHARACTER_FRAMEBUFFER_SHELL_DRIVER_NAME + + +static struct device *dev; +static const char * const param_name[] = { + "height", "width", "ppt", "rows", "cols"}; + +static int cmd_clear(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + err = cfb_framebuffer_clear(dev, true); + if (err) { + shell_error(shell, "Framebuffer clear error=%d", err); + return err; + } + + err = cfb_framebuffer_finalize(dev); + if (err) { + shell_error(shell, "Framebuffer finalize error=%d", err); + return err; + } + + shell_print(shell, "Display Cleared"); + + return err; +} + +static int cmd_cfb_print(const struct shell *shell, int col, int row, char *str) +{ + int err; + u8_t ppt; + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + ppt = cfb_get_display_parameter(dev, CFB_DISPLAY_PPT); + + err = cfb_framebuffer_clear(dev, false); + if (err) { + shell_error(shell, "Framebuffer clear failed error=%d", err); + return err; + } + + err = cfb_print(dev, str, col, row * ppt); + if (err) { + shell_error(shell, "Failed to print the string %s error=%d", + str, err); + return err; + } + + err = cfb_framebuffer_finalize(dev); + if (err) { + shell_error(shell, + "Failed to finalize the Framebuffer error=%d", err); + return err; + } + + return err; +} + +static int cmd_print(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + int col, row; + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + col = strtol(argv[1], NULL, 10); + if (col > cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)) { + shell_error(shell, "Invalid col=%d position", col); + return -EINVAL; + } + + row = strtol(argv[2], NULL, 10); + if (row > cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS)) { + shell_error(shell, "Invalid row=%d position", row); + return -EINVAL; + } + + err = cmd_cfb_print(shell, col, row, argv[3]); + if (err) { + shell_error(shell, "Failed printing to Framebuffer error=%d", + err); + } + + return err; +} + +static int cmd_scroll_vert(const struct shell *shell, size_t argc, char *argv[]) +{ + int err = 0; + int col, row; + int boundary; + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + col = strtol(argv[1], NULL, 10); + if (col > cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)) { + shell_error(shell, "Invalid col=%d position", col); + return -EINVAL; + } + + row = strtol(argv[2], NULL, 10); + if (row > cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS)) { + shell_error(shell, "Invalid row=%d position", row); + return -EINVAL; + } + + boundary = cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS) - row; + + for (int i = 0; i < boundary; i++) { + err = cmd_cfb_print(shell, col, row, argv[3]); + if (err) { + shell_error(shell, + "Failed printing to Framebuffer error=%d", + err); + break; + } + row++; + } + + cmd_cfb_print(shell, 0, 0, ""); + + return err; +} + +static int cmd_scroll_horz(const struct shell *shell, size_t argc, char *argv[]) +{ + int err = 0; + int col, row; + int boundary; + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + col = strtol(argv[1], NULL, 10); + if (col > cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)) { + shell_error(shell, "Invalid col=%d position", col); + return -EINVAL; + } + + row = strtol(argv[2], NULL, 10); + if (row > cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS)) { + shell_error(shell, "Invalid row=%d position", row); + return -EINVAL; + } + + col++; + boundary = cfb_get_display_parameter(dev, CFB_DISPLAY_COLS) - col; + + for (int i = 0; i < boundary; i++) { + err = cmd_cfb_print(shell, col, row, argv[3]); + if (err) { + shell_error(shell, + "Failed printing to Framebuffer error=%d", + err); + break; + } + col++; + } + + cmd_cfb_print(shell, 0, 0, ""); + + return err; +} + +static int cmd_set_font(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + int idx; + u8_t height; + u8_t width; + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + idx = strtol(argv[1], NULL, 10); + + err = cfb_get_font_size(dev, idx, &width, &height); + if (err) { + shell_error(shell, "Invalid font idx=%d err=%d\n", idx, err); + return err; + } + + err = cfb_framebuffer_set_font(dev, idx); + if (err) { + shell_error(shell, "Failed setting font idx=%d err=%d", idx, + err); + return err; + } + + shell_print(shell, "Font idx=%d height=%d widht=%d set", idx, height, + width); + + return err; +} + +static int cmd_invert(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + err = cfb_framebuffer_invert(dev); + if (err) { + shell_error(shell, "Error inverting Framebuffer"); + return err; + } + + cmd_cfb_print(shell, 0, 0, ""); + + shell_print(shell, "Framebuffer Inverted"); + + return err; +} + +static int cmd_get_fonts(const struct shell *shell, size_t argc, char *argv[]) +{ + int err = 0; + u8_t font_height; + u8_t font_width; + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + for (int idx = 0; idx < cfb_get_numof_fonts(dev); idx++) { + if (cfb_get_font_size(dev, idx, &font_width, &font_height)) { + break; + } + shell_print(shell, "idx=%d height=%d width=%d", idx, + font_height, font_width); + } + + return err; +} + +static int cmd_get_device(const struct shell *shell, size_t argc, char *argv[]) +{ + int err = 0; + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + shell_print(shell, "Framebuffer Device: %s", DISPLAY_DRIVER); + + return err; +} + +static int cmd_get_param_all(const struct shell *shell, size_t argc, + char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + for (unsigned int i = 0; i <= CFB_DISPLAY_COLS; i++) { + shell_print(shell, "param: %s=%d", param_name[i], + cfb_get_display_parameter(dev, i)); + + } + + return 0; +} + +static int cmd_get_param_height(const struct shell *shell, size_t argc, + char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + shell_print(shell, "param: %s=%d", param_name[CFB_DISPLAY_HEIGH], + cfb_get_display_parameter(dev, CFB_DISPLAY_HEIGH)); + + return 0; +} + +static int cmd_get_param_width(const struct shell *shell, size_t argc, + char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + shell_print(shell, "param: %s=%d", param_name[CFB_DISPLAY_WIDTH], + cfb_get_display_parameter(dev, CFB_DISPLAY_WIDTH)); + + return 0; +} + +static int cmd_get_param_ppt(const struct shell *shell, size_t argc, + char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + shell_print(shell, "param: %s=%d", param_name[CFB_DISPLAY_PPT], + cfb_get_display_parameter(dev, CFB_DISPLAY_PPT)); + + return 0; +} + +static int cmd_get_param_rows(const struct shell *shell, size_t argc, + char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + shell_print(shell, "param: %s=%d", param_name[CFB_DISPLAY_ROWS], + cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS)); + + return 0; +} + +static int cmd_get_param_cols(const struct shell *shell, size_t argc, + char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + if (!dev) { + shell_error(shell, HELP_INIT); + return -ENODEV; + } + + shell_print(shell, "param: %s=%d", param_name[CFB_DISPLAY_COLS], + cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)); + + return 0; +} + +static int cmd_init(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + + dev = device_get_binding(DISPLAY_DRIVER); + + if (dev == NULL) { + shell_error(shell, "Device not found"); + return -ENODEV; + } + + err = cfb_framebuffer_init(dev); + if (err) { + shell_error(shell, "Framebuffer initialization failed!"); + return err; + } + + shell_print(shell, "Framebuffer initialized: %s", DISPLAY_DRIVER); + + cmd_clear(shell, argc, argv); + + return err; +} + +SHELL_CREATE_STATIC_SUBCMD_SET(sub_cmd_get_param) { + + SHELL_CMD_ARG(all, NULL, NULL, cmd_get_param_all, 1, 0), + SHELL_CMD_ARG(height, NULL, NULL, cmd_get_param_height, 1, 0), + SHELL_CMD_ARG(width, NULL, NULL, cmd_get_param_width, 1, 0), + SHELL_CMD_ARG(ppt, NULL, NULL, cmd_get_param_ppt, 1, 0), + SHELL_CMD_ARG(rows, NULL, NULL, cmd_get_param_rows, 1, 0), + SHELL_CMD_ARG(cols, NULL, NULL, cmd_get_param_cols, 1, 0), + SHELL_SUBCMD_SET_END +}; + +SHELL_CREATE_STATIC_SUBCMD_SET(sub_cmd_scroll) { + + SHELL_CMD_ARG(vertical, NULL, HELP_PRINT, cmd_scroll_vert, 4, 0), + SHELL_CMD_ARG(horizontal, NULL, HELP_PRINT, cmd_scroll_horz, 4, 0), + SHELL_SUBCMD_SET_END +}; + +SHELL_CREATE_STATIC_SUBCMD_SET(cfb_cmds) { + SHELL_CMD_ARG(init, NULL, HELP_NONE, cmd_init, 1, 0), + SHELL_CMD_ARG(get_device, NULL, HELP_NONE, cmd_get_device, 1, 0), + SHELL_CMD(get_param, &sub_cmd_get_param, + "", NULL), + SHELL_CMD_ARG(get_fonts, NULL, HELP_NONE, cmd_get_fonts, 1, 0), + SHELL_CMD_ARG(set_font, NULL, "", cmd_set_font, 2, 0), + SHELL_CMD_ARG(invert, NULL, HELP_NONE, cmd_invert, 1, 0), + SHELL_CMD_ARG(print, NULL, HELP_PRINT, cmd_print, 4, 0), + SHELL_CMD(scroll, &sub_cmd_scroll, "scroll a text in vertical or " + "horizontal direction", NULL), + SHELL_CMD_ARG(clear, NULL, HELP_NONE, cmd_clear, 1, 0), + SHELL_SUBCMD_SET_END +}; + +SHELL_CMD_REGISTER(cfb, &cfb_cmds, "Character Framebuffer shell commands", + NULL);