diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/Kconfig b/boards/arm/stm32wl5/nucleo-wl55jc/Kconfig index a65425890d..134d59c7ae 100644 --- a/boards/arm/stm32wl5/nucleo-wl55jc/Kconfig +++ b/boards/arm/stm32wl5/nucleo-wl55jc/Kconfig @@ -275,4 +275,155 @@ endif # ARCH_BOARD_FLASH_PART4_SIZE > 0 endif # ARCH_BOARD_FLASH_MOUNT +if LCD_SSD1680 && ARCH_BOARD_NUCLEO_WL55JC + +menu "E-ink SSD1680 pins config" + +choice + prompt "Port that handles Chip Select line (output)" + default SSD1680_GPIO_CS_PORTA if ARCH_BOARD_NUCLEO_WL55JC + +config SSD1680_GPIO_CS_DISABLED + bool "Not available" + +config SSD1680_GPIO_CS_PORTA + bool "Port A" + +config SSD1680_GPIO_CS_PORTB + bool "Port B" + +config SSD1680_GPIO_CS_PORTC + bool "Port C" + +config SSD1680_GPIO_CS_PORTD + bool "Port D" + +endchoice + +if SSD1680_GPIO_CS_PORTA || SSD1680_GPIO_CS_PORTB || SSD1680_GPIO_CS_PORTC || SSD1680_GPIO_CS_PORTD +config SSD1680_GPIO_PIN_CS + int "Pin that select the chip on SPI bus (output)" + default "4" if ARCH_BOARD_NUCLEO_WL55JC + range 0 15 +endif #SSD1680_GPIO_CS_PORTA || SSD1680_GPIO_CS_PORTB || SSD1680_GPIO_CS_PORTC || SSD1680_GPIO_CS_PORTD + +choice + prompt "Port that handles Data/!Command line" + default SSD1680_GPIO_DTA_CMD_PORTA if ARCH_BOARD_NUCLEO_WL55JC + +config SSD1680_GPIO_DTA_CMD_DISABLED + bool "Not available" + +config SSD1680_GPIO_DTA_CMD_PORTA + bool "Port A" + +config SSD1680_GPIO_DTA_CMD_PORTB + bool "Port B" + +config SSD1680_GPIO_DTA_CMD_PORTC + bool "Port C" + +config SSD1680_GPIO_DTA_CMD_PORTD + bool "Port D" + +endchoice + +if SSD1680_GPIO_DTA_CMD_PORTA || SSD1680_GPIO_DTA_CMD_PORTB || SSD1680_GPIO_DTA_CMD_PORTC || SSD1680_GPIO_DTA_CMD_PORTD +config SSD1680_GPIO_PIN_DTA_CMD + int "Pin that switch between command and data on 4-wire SPI bus" + default "9" if ARCH_BOARD_NUCLEO_WL55JC + range 0 15 +endif #SSD1680_GPIO_DTA_CMD_PORTA || SSD1680_GPIO_DTA_CMD_PORTB || SSD1680_GPIO_DTA_CMD_PORTC || SSD1680_GPIO_DTA_CMD_PORTD + +choice + prompt "Port that handles reset line (output)" + default SSD1680_GPIO_RST_PORTC if ARCH_BOARD_NUCLEO_WL55JC + +config SSD1680_GPIO_RST_DISABLED + bool "Not available" + +config SSD1680_GPIO_RST_PORTA + bool "Port A" + +config SSD1680_GPIO_RST_PORTB + bool "Port B" + +config SSD1680_GPIO_RST_PORTC + bool "Port C" + +config SSD1680_GPIO_RST_PORTD + bool "Port D" +endchoice + +if SSD1680_GPIO_RST_PORTA || SSD1680_GPIO_RST_PORTB || SSD1680_GPIO_RST_PORTC || SSD1680_GPIO_RST_PORTD +config SSD1680_GPIO_PIN_RST + int "Pin that handles the reset line (output)" + default "2" if ARCH_BOARD_NUCLEO_WL55JC + range 0 15 +endif #SSD1680_GPIO_RST_PORTA || SSD1680_GPIO_RST_PORTB || SSD1680_GPIO_RST_PORTC || SSD1680_GPIO_RST_PORTD + +choice + prompt "Port that handles busy line (input)" + default SSD1680_GPIO_BUSY_PORTC if ARCH_BOARD_NUCLEO_WL55JC + +config SSD1680_GPIO_BUSY_DISABLED + bool "Not available" + +config SSD1680_GPIO_BUSY_PORTA + bool "Port A" + +config SSD1680_GPIO_BUSY_PORTB + bool "Port B" + +config SSD1680_GPIO_BUSY_PORTC + bool "Port C" + +config SSD1680_GPIO_BUSY_PORTD + bool "Port D" + +endchoice + +if SSD1680_GPIO_BUSY_PORTA || SSD1680_GPIO_BUSY_PORTB || SSD1680_GPIO_BUSY_PORTC || SSD1680_GPIO_BUSY_PORTD +config SSD1680_GPIO_PIN_BUSY + int "Pin that handles the busy line (input)" + default "1" if ARCH_BOARD_NUCLEO_WL55JC + range 0 15 +endif #SSD1680_GPIO_BUSY_PORTA || SSD1680_GPIO_BUSY_PORTB || SSD1680_GPIO_BUSY_PORTC || SSD1680_GPIO_BUSY_PORTD + +choice + prompt "Port that handles power line" + default SSD1680_GPIO_PWR_DISABLED if ARCH_BOARD_NUCLEO_WL55JC + +config SSD1680_GPIO_PWR_DISABLED + bool "Not available" + +config SSD1680_GPIO_PWR_PORTA + bool "Port A" + +config SSD1680_GPIO_PWR_PORTB + bool "Port B" + +config SSD1680_GPIO_PWR_PORTC + bool "Port C" + +config SSD1680_GPIO_PWR_PORTD + bool "Port D" + +endchoice + +if SSD1680_GPIO_PWR_PORTA || SSD1680_GPIO_PWR_PORTB || SSD1680_GPIO_PWR_PORTC || SSD1680_GPIO_PWR_PORTD +config SSD1680_GPIO_PIN_PWR + int "Pin that handles the pwr on/off line (output)" + range 0 31 +endif #SSD1680_GPIO_PWR_PORTA || SSD1680_GPIO_PWR_PORTB || SSD1680_GPIO_PWR_PORTC || SSD1680_GPIO_PWR_PORTD + + +config SSD1680_SPI_BUS + int "Spi bus no" + range 1 2 + default "1" +endmenu + +endif #LCD_SSD1680 + endif # ARCH_BOARD_NUCLEO_WL55JC diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/configs/fb/defconfig b/boards/arm/stm32wl5/nucleo-wl55jc/configs/fb/defconfig new file mode 100644 index 0000000000..62a6c06261 --- /dev/null +++ b/boards/arm/stm32wl5/nucleo-wl55jc/configs/fb/defconfig @@ -0,0 +1,44 @@ +# +# 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_STANDARD_SERIAL is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="nucleo-wl55jc" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_NUCLEO_WL55JC=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP="stm32wl5" +CONFIG_ARCH_CHIP_STM32WL55JC_CPU1=y +CONFIG_ARCH_CHIP_STM32WL5=y +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BUILTIN=y +CONFIG_DRIVERS_VIDEO=y +CONFIG_EXAMPLES_FB=y +CONFIG_FB_MODULEINFO=y +CONFIG_INIT_ENTRYNAME="main" +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_LCD=y +CONFIG_LCD_DEV=y +CONFIG_LCD_FRAMEBUFFER=y +CONFIG_LCD_SSD1680=y +CONFIG_LCD_SSD1680_2_13_V2=y +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_RAM_SIZE=32768 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_SPI=y +CONFIG_SPI_DRIVER=y +CONFIG_STM32WL5_LPUART1=y +CONFIG_STM32WL5_SPI1=y +CONFIG_STM32WL5_USART1=y + +CONFIG_STM32WL5_LPUART1=y +CONFIG_STM32WL5_SPI1=y +CONFIG_STM32WL5_SPI2S2=y +CONFIG_SYSTEM_NSH=y +CONFIG_VIDEO_FB=y diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/include/board.h b/boards/arm/stm32wl5/nucleo-wl55jc/include/board.h index 2d841e03fe..d786833bd0 100644 --- a/boards/arm/stm32wl5/nucleo-wl55jc/include/board.h +++ b/boards/arm/stm32wl5/nucleo-wl55jc/include/board.h @@ -136,6 +136,14 @@ #define GPIO_LPUART1_RX GPIO_LPUART1_RX_1 /* PA3 */ #define GPIO_LPUART1_TX GPIO_LPUART1_TX_1 /* PA2 */ +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_2 +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_2 +#define GPIO_SPI1_SCK GPIO_SPI1_SCK_2 + +#define GPIO_SPI2S2_MISO GPIO_SPI2_MISO_2 +#define GPIO_SPI2S2_MOSI GPIO_SPI2_MOSI_2 +#define GPIO_SPI2S2_SCK GPIO_SPI2_SCK_3 + /* user buttons * * There are 3 buttons provided for user to program diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/src/Makefile b/boards/arm/stm32wl5/nucleo-wl55jc/src/Makefile index 16a184a937..4bbfdf84f5 100644 --- a/boards/arm/stm32wl5/nucleo-wl55jc/src/Makefile +++ b/boards/arm/stm32wl5/nucleo-wl55jc/src/Makefile @@ -34,4 +34,14 @@ ifeq ($(CONFIG_ARCH_BOARD_FLASH_MOUNT),y) CSRCS += stm32_flash.c endif +ifeq ($(CONFIG_SPI_DRIVER),y) + CSRCS += stm32_spi.c +endif + +ifeq ($(CONFIG_VIDEO_FB),y) +ifeq ($(CONFIG_LCD_SSD1680),y) + CSRCS += stm32_ssd1680.c +endif +endif + include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/src/nucleo-wl55jc.h b/boards/arm/stm32wl5/nucleo-wl55jc/src/nucleo-wl55jc.h index e3b7b86338..5a8883af04 100644 --- a/boards/arm/stm32wl5/nucleo-wl55jc/src/nucleo-wl55jc.h +++ b/boards/arm/stm32wl5/nucleo-wl55jc/src/nucleo-wl55jc.h @@ -48,6 +48,77 @@ # undef HAVE_PROC #endif +#if defined(CONFIG_LCD_SSD1680) + +/* There is no E-ink display on a board. + * It can be connected on many different ways + * It is possible to configure pins using make menuconfig + */ + +# if defined(CONFIG_SSD1680_GPIO_CS_PORTA) +# define CONFIG_SSD1680_CS_PORT GPIO_PORTA +# elif defined(CONFIG_SSD1680_GPIO_CS_PORTB) +# define CONFIG_SSD1680_CS_PORT GPIO_PORTB +# elif defined(CONFIG_SSD1680_GPIO_CS_PORTC) +# define CONFIG_SSD1680_CS_PORT GPIO_PORTC +# elif defined(CONFIG_SSD1680_GPIO_CS_PORTD) +# define CONFIG_SSD1680_CS_PORT GPIO_PORTD +# endif + +# if defined(CONFIG_SSD1680_GPIO_DTA_CMD_PORTA) +# define CONFIG_SSD1680_DC_PORT GPIO_PORTA +# elif defined(CONFIG_SSD1680_GPIO_DTA_CMD_PORTB) +# define CONFIG_SSD1680_DC_PORT GPIO_PORTB +# elif defined(CONFIG_SSD1680_GPIO_DTA_CMD_PORTC) +# define CONFIG_SSD1680_DC_PORT GPIO_PORTC +# elif defined(CONFIG_SSD1680_GPIO_DTA_CMD_PORTD) +# define CONFIG_SSD1680_DC_PORT GPIO_PORTD +# endif + +# if defined(CONFIG_SSD1680_GPIO_RST_PORTA) +# define CONFIG_SSD1680_RST_PORT GPIO_PORTA +# elif defined(CONFIG_SSD1680_GPIO_RST_PORTB) +# define CONFIG_SSD1680_RST_PORT GPIO_PORTB +# elif defined(CONFIG_SSD1680_GPIO_RST_PORTC) +# define CONFIG_SSD1680_RST_PORT GPIO_PORTC +# elif defined(CONFIG_SSD1680_GPIO_RST_PORTD) +# define CONFIG_SSD1680_RST_PORT GPIO_PORTD +# endif + +# if defined(CONFIG_SSD1680_GPIO_BUSY_PORTA) +# define CONFIG_SSD1680_BUSY_PORT GPIO_PORTA +# elif defined(CONFIG_SSD1680_GPIO_BUSY_PORTB) +# define CONFIG_SSD1680_BUSY_PORT GPIO_PORTB +# elif defined(CONFIG_SSD1680_GPIO_BUSY_PORTC) +# define CONFIG_SSD1680_BUSY_PORT GPIO_PORTC +# elif defined(CONFIG_SSD1680_GPIO_BUSY_PORTD) +# define CONFIG_SSD1680_BUSY_PORT GPIO_PORTD +# endif + +# define GPIO_SSD1680_CS (GPIO_OUTPUT|GPIO_OTYPER_PP(0)|GPIO_SPEED_2MHz|\ + GPIO_OUTPUT_SET|\ + CONFIG_SSD1680_CS_PORT|\ + CONFIG_SSD1680_GPIO_PIN_CS) + +# define GPIO_SSD1680_CMD (GPIO_OUTPUT|GPIO_OTYPER_PP(0)|GPIO_OSPEED_2MHz|\ + GPIO_OUTPUT_SET|\ + CONFIG_SSD1680_DC_PORT|\ + CONFIG_SSD1680_GPIO_PIN_DTA_CMD) + +# ifdef CONFIG_SSD1680_RST_PORT +# define GPIO_SSD1680_RST (GPIO_OUTPUT|GPIO_OTYPER_PP(0)|GPIO_SPEED_2MHz|\ + GPIO_OUTPUT_SET|\ + CONFIG_SSD1680_RST_PORT|\ + CONFIG_SSD1680_GPIO_PIN_RST) +# endif + +# ifdef CONFIG_SSD1680_BUSY_PORT +# define GPIO_SSD1680_BUSY (GPIO_INPUT|GPIO_PULLUP|GPIO_SPEED_2MHz|\ + CONFIG_SSD1680_BUSY_PORT|\ + CONFIG_SSD1680_GPIO_PIN_BUSY) +# endif +#endif + #define GPIO_LED_GREEN (GPIO_PORTB|GPIO_PIN9 |GPIO_OUTPUT|GPIO_PULLUP|GPIO_SPEED_50MHz) #define GPIO_LED_RED (GPIO_PORTB|GPIO_PIN11|GPIO_OUTPUT|GPIO_PULLUP|GPIO_SPEED_50MHz) #define GPIO_LED_BLUE (GPIO_PORTB|GPIO_PIN15|GPIO_OUTPUT|GPIO_PULLUP|GPIO_SPEED_50MHz) @@ -84,4 +155,13 @@ void board_leds_initialize(void); int stm32wl5_flash_init(void); +/* Name: stm32wl5_spidev_initialize + * + * Description: + * Initialize SPIs + * + ****************************************************************************/ + +void stm32wl5_spidev_initialize(void); + #endif /* __BOARDS_ARM_STM32WL5_NUCLEO_WL55JC_SRC_NUCLEO_WL55JC_H */ diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_boot.c b/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_boot.c index 0073361b1e..cc5ce21a24 100644 --- a/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_boot.c +++ b/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_boot.c @@ -32,6 +32,10 @@ #include +#ifdef CONFIG_VIDEO_FB +#include +#endif + #include "arm_internal.h" #include "nucleo-wl55jc.h" @@ -81,6 +85,26 @@ void stm32wl5_board_initialize(void) #ifdef CONFIG_BOARD_LATE_INITIALIZE void board_late_initialize(void) { +#if defined(CONFIG_VIDEO_FB) + int ret; +#endif + +#if defined(CONFIG_STM32WL5_SPI1) || defined(CONFIG_STM32WL5_SPI2S2) + stm32wl5_spidev_initialize(); +#endif + +#if defined(CONFIG_LCD_SSD1680) && !defined(CONFIG_VIDEO_FB) + board_lcd_initialize(); +#endif + +#ifdef CONFIG_VIDEO_FB + ret = fb_register(0, 0); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: fb_register() failed: %d\n", ret); + } +#endif + /* Perform NSH initialization here instead of from the NSH. This * alternative NSH initialization is necessary when NSH is ran in * user-space but the initialization function must run in kernel space. diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_spi.c b/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_spi.c new file mode 100644 index 0000000000..cab6b89e03 --- /dev/null +++ b/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_spi.c @@ -0,0 +1,252 @@ +/**************************************************************************** + * boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_spi.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "arm_internal.h" +#include "chip.h" + +#include "stm32wl5.h" +#include "nucleo-wl55jc.h" + +#if defined(CONFIG_STM32WL5_SPI1) || defined(CONFIG_STM32WL5_SPI2S2) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Global driver instances */ + +#ifdef CONFIG_STM32WL5_SPI1 +struct spi_dev_s *g_spi1; +#endif +#ifdef CONFIG_STM32WL5_SPI2S2 +struct spi_dev_s *g_spi2; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the Nucleo-wl55JC + * boards. + * + ****************************************************************************/ + +void weak_function stm32wl5_spidev_initialize(void) +{ +#ifdef CONFIG_STM32WL5_SPI1 + /* Configure SPI-based devices */ + + g_spi1 = stm32wl5_spibus_initialize(1); + if (!g_spi1) + { + spierr("ERROR: FAILED to initialize SPI port 1\n"); + return; + } + +#ifdef CONFIG_LCD_SSD1680 + spiinfo("Preparing additional lines for SSD1680 device\n"); + stm32wl5_configgpio(GPIO_SSD1680_CS); /* SSD1680 chip select */ + stm32wl5_configgpio(GPIO_SSD1680_CMD); /* SSD1680 data/!command */ + stm32wl5_configgpio(GPIO_SSD1680_RST); /* SSD1680 reset */ + stm32wl5_configgpio(GPIO_SSD1680_BUSY); /* SSD1680 busy */ +#endif + +#endif + +#ifdef CONFIG_STM32_SPI2S2 + /* Configure SPI-based devices */ + + g_spi2 = stm32_spibus_initialize(2); +#endif +} + +/**************************************************************************** + * Name: stm32_spi1/2s2elect and stm32_spi1/2s2status + * + * Description: + * The external functions, stm32_spi1/2s2select and stm32_spi1/2s2status + * must be provided by board-specific logic. They are implementations of + * the select and status methods of the SPI interface defined by struct + * spi_ops_s (see include/nuttx/spi/spi.h). All other methods (including + * stm32wl5_spibus_initialize()) are provided by common STM32 logic. + * To use this common SPI logic on your board: + * + * 1. Provide logic in stm32_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32_spi1/2s2select() and stm32_spi1/2s2status() functions + * in your board-specific logic. These functions will perform chip + * selection and status operations using GPIOs in the way your board is + * configured. + * 3. Add a calls to stm32wl5_spibus_initialize() in your low level + * application initialization logic + * 4. The handle returned by stm32wl5_spibus_initialize() may then be used + * to bind the SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +#ifdef CONFIG_STM32WL5_SPI1 +void stm32wl5_spi1select(struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : + "de-assert"); + +#if defined(CONFIG_LCD_SSD1680) + if (devid == SPIDEV_DISPLAY(0)) + { + stm32wl5_gpiowrite(GPIO_SSD1680_CS, !selected); + } +#endif + +#if defined(CONFIG_CAN_MCP2515) + if (devid == SPIDEV_CANBUS(0)) + { + stm32wl5_gpiowrite(GPIO_MCP2515_CS, !selected); + } +#endif + +#ifdef HAVE_MMCSD + if (devid == SPIDEV_MMCSD(0)) + { + stm32wl5_gpiowrite(GPIO_SPI_CS_SD_CARD, !selected); + } +#endif +} + +uint8_t stm32wl5_spi1status(struct spi_dev_s *dev, uint32_t devid) +{ +#if defined(CONFIG_LCD_SSD1680) + if (devid == SPIDEV_DISPLAY(0)) + { + return SPI_STATUS_PRESENT; + } +#endif + + return 0; +} + +int stm32wl5_spi1cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ +#if defined(CONFIG_LCD_SSD1680) + if (devid == SPIDEV_DISPLAY(0)) + { + stm32wl5_gpiowrite(GPIO_SSD1680_CMD, !cmd); + } +#endif + + return OK; +} + +#endif + +#ifdef CONFIG_STM32WL5_SPI2S2 +void stm32wl5_spi2s2select(struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : + "de-assert"); +} + +uint8_t stm32wl5_spi2s2status(struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} + +int stm32wl5_spi2s2cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return OK; +} + +#endif + +/**************************************************************************** + * Name: stm32_spi1cmddata + * + * Description: + * Set or clear the SH1101A A0 or SD1306 D/C n bit to select data (true) + * or command (false). This function must be provided by platform-specific + * logic. This is an implementation of the cmddata method of the SPI + * interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h). + * + * Input Parameters: + * + * spi - SPI device that controls the bus the device that requires the CMD/ + * DATA selection. + * devid - If there are multiple devices on the bus, this selects which one + * to select cmd or data. NOTE: This design restricts, for example, + * one one SPI display per SPI bus. + * cmd - true: select command; false: select data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +#ifdef CONFIG_STM32_SPI1 +int stm32_spi1cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ +#if defined(CONFIG_LCD_SSD16800) + if (devid == SPIDEV_DISPLAY(0)) + { + stm32_gpiowrite(GPIO_SSD1680_CMD, !cmd); + } +#endif + + return OK; +} +#endif + +#ifdef CONFIG_STM32_SPI2 +int stm32_spi2cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return OK; +} +#endif + +#ifdef CONFIG_STM32_SPI3 +int stm32_spi3cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return OK; +} +#endif +#endif /* CONFIG_SPI_CMDDATA */ + +#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 || CONFIG_STM32_SPI3 */ diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_ssd1680.c b/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_ssd1680.c new file mode 100644 index 0000000000..28adb1ac4f --- /dev/null +++ b/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_ssd1680.c @@ -0,0 +1,190 @@ +/**************************************************************************** + * boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_ssd1680.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#include "stm32wl5.h" +#include "nucleo-wl55jc.h" +#include "stm32wl5_gpio.h" +#include "stm32wl5_ssd1680.h" + +#if defined(CONFIG_VIDEO_FB) && defined(CONFIG_LCD_FRAMEBUFFER) +# include +#endif + +#ifdef CONFIG_LCD_SSD1680 + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#if defined(GPIO_SSD1680_PWR) +static bool ssd1680_set_vcc(bool state) +{ + esp32_gpiowrite(GPIO_SSD1680_PWR, state); + return true; +} +#endif + +#if defined(CONFIG_SSD1680_GPIO_PIN_RST) +static bool ssd1680_set_rst(bool state) +{ + stm32wl5_gpiowrite(GPIO_SSD1680_RST, state); + return true; +} +#endif + +#if defined(CONFIG_SSD1680_GPIO_PIN_BUSY) +static bool ssd1680_check_busy(void) +{ + return stm32wl5_gpioread(GPIO_SSD1680_BUSY); +} +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct lcd_dev_s *g_lcddev; +struct ssd1680_priv_s g_ssd1680_priv = +{ +#if defined(CONFIG_SSD1680_GPIO_PIN_PWR) && (CONFIG_SSD1680_GPIO_PIN_PWR >= 0) + .set_vcc = ssd1680_set_vcc, +#endif + +#if defined(CONFIG_SSD1680_GPIO_PIN_RST) && (CONFIG_SSD1680_GPIO_PIN_RST >= 0) + .set_rst = ssd1680_set_rst, +#endif + +#if defined(CONFIG_SSD1680_GPIO_PIN_BUSY) && (CONFIG_SSD1680_GPIO_PIN_BUSY >= 0) + .check_busy = ssd1680_check_busy, +#endif +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_lcd_initialize + ****************************************************************************/ + +int board_lcd_initialize(void) +{ + struct spi_dev_s *spi; + + /* Initialize additional I/O for e-ink display */ + +#if defined(GPIO_SSD1680_PWR) + stm32wl5_configgpio(GPIO_SSD1680_PWR); /* SSD1680 pwr */ + lcdinfo("SSD1680 power line is available (0x%08x)\n", GPIO_SSD1680_PWR); +#else + lcdinfo("PWR control line is disabled\n"); +#endif +#if defined(GPIO_SSD1680_RST) + stm32wl5_configgpio(GPIO_SSD1680_RST); /* SSD1680 reset */ + lcdinfo("SSD1680 reset line is available (0x%08x)\n", GPIO_SSD1680_RST); +#elif + lcdinfo("SSD1680 RESET line is disabled\n"); +#endif + +#if defined(GPIO_SSD1680_BUSY) + stm32wl5_configgpio(GPIO_SSD1680_BUSY); /* SSD1680 busy */ + lcdinfo("SSD1680 Line for reading busy state is available (0x%08x)\n", + GPIO_SSD1680_BUSY); +#elif + lcdinfo("SSD1680 Read busy line is disabled\n"); +#endif + + /* Initialize SPI */ + + spi = stm32wl5_spibus_initialize(CONFIG_SSD1680_SPI_BUS); + if (!spi) + { + lcderr("ERROR: Failed to initialize SPI port %d\n", + CONFIG_SSD1680_SPI_BUS); + return -ENODEV; + } + else + { + lcdinfo("Using SPI bus %d. SPI is initialized\n", + CONFIG_SSD1680_SPI_BUS); + } + + /* Bind the SPI port to the E-PAPER display */ + + g_lcddev = ssd1680_initialize(spi, &g_ssd1680_priv); + if (!g_lcddev) + { + lcderr("ERROR: Failed to bind SPI port %d to E-paper display\n", + CONFIG_SSD1680_SPI_BUS); + return -ENODEV; + } + else + { + lcdinfo("Bound SPI port %d to E-PAPER\n", CONFIG_SSD1680_SPI_BUS); + + /* And turn the OLED on. + * Must be because setpower(1) function invokes the chip configuration + */ + + g_lcddev->setpower(g_lcddev, CONFIG_LCD_MAXPOWER); + } + + return OK; +} + +/**************************************************************************** + * Name: board_ssd1680_getdev + * + * Description: + * Get the SSD1680 device driver instance + * + * Returned Value: + * Pointer to the instance + * + ****************************************************************************/ + +struct lcd_dev_s *board_ssd1680_getdev(void) +{ + return g_lcddev; +} + +void board_lcd_uninitialize(void) +{ +} + +struct lcd_dev_s *board_lcd_getdev(int devno) +{ + return board_ssd1680_getdev(); +} + +#endif diff --git a/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32wl5_ssd1680.h b/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32wl5_ssd1680.h new file mode 100644 index 0000000000..775901a84d --- /dev/null +++ b/boards/arm/stm32wl5/nucleo-wl55jc/src/stm32wl5_ssd1680.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * boards/arm/stm32wl5/nucleo-wl55jc/src/stm32wl5_ssd1680.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_STMWL5_NUCLEO_WL55JC_INCLUDE_STM32WL5_SSD1680_H +#define __BOARDS_ARM_STMWL5_NUCLEO_WL55JC_INCLUDE_STM32WL5_SSD1680_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: board_ssd1680_getdev + * + * Description: + * Get the SSD1680 device driver instance + * + * Returned Value: + * Pointer to the instance + * + ****************************************************************************/ + +struct lcd_dev_s *board_ssd1680_getdev(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __BOARDS_ARM_STMWL5_NUCLEO_WL55JC_INCLUDE_STM32WL5_SSD1680_H */ \ No newline at end of file