diff --git a/Documentation/applications/examples/lvglterm/index.rst b/Documentation/applications/examples/lvglterm/index.rst index 0b236f81c58..18e93d34b86 100644 --- a/Documentation/applications/examples/lvglterm/index.rst +++ b/Documentation/applications/examples/lvglterm/index.rst @@ -4,18 +4,20 @@ LVGL application that runs an interactive NuttShell (NSH) on the display. NSH is started with its standard streams redirected through pipes, its output is -rendered in an LVGL text area, and the input comes from one of two sources +rendered in an LVGL text area, and the input comes from one of three sources selected at build time. The shared code lives in ``lvglterm.c`` (NSH startup, output rendering, main -loop); ``lvglterm_touch.c`` and ``lvglterm_kbd.c`` implement the two input +loop); ``lvglterm_touch.c`` and ``lvglterm_kbd.c`` implement the input variants. Input variants ============== The input source is chosen with the *LVGL Terminal input source* Kconfig -choice (only one is built at a time): +choice (only one is built at a time). The physical-keyboard options differ in +the data the keyboard device returns on ``read()``, so the one that matches the +hardware must be selected. On-screen keyboard (touch) ``CONFIG_EXAMPLES_LVGLTERM_INPUT_TOUCH`` (default). An LVGL keyboard @@ -29,23 +31,39 @@ On-screen keyboard (touch) On-screen keyboard (touch) variant -Physical keyboard - ``CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD``. Key events are read from a - ``/dev/kbdN`` keyboard device and streamed to the shell; the output fills - the whole screen. Requires ``CONFIG_INPUT_KEYBOARD``. - - The device defaults to ``CONFIG_EXAMPLES_LVGLTERM_KBD_DEV`` - (``/dev/kbd0``) and can be overridden at run time by passing the path as - the first argument (``lvglterm /dev/kbd1``) when more than one keyboard is - present. Keyboards that report the Fn navigation cluster as cursor keys - can scroll the output with Up/Down. +Matrix / upper-half keyboard + ``CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX``. ``struct + keyboard_event_s`` events are read from a keyboard registered through the + ``CONFIG_INPUT_KEYBOARD`` upper half (for example the M5Stack Cardputer + matrix keyboard on ``/dev/kbd0``) and streamed to the shell; the output + fills the whole screen. The Fn Up/Down cursor keys scroll the output. .. figure:: lvglterm-kbd.png :align: center :width: 500px - :alt: LVGL Terminal driven by a physical keyboard + :alt: LVGL Terminal driven by a matrix keyboard - Physical keyboard variant + Matrix / upper-half keyboard variant + +USB HID keyboard + ``CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_USB``. A USB HID keyboard (for + example on ``/dev/kbda`` with ``CONFIG_USBHOST_HIDKBD``) delivers a byte + stream that is decoded with the keyboard codec and streamed to the shell. + When the driver is built with ``CONFIG_HIDKBD_ENCODED`` the Up/Down cursor + keys scroll the terminal. + + .. figure:: lvglterm-usb.png + :align: center + :width: 500px + :alt: LVGL Terminal driven by a USB HID keyboard + + USB HID keyboard variant + +Both keyboard variants default the device to +``CONFIG_EXAMPLES_LVGLTERM_KBD_DEV`` (``/dev/kbd0`` for the matrix keyboard, +``/dev/kbda`` for USB) and can be overridden at run time by passing the path +as the first argument (``lvglterm /dev/kbd1``) when more than one keyboard is +present. Font ==== @@ -63,9 +81,13 @@ Configuration - ``CONFIG_SYSTEM_NSH=y`` -- the NSH library must be enabled. - ``CONFIG_GRAPHICS_LVGL=y`` and ``CONFIG_LV_USE_NUTTX=y`` -- LVGL with its NuttX integration. -- A display (``CONFIG_LV_USE_NUTTX_LCD`` or a framebuffer). The touch variant - also needs a touchscreen input (``CONFIG_LV_USE_NUTTX_TOUCHSCREEN``); the - keyboard variant needs a keyboard driver (``CONFIG_INPUT_KEYBOARD``). +- A display (``CONFIG_LV_USE_NUTTX_LCD`` or a framebuffer). Each input variant + also needs its own driver: a touchscreen + (``CONFIG_LV_USE_NUTTX_TOUCHSCREEN``) for the touch variant, + ``CONFIG_INPUT_KEYBOARD`` for the matrix variant, or + ``CONFIG_USBHOST_HIDKBD`` for the USB variant. The USB variant selects + ``CONFIG_LIBC_KBDCODEC`` automatically and, for the cursor keys, the driver + should be built with ``CONFIG_HIDKBD_ENCODED``. - The selected font (``CONFIG_LV_FONT_UNSCII_8`` or ``CONFIG_LV_FONT_UNSCII_16``) is enabled automatically by the font choice. diff --git a/Documentation/applications/examples/lvglterm/lvglterm-usb.png b/Documentation/applications/examples/lvglterm/lvglterm-usb.png new file mode 100644 index 00000000000..4d4dc467be9 Binary files /dev/null and b/Documentation/applications/examples/lvglterm/lvglterm-usb.png differ diff --git a/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst b/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst index ff07a5230f7..c6f68b67ec6 100644 --- a/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst +++ b/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst @@ -909,6 +909,54 @@ Type a command on the on-screen keyboard and press Enter; the command line ``nsh> `` and its output appear in the terminal area above the keyboard. +lvglterm_kbda +------------- + +**Purpose:** runs the ``lvglterm`` example -- an interactive NuttShell (NSH) +terminal rendered on the display -- driven by an external **USB HID keyboard**, +demonstrating that the OTG FS USB host and the microSD card can be used at the +same time on this board. + +The board's OTG FS port is enabled as a USB host (VBUS power switch on PI12), +so a USB HID keyboard plugged into the service connector is enumerated as +``/dev/kbda`` and its keys are streamed to NSH. The microSD card is enabled as +well and, because ``CONFIG_MMCSD_MMCSUPPORT`` is disabled, an SD card is probed +correctly (not as an MMC device) and registered as ``/dev/mmcsd0``. + +**Build and flash:** + +.. code-block:: console + + $ ./tools/configure.sh linum-stm32h753bi:lvglterm_kbda + $ make -j + +Flash the resulting ``nuttx.bin`` to the board. + +**How to test:** plug a USB HID keyboard and an SD card, reset the board and +check that both devices are present:: + + nsh> ls /dev + /dev: + console + fb0 + kbda + mmcsd0 + null + rtc0 + ttyS0 + zero + +Start the terminal and type on the USB keyboard; the command line and its +output appear on the display, and the Up/Down cursor keys scroll it:: + + nsh> lvglterm + +The SD card can be mounted and read while the keyboard is in use, confirming +that the USB host and the SDMMC peripheral coexist:: + + nsh> mount -t vfat /dev/mmcsd0 /data + nsh> ls /data + tone ---- diff --git a/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-m5-cardputer/index.rst b/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-m5-cardputer/index.rst index a8258dec019..eda4fe85e84 100644 --- a/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-m5-cardputer/index.rst +++ b/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-m5-cardputer/index.rst @@ -60,7 +60,7 @@ turns it on). The key-position-to-character table follows the M5Cardputer layout; verify it against the printed legends on first bring-up. Applications read ``/dev/kbd0`` for key events (for example the ``lvglterm`` example, built - with its physical-keyboard input variant, feeds it into an on-screen + with its matrix-keyboard input variant, feeds it into an on-screen shell). Pin Mapping @@ -141,7 +141,7 @@ lvgl lvglterm On-screen NuttShell terminal with LVGL and the physical keyboard. Runs - the ``lvglterm`` example built with its physical-keyboard input variant: + the ``lvglterm`` example built with its matrix-keyboard input variant: NSH output is rendered in an LVGL text area and the keyboard (``/dev/kbd0``) feeds the input. Wi-Fi is included, so the on-screen shell can associate with an access point using ``wapi``. ``Fn`` + ``;`` / diff --git a/boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda/defconfig b/boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda/defconfig new file mode 100644 index 00000000000..2c052238fb6 --- /dev/null +++ b/boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda/defconfig @@ -0,0 +1,93 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_STM32_FB_CMAP is not set +# CONFIG_STM32_LTDC_L1_CHROMAKEYEN is not set +# CONFIG_STM32_LTDC_L2 is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="linum-stm32h753bi" +CONFIG_ARCH_BOARD_LINUM_STM32H753BI=y +CONFIG_ARCH_CHIP="stm32h7" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32H753BI=y +CONFIG_ARCH_CHIP_STM32H7=y +CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_DTCM=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_BOARD_LOOPSPERMSEC=43103 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DRIVERS_VIDEO=y +CONFIG_EXAMPLES_LVGLTERM=y +CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_USB=y +CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FB_OVERLAY=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_GRAN=y +CONFIG_GRAN_INTR=y +CONFIG_GRAPHICS_LVGL=y +CONFIG_HIDKBD_ENCODED=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INPUT=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_EXECFUNCS=y +CONFIG_LIBM=y +CONFIG_LINE_MAX=64 +CONFIG_LV_MEM_SIZE_KILOBYTES=128 +CONFIG_LV_USE_NUTTX=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y +CONFIG_MM_REGIONS=5 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PIPES=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=245760 +CONFIG_RAM_START=0x20010000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RTC_ALARM=y +CONFIG_RTC_DATETIME=y +CONFIG_RTC_DRIVER=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SDMMC1_SDIO_MODE=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32_FMC=y +CONFIG_STM32_HSI48=y +CONFIG_STM32_I2C3=y +CONFIG_STM32_LTDC=y +CONFIG_STM32_LTDC_FB_BASE=0xC0600000 +CONFIG_STM32_LTDC_FB_SIZE=2097152 +CONFIG_STM32_OTGFS=y +CONFIG_STM32_PWR=y +CONFIG_STM32_RTC=y +CONFIG_STM32_SDMMC1=y +CONFIG_STM32_USART1=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_TESTING_RAMTEST=y +CONFIG_USART1_SERIAL_CONSOLE=y +CONFIG_USBHOST=y +CONFIG_USBHOST_HIDKBD=y +CONFIG_USEC_PER_TICK=1000 +CONFIG_VIDEO_FB=y diff --git a/boards/arm/stm32h7/linum-stm32h753bi/include/board.h b/boards/arm/stm32h7/linum-stm32h753bi/include/board.h index fc345aa0d2c..28ede095363 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/include/board.h +++ b/boards/arm/stm32h7/linum-stm32h753bi/include/board.h @@ -391,6 +391,15 @@ #define GPIO_OTGFS_DM (GPIO_OTGFS_DM_0|GPIO_SPEED_100MHz) /* PA11 */ #define GPIO_OTGFS_DP (GPIO_OTGFS_DP_0|GPIO_SPEED_100MHz) /* PA12 */ +/* The Linum board wires the USB connector for host/device use without an + * OTG_FS_ID pin (mode is forced by the driver), so PA10 is NOT used as + * OTG_FS_ID. The OTG host driver still configures GPIO_OTGFS_ID + * unconditionally, so map it to a harmless floating input instead of the + * OTG_FS_ID alternate function to keep PA10 free. + */ + +#define GPIO_OTGFS_ID (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN10) + /* SDMMC1 - Used SD Card memory */ /* Init 400 kHz, PLL1Q/(2*300) = 240 MHz / (2*300) = 400 Khz */ @@ -502,7 +511,10 @@ * this value will need to be doubled. */ -#ifdef CONFIG_STM32_LTDC +#if defined(CONFIG_STM32_LTDC) && defined(CONFIG_STM32_LTDC_L1_ARGB8888) +/* A 32-bpp ARGB8888 framebuffer (1024x600x4 = 2.4M) needs the last 3M */ +# define BOARD_SDRAM1_SIZE (5*1024*1024) +#elif defined(CONFIG_STM32_LTDC) # define BOARD_SDRAM1_SIZE (6*1024*1024) #else # define BOARD_SDRAM1_SIZE (8*1024*1024) diff --git a/boards/arm/stm32h7/linum-stm32h753bi/src/linum-stm32h753bi.h b/boards/arm/stm32h7/linum-stm32h753bi/src/linum-stm32h753bi.h index 64027b170b9..6162d3d84b7 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/src/linum-stm32h753bi.h +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/linum-stm32h753bi.h @@ -305,4 +305,22 @@ int board_tone_initialize(int devno); int stm32_tsc_setup(int minor); #endif +/**************************************************************************** + * Name: stm32_usbhost_initialize + * + * Description: + * Called at application startup time to initialize the USB host + * functionality. This function will start a thread that will monitor for + * device connection/disconnection events. + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +int stm32_usbhost_initialize(void); +#endif + #endif /* __BOARDS_ARM_STM32H7_LINUM_STM32H753BI_SRC_LINUM_STM32H753BI_H */ diff --git a/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_boot.c b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_boot.c index 01c91d90986..588e3122f42 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_boot.c +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_boot.c @@ -55,6 +55,14 @@ void stm32_boardinitialize(void) board_autoled_initialize(); #endif + +#ifdef CONFIG_STM32_OTGFS + /* Initialize USB-related GPIOs (VBUS sensing, power switch enable and + * over-current) so the OTG FS port can drive VBUS in host mode. + */ + + stm32_usbinitialize(); +#endif } /**************************************************************************** diff --git a/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_bringup.c b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_bringup.c index 02f6a1cc0ae..5936c0d50ae 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_bringup.c +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_bringup.c @@ -359,5 +359,17 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_USBHOST + /* Initialize USB host to support an external HID keyboard (e.g. as the + * NXDoom game controller) plugged into the OTG FS service port. + */ + + ret = stm32_usbhost_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_usbhost_initialize() failed: %d\n", ret); + } +#endif + return OK; } diff --git a/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_usb.c b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_usb.c index 884e370b0c9..a9d4fabdcdd 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_usb.c +++ b/boards/arm/stm32h7/linum-stm32h753bi/src/stm32_usb.c @@ -271,9 +271,11 @@ void stm32_usbhost_vbusdrive(int iface, bool enable) { DEBUGASSERT(iface == 0); - /* Set the Power Switch by driving the active high enable pin */ + /* Set the Power Switch by driving the enable pin. On the Linum board the + * USB power switch enable (PI12) is active low, so invert the request. + */ - stm32_gpiowrite(GPIO_OTGFS_PWRON, enable); + stm32_gpiowrite(GPIO_OTGFS_PWRON, !enable); } #endif diff --git a/boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig b/boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig index 67bec4730d1..5bb9c031f09 100644 --- a/boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig +++ b/boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig @@ -47,6 +47,7 @@ CONFIG_ESP32S3_USBSERIAL=y CONFIG_ESPRESSIF_WIFI=y CONFIG_EXAMPLES_LVGLTERM=y CONFIG_EXAMPLES_LVGLTERM_FONT_UNSCII_8=y +CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX=y CONFIG_FAT_LCNAMES=y CONFIG_FAT_LFN=y CONFIG_FS_FAT=y