From 2e27113eeca3f3391aa58e11d2afbfb9fe07e700 Mon Sep 17 00:00:00 2001 From: Diego Sueiro Date: Thu, 15 Nov 2018 08:39:52 +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 | 402 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 420 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..252562108ab --- /dev/null +++ b/subsys/fb/cfb_shell.c @@ -0,0 +1,402 @@ +/** @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 print(_sh, _ft, ...) \ + shell_fprintf(_sh, SHELL_NORMAL, _ft "\r\n", \ + ##__VA_ARGS__) +#define error(_sh, _ft, ...) \ + shell_fprintf(_sh, SHELL_ERROR, _ft "\r\n", \ + ##__VA_ARGS__) + +#define HELP_NONE "[none]" +#define HELP_INIT "call \"cfb init\" first" + +#define DISPLAY_DRIVER CONFIG_CHARACTER_FRAMEBUFFER_SHELL_DRIVER_NAME + + +static struct device *dev; + +static int cmd_clear(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + + if (!dev) { + error(shell, HELP_INIT); + return -ENODEV; + } + + err = cfb_framebuffer_clear(dev, true); + if (err) { + error(shell, "Framebuffer clear error=%d", err); + return err; + } + + err = cfb_framebuffer_finalize(dev); + if (err) { + error(shell, "Framebuffer finalize error=%d", err); + return err; + } + + 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) { + error(shell, HELP_INIT); + return -ENODEV; + } + + ppt = cfb_get_display_parameter(dev, CFB_DISPLAY_PPT); + + err = cfb_framebuffer_clear(dev, false); + if (err) { + error(shell, "Framebuffer clear failed error=%d", err); + return err; + } + + err = cfb_print(dev, str, col, row * ppt); + if (err) { + error(shell, "Failed to print the string %s error=%d", + str, err); + return err; + } + + err = cfb_framebuffer_finalize(dev); + if (err) { + 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) { + error(shell, HELP_INIT); + return -ENODEV; + } + + err = shell_cmd_precheck(shell, (argc >= 3), NULL, 0); + if (err) { + return err; + } + + col = strtol(argv[1], NULL, 10); + if (col > cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)) { + 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)) { + error(shell, "Invalid row=%d position", row); + return -EINVAL; + } + + err = cmd_cfb_print(shell, col, row, argv[3]); + if (err) { + error(shell, "Failed printing to Framebuffer error=%d", err); + } + + return err; +} + +static int cmd_scroll(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + int col, row; + int scroll, boundary; + + if (!dev) { + error(shell, HELP_INIT); + return -ENODEV; + } + + err = shell_cmd_precheck(shell, (argc >= 4), NULL, 0); + if (err) { + return err; + } + + if (!strcmp(argv[1], "vertical")) { + scroll = 1; + boundary = cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS); + } else if (!strcmp(argv[1], "horizontal")) { + scroll = 0; + boundary = cfb_get_display_parameter(dev, CFB_DISPLAY_COLS); + } else { + shell_help_print(shell, NULL, 0); + /* shell_cmd_precheck returns 1 when help is printed */ + return 1; + } + + col = strtol(argv[2], NULL, 10); + if (col > cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)) { + error(shell, "Invalid col=%d position", col); + return -EINVAL; + } + + row = strtol(argv[3], NULL, 10); + if (row > cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS)) { + error(shell, "Invalid row=%d position", row); + return -EINVAL; + } + + if (scroll) { + boundary -= row; + } else { + col++; + boundary -= col; + } + + for (int i = 0; i < boundary; i++) { + err = cmd_cfb_print(shell, col, row, argv[4]); + if (err) { + error(shell, "Failed printing to Framebuffer error=%d", + err); + } + if (scroll) { + row++; + } else { + 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) { + error(shell, HELP_INIT); + return -ENODEV; + } + + err = shell_cmd_precheck(shell, (argc >= 1), NULL, 0); + if (err) { + return err; + } + + idx = strtol(argv[1], NULL, 10); + + err = cfb_get_font_size(dev, idx, &width, &height); + if (err) { + error(shell, "Invalid font idx=%d err=%d\n", idx, err); + return err; + } + + err = cfb_framebuffer_set_font(dev, idx); + if (err) { + error(shell, "Failed setting font idx=%d err=%d", idx, err); + return err; + } + + 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; + + if (!dev) { + error(shell, HELP_INIT); + return -ENODEV; + } + + err = cfb_framebuffer_invert(dev); + if (err) { + error(shell, "Error inverting Framebuffer"); + return err; + } + + cmd_cfb_print(shell, 0, 0, ""); + + 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; + + if (!dev) { + 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; + } + 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; + + if (!dev) { + error(shell, HELP_INIT); + return -ENODEV; + } + + print(shell, "Framebuffer Device: %s", DISPLAY_DRIVER); + + return err; +} + +static int cmd_get_param(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + int param = -1; + static const char * const param_name[] = { + "height", "width", "ppt", "rows", "cols"}; + + if (!dev) { + error(shell, HELP_INIT); + return -ENODEV; + } + + err = shell_cmd_precheck(shell, (argc >= 1), NULL, 0); + if (err) { + return err; + } + + /* Parse duplicate filtering data */ + if (argc >= 1) { + const char *param_filter = argv[1]; + + if (!strcmp(param_filter, "all")) { + param = -1; + } else if (!strcmp(param_filter, param_name[0])) { + param = CFB_DISPLAY_HEIGH; + } else if (!strcmp(param_filter, param_name[1])) { + param = CFB_DISPLAY_WIDTH; + } else if (!strcmp(param_filter, param_name[2])) { + param = CFB_DISPLAY_PPT; + } else if (!strcmp(param_filter, param_name[3])) { + param = CFB_DISPLAY_ROWS; + } else if (!strcmp(param_filter, param_name[4])) { + param = CFB_DISPLAY_COLS; + } else { + shell_help_print(shell, NULL, 0); + /* shell_cmd_precheck returns 1 when help is printed */ + return 1; + } + } + + if (param >= CFB_DISPLAY_HEIGH) { + print(shell, "param: %s=%d", param_name[param], + cfb_get_display_parameter(dev, param)); + } else { + for (unsigned int i = 0; i <= CFB_DISPLAY_COLS; i++) { + print(shell, "param: %s=%d", param_name[i], + cfb_get_display_parameter(dev, i)); + + } + } + + return err; +} + +static int cmd_init(const struct shell *shell, size_t argc, char *argv[]) +{ + int err; + + dev = device_get_binding(DISPLAY_DRIVER); + + if (dev == NULL) { + error(shell, "Device not found"); + return -ENODEV; + } + + err = cfb_framebuffer_init(dev); + if (err) { + error(shell, "Framebuffer initialization failed!"); + return err; + } + + print(shell, "Framebuffer initialized: %s", DISPLAY_DRIVER); + + cmd_clear(shell, argc, argv); + + return err; +} + +SHELL_CREATE_STATIC_SUBCMD_SET(cfb_cmds) { + SHELL_CMD(init, NULL, HELP_NONE, cmd_init), + SHELL_CMD(get_device, NULL, HELP_NONE, cmd_get_device), + SHELL_CMD(get_param, NULL, "", + cmd_get_param), + SHELL_CMD(get_fonts, NULL, HELP_NONE, cmd_get_fonts), + SHELL_CMD(set_font, NULL, "", cmd_set_font), + SHELL_CMD(invert, NULL, HELP_NONE, cmd_invert), + SHELL_CMD(print, NULL, " ", cmd_print), + SHELL_CMD(scroll, NULL, " " + " ", cmd_scroll), + SHELL_CMD(clear, NULL, HELP_NONE, cmd_clear), + SHELL_SUBCMD_SET_END +}; + +static int cmd_cfb(const struct shell *shell, size_t argc, char **argv) +{ + int err; + + if (argc == 1) { + shell_help_print(shell, NULL, 0); + /* shell_cmd_precheck returns 1 when help is printed */ + return 1; + } + + err = shell_cmd_precheck(shell, (argc == 2), NULL, 0); + if (err) { + return err; + } + + error(shell, "%s unknown parameter: %s", argv[0], argv[1]); + + return -EINVAL; +} + +SHELL_CMD_REGISTER(cfb, &cfb_cmds, "Character Framebuffer shell commands", + cmd_cfb);