This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push: new fb29f568d1 boards/arm/stm32f401rc-rs485: Add support to ST7735 LCD fb29f568d1 is described below commit fb29f568d1bfeb4fceec22b8f311d291bc7209f5 Author: Rodrigo Sim <rcsi...@gmail.com> AuthorDate: Sat Apr 26 12:06:30 2025 -0300 boards/arm/stm32f401rc-rs485: Add support to ST7735 LCD This commit adds support for the LCD based on ST7735 controller on the STM32F401RC-RS485 board and updates the board documentation accordingly. Signed-off-by: Rodrigo Sim <rcsi...@gmail.com> --- .../arm/stm32f4/boards/stm32f401rc-rs485/index.rst | 87 +++++++++++++++++++++- .../arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt | 9 +++ boards/arm/stm32/stm32f401rc-rs485/src/Make.defs | 9 ++- .../stm32f401rc-rs485/src/stm32_lcd_ssd1306.c | 8 +- .../{stm32_lcd_ssd1306.c => stm32_lcd_st7735.c} | 68 ++++++++++------- boards/arm/stm32/stm32f401rc-rs485/src/stm32_spi.c | 12 +-- .../stm32f401rc-rs485/src/stm32f401rc-rs485.h | 10 +-- 7 files changed, 156 insertions(+), 47 deletions(-) diff --git a/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst b/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst index 6c2e661aa8..bf838dd03d 100644 --- a/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst +++ b/Documentation/platforms/arm/stm32f4/boards/stm32f401rc-rs485/index.rst @@ -848,9 +848,6 @@ features such as scheduling and multi-sensor handling. - ``value1`` corresponds to pressure in hPa (hectopascals). - ``value2`` corresponds to temperature in tenths of degrees Celsius (e.g., 224.00 = 22.4°C). -Hardware Connections --------------------- - Connect the BMP180 sensor to the STM32 board using the I2C interface. +--------+------+ @@ -860,3 +857,87 @@ Connect the BMP180 sensor to the STM32 board using the I2C interface. +--------+------+ | SCL | PB8 | +--------+------+ + +ST7735 +====== + +This example shows how to bring up and use a ST7735-based TFT LCD display in NuttX. + +How to add support for the ST7735 display to a new board in NuttX: + +1. **LCD Initialization:** + Implement LCD initialization/uninitialization in `stm32_lcd_st7735.c` + to handle the display. You can copy this from another board that + supports ST7735. + +2. **Update CMakeLists.txt and Make.defs:** + Add `stm32_lcd_st7735.c` if `CONFIG_LCD_ST7735` is enabled. + +3. **SPI Initialization:** + Ensure SPI is configured in `stm32_spi.c` for the ST7735. + +4. **Board Setup:** + Configure GPIO pins for RESET, DC, and CS. + +You can wire the display to your board this way: + ++------------+---------+ +| LCD | PIN | ++============+=========+ +| CS | PB7 | ++------------+---------+ +| DC | PB8 | ++------------+---------+ +| RESET | PB6 | ++------------+---------+ +| SDA (MOSI) | PA7 | ++------------+---------+ +| SCK (SCLK) | PA5 | ++------------+---------+ + +.. note:: + + The ST7735 uses the SPI interface. + ``SDA`` corresponds to SPI ``MOSI`` (Master Out Slave In), + and ``SCK`` corresponds to SPI ``SCLK`` (Serial Clock). + +Enable the following options using ``make menuconfig``: +-------------------------------------------------------- + +:: + + CONFIG_DRIVERS_VIDEO=y + CONFIG_EXAMPLES_FB=y + CONFIG_LCD=y + CONFIG_LCD_FRAMEBUFFER=y + CONFIG_LCD_ST7735=y + CONFIG_SPI_CMDDATA=y + CONFIG_STM32_SPI1=y + CONFIG_VIDEO_FB=y + +NSH usage +--------- + +:: + + NuttShell (NSH) NuttX-12.9.0 + nsh> fb + VideoInfo: + fmt: 11 + xres: 160 + yres: 128 + nplanes: 1 + PlaneInfo (plane 0): + fbmem: 0x20003598 + fblen: 40960 + stride: 320 + display: 0 + bpp: 16 + Mapped FB: 0x20003598 + 0: ( 0, 0) (160,128) + 1: ( 14, 11) (132,106) + 2: ( 28, 22) (104, 84) + 3: ( 42, 33) ( 76, 62) + 4: ( 56, 44) ( 48, 40) + 5: ( 70, 55) ( 20, 18) + Test finished diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt b/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt index 1dc545f551..6348e9cc05 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt +++ b/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt @@ -69,6 +69,15 @@ if(CONFIG_DEV_GPIO) list(APPEND SRCS stm32_gpio.c) endif() +if(CONFIG_VIDEO_FB) + if(CONFIG_LCD_SSD1306) + list(APPEND SRCS stm32_lcd_ssd1306.c) + endif() + if(CONFIG_LCD_ST7735) + list(APPEND SRCS stm32_lcd_st7735.c) + endif() +endif() + target_sources(board PRIVATE ${SRCS}) if(CONFIG_ARCH_CHIP_STM32F401RC) diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs b/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs index 24b7f5c91b..4c5b08a780 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs +++ b/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs @@ -25,9 +25,12 @@ include $(TOPDIR)/Make.defs CSRCS = stm32_boot.c stm32_bringup.c stm32_spi.c ifeq ($(CONFIG_VIDEO_FB),y) -ifeq ($(CONFIG_LCD_SSD1306),y) - CSRCS += stm32_lcd_ssd1306.c -endif + ifeq ($(CONFIG_LCD_SSD1306),y) + CSRCS += stm32_lcd_ssd1306.c + endif + ifeq ($(CONFIG_LCD_ST7735),y) + CSRCS += stm32_lcd_st7735.c + endif endif ifeq ($(CONFIG_ARCH_LEDS),y) diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.c b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.c index 6543d7b9cd..10646f2a9b 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.c +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.c @@ -66,14 +66,14 @@ int board_lcd_initialize(void) /* Initialize the RESET and DC pins */ - stm32_configgpio(GPIO_OLED_RESET); - stm32_configgpio(GPIO_OLED_DC); + stm32_configgpio(GPIO_LCD_RESET); + stm32_configgpio(GPIO_LCD_DC); /* Reset the OLED display */ - stm32_gpiowrite(GPIO_OLED_RESET, 0); + stm32_gpiowrite(GPIO_LCD_RESET, 0); up_mdelay(1); - stm32_gpiowrite(GPIO_OLED_RESET, 1); + stm32_gpiowrite(GPIO_LCD_RESET, 1); up_mdelay(120); ret = board_ssd1306_initialize(OLED_SPI_PORT); diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.c b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_st7735.c similarity index 68% copy from boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.c copy to boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_st7735.c index 6543d7b9cd..a80240e75f 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.c +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_st7735.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.c + * boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_st7735.c * * SPDX-License-Identifier: Apache-2.0 * @@ -35,71 +35,87 @@ #include <nuttx/board.h> #include <nuttx/spi/spi.h> #include <nuttx/lcd/lcd.h> -#include <nuttx/lcd/ssd1306.h> +#include <nuttx/lcd/st7735.h> -#include "stm32.h" +#include "arm_internal.h" +#include "stm32_gpio.h" +#include "stm32_spi.h" #include "stm32f401rc-rs485.h" -#include "stm32_ssd1306.h" - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -#define OLED_SPI_PORT 1 /* OLED display connected to SPI1 */ +#define LCD_SPI_PORTNO 1 /**************************************************************************** * Private Data ****************************************************************************/ +static struct spi_dev_s *g_spidev; +static struct lcd_dev_s *g_lcd = NULL; + /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: board_lcd_initialize + * Name: board_lcd_initialize + * + * Description: + * Initialize the LCD video hardware. The initial state of the LCD is + * fully initialized, display memory cleared, and the LCD ready to use, but + * with the power setting at 0 (full off). + * ****************************************************************************/ int board_lcd_initialize(void) { - int ret; + stm32_configgpio(GPIO_LCD_RESET); + stm32_configgpio(GPIO_LCD_DC); - /* Initialize the RESET and DC pins */ - - stm32_configgpio(GPIO_OLED_RESET); - stm32_configgpio(GPIO_OLED_DC); - - /* Reset the OLED display */ + g_spidev = stm32_spibus_initialize(LCD_SPI_PORTNO); + if (!g_spidev) + { + lcderr("ERROR: Failed to initialize SPI port %d\n", LCD_SPI_PORTNO); + return -ENODEV; + } - stm32_gpiowrite(GPIO_OLED_RESET, 0); + stm32_gpiowrite(GPIO_LCD_RESET, 0); up_mdelay(1); - stm32_gpiowrite(GPIO_OLED_RESET, 1); + stm32_gpiowrite(GPIO_LCD_RESET, 1); up_mdelay(120); - ret = board_ssd1306_initialize(OLED_SPI_PORT); - if (ret < 0) - { - lcderr("ERROR: Failed to initialize SSD1306\n"); - return ret; - } + g_lcd = st7735_lcdinitialize(g_spidev); return OK; } /**************************************************************************** - * Name: board_lcd_getdev + * Name: board_lcd_getdev + * + * Description: + * Return a a reference to the LCD object for the specified LCD. This + * allows support for multiple LCD devices. + * ****************************************************************************/ struct lcd_dev_s *board_lcd_getdev(int devno) { - return board_ssd1306_getdev(); + return g_lcd; } /**************************************************************************** - * Name: board_lcd_uninitialize + * Name: board_lcd_uninitialize + * + * Description: + * Uninitialize the LCD support + * ****************************************************************************/ void board_lcd_uninitialize(void) { - /* TO-FIX */ + /* Turn the display off */ + + g_lcd->setpower(g_lcd, 0); } diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_spi.c b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_spi.c index e0ef7a6144..8922c7d604 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_spi.c +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_spi.c @@ -57,8 +57,8 @@ void weak_function stm32_spidev_initialize(void) { -#ifdef CONFIG_LCD_SSD1306 - stm32_configgpio(GPIO_OLED_CS); /* OLED chip select */ +#if defined(CONFIG_LCD_SSD1306) || defined(CONFIG_LCD_ST7735) + stm32_configgpio(GPIO_LCD_CS); /* LCD chip select */ #endif #ifdef CONFIG_LCD_MAX7219 @@ -103,10 +103,10 @@ void stm32_spi1select(struct spi_dev_s *dev, spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); - #ifdef CONFIG_LCD_SSD1306 +#if defined(CONFIG_LCD_SSD1306) || defined(CONFIG_LCD_ST7735) if (devid == SPIDEV_DISPLAY(0)) { - stm32_gpiowrite(GPIO_OLED_CS, !selected); + stm32_gpiowrite(GPIO_LCD_CS, !selected); } #endif @@ -186,14 +186,14 @@ uint8_t stm32_spi3status(struct spi_dev_s *dev, uint32_t devid) #ifdef CONFIG_STM32_SPI1 int stm32_spi1cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) { -#if defined(CONFIG_LCD_SSD1306) +#if defined(CONFIG_LCD_SSD1306) || defined(CONFIG_LCD_ST7735) if (devid == SPIDEV_DISPLAY(0)) { /* This is the Data/Command control pad which determines whether the * data bits are data or a command. */ - stm32_gpiowrite(GPIO_OLED_DC, !cmd); + stm32_gpiowrite(GPIO_LCD_DC, !cmd); return OK; } diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h b/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h index 1a2da26368..a257063d5e 100644 --- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h +++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h @@ -94,14 +94,14 @@ #define GPIO_BTN_SW5 \ (GPIO_INPUT |GPIO_FLOAT |GPIO_EXTI | GPIO_PORTB | GPIO_PIN15) -/* OLED SSD1309 */ +/* LCD SSD1309 or ST7735 */ -#if defined(CONFIG_LCD_SSD1306) -# define GPIO_OLED_RESET (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ +#if defined(CONFIG_LCD_SSD1306) || defined(CONFIG_LCD_ST7735) +# define GPIO_LCD_RESET (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN6) -# define GPIO_OLED_CS (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ +# define GPIO_LCD_CS (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN7) -# define GPIO_OLED_DC (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ +# define GPIO_LCD_DC (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN8) #endif