diff --git a/boards/arm/stm32/olimex-stm32-p407/include/board.h b/boards/arm/stm32/olimex-stm32-p407/include/board.h index 6d203554f9d..0d92297b8d1 100644 --- a/boards/arm/stm32/olimex-stm32-p407/include/board.h +++ b/boards/arm/stm32/olimex-stm32-p407/include/board.h @@ -349,11 +349,11 @@ #define BOARD_DHTXX_GPIO_OUTPUT GPIO_DHTXX_PIN_OUTPUT #define BOARD_DHTXX_FRTIMER 1 /* Free-run timer 1 */ -/* SPI3 DMA -- As used for I2S DMA transfer with the audio configuration */ +/* SPI3 - As present in the UEXT header */ -#define GPIO_SPI3_MISO GPIO_SPI3_MISO_1 -#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_1 -#define GPIO_SPI3_SCK GPIO_SPI3_SCK_1 +#define GPIO_SPI3_MISO GPIO_SPI3_MISO_2 +#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_2 +#define GPIO_SPI3_SCK GPIO_SPI3_SCK_2 #define DMACHAN_SPI3_RX DMAMAP_SPI3_RX_1 #define DMACHAN_SPI3_TX DMAMAP_SPI3_TX_1 diff --git a/boards/arm/stm32/olimex-stm32-p407/src/Make.defs b/boards/arm/stm32/olimex-stm32-p407/src/Make.defs index d6a26915893..42afcfeb283 100644 --- a/boards/arm/stm32/olimex-stm32-p407/src/Make.defs +++ b/boards/arm/stm32/olimex-stm32-p407/src/Make.defs @@ -35,7 +35,7 @@ include $(TOPDIR)/Make.defs -CSRCS = stm32_boot.c stm32_bringup.c +CSRCS = stm32_boot.c stm32_bringup.c stm32_spi.c stm32_st7735.c ifeq ($(CONFIG_ARCH_LEDS),y) CSRCS += stm32_autoleds.c diff --git a/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h b/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h index 0f25f500048..bb80b05a5fd 100644 --- a/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h +++ b/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h @@ -207,6 +207,15 @@ # define CS4344_I2S_BUS 3 #endif +/* External ST7735 Pins */ + +#define GPIO_ST7735_CS (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ + GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN6) +#define GPIO_ST7735_AO (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ + GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN10) +#define GPIO_ST7735_RST (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ + GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN12) + #ifndef __ASSEMBLY__ /**************************************************************************** @@ -229,6 +238,17 @@ int stm32_bringup(void); +/**************************************************************************** + * Name: stm32_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the olimex-stm32-p407 + * board. + * + ****************************************************************************/ + +void weak_function stm32_spidev_initialize(void); + /**************************************************************************** * Name: stm32_stram_configure * diff --git a/boards/arm/stm32/olimex-stm32-p407/src/stm32_boot.c b/boards/arm/stm32/olimex-stm32-p407/src/stm32_boot.c index 0dab51e1fbb..cb6a08a1e9d 100644 --- a/boards/arm/stm32/olimex-stm32-p407/src/stm32_boot.c +++ b/boards/arm/stm32/olimex-stm32-p407/src/stm32_boot.c @@ -55,9 +55,10 @@ * Name: stm32_boardinitialize * * Description: - * All STM32 architectures must provide the following entry point. This entry point - * is called early in the initialization -- after all memory has been configured - * and mapped but before any devices have been initialized. + * All STM32 architectures must provide the following entry point. + * This entry point is called early in the initialization -- after all + * memory has been configured and mapped but before any devices have been + * initialized. * ****************************************************************************/ @@ -70,10 +71,10 @@ void stm32_boardinitialize(void) #endif #ifdef CONFIG_STM32_OTGFS - /* Initialize USB if the 1) OTG FS controller is in the configuration and 2) - * disabled, and 3) the weak function stm32_usb_configure() has been brought - * into the build. Presumably either CONFIG_USBDEV or CONFIG_USBHOST is also - * selected. + /* Initialize USB if the 1) OTG FS controller is in the configuration + * and 2) disabled, and 3) the weak function stm32_usb_configure() has been + * brought into the build. Presumably either CONFIG_USBDEV or + * CONFIG_USBHOST is also selected. */ stm32_usb_configure(); @@ -90,6 +91,18 @@ void stm32_boardinitialize(void) #ifdef CONFIG_ARCH_BUTTONS board_button_initialize(); #endif + + /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak + * function stm32_spidev_initialize() has been brought into the link. + */ + +#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) ||\ + defined(CONFIG_STM32_SPI3) + if (stm32_spidev_initialize) + { + stm32_spidev_initialize(); + } +#endif } /**************************************************************************** @@ -98,10 +111,11 @@ void stm32_boardinitialize(void) * Description: * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional * initialization call will be performed in the boot-up sequence to a - * function called board_late_initialize(). board_late_initialize() will be - * called immediately after up_initialize() is called and just before the - * initial application is started. This additional initialization phase - * may be used, for example, to initialize board-specific device drivers. + * function called board_late_initialize(). board_late_initialize() will + * be called immediately after up_initialize() is called and just before + * the initial application is started. This additional initialization + * phase may be used, for example, to initialize board-specific device + * drivers. * ****************************************************************************/ diff --git a/boards/arm/stm32/olimex-stm32-p407/src/stm32_spi.c b/boards/arm/stm32/olimex-stm32-p407/src/stm32_spi.c new file mode 100644 index 00000000000..097d287c405 --- /dev/null +++ b/boards/arm/stm32/olimex-stm32-p407/src/stm32_spi.c @@ -0,0 +1,195 @@ +/**************************************************************************** + * boards/arm/stm32/olimex-stm32-p407/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_arch.h" +#include "chip.h" +#include "stm32.h" + +#include "olimex-stm32-p407.h" + +#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) ||\ + defined(CONFIG_STM32_SPI3) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the olimex + * board. + * + ****************************************************************************/ + +void weak_function stm32_spidev_initialize(void) +{ + stm32_configgpio(GPIO_ST7735_CS); +} + +/**************************************************************************** + * Name: stm32_spi1/2/3select and stm32_spi1/2/3status + * + * Description: + * The external functions, stm32_spi1/2/3select and stm32_spi1/2/3status + * 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 + * stm32_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/2/3select() and stm32_spi1/2/3status() 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 call to stm32_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by stm32_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_STM32_SPI1 +void stm32_spi1select(FAR struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %d CS: %s\n", + (int)devid, selected ? "assert" : "de-assert"); +} + +uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif + +#ifdef CONFIG_STM32_SPI2 +void stm32_spi2select(FAR struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %d CS: %s\n", + (int)devid, selected ? "assert" : "de-assert"); +} + +uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif + +#ifdef CONFIG_STM32_SPI3 +void stm32_spi3select(FAR struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %d CS: %s\n", + (int)devid, selected ? "assert" : "de-assert"); + +#ifdef CONFIG_LCD_ST7735 + if (devid == SPIDEV_DISPLAY(0)) + { + stm32_gpiowrite(GPIO_ST7735_CS, !selected); + } +#endif +} + +uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#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(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return -ENODEV; +} +#endif + +#ifdef CONFIG_STM32_SPI2 +int stm32_spi2cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return -ENODEV; +} +#endif + +#ifdef CONFIG_STM32_SPI3 +int stm32_spi3cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + /* This is the Data/Command control pad which determines whether the + * data bits are data or a command. + */ + +#ifdef CONFIG_LCD_ST7735 + if (devid == SPIDEV_DISPLAY(0)) + { + stm32_gpiowrite(GPIO_ST7735_AO, !cmd); + return OK; + } +#endif + + return -ENODEV; +} +#endif +#endif /* CONFIG_SPI_CMDDATA */ + +#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 */ diff --git a/boards/arm/stm32/olimex-stm32-p407/src/stm32_st7735.c b/boards/arm/stm32/olimex-stm32-p407/src/stm32_st7735.c new file mode 100644 index 00000000000..260726157f6 --- /dev/null +++ b/boards/arm/stm32/olimex-stm32-p407/src/stm32_st7735.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * boards/arm/stm32/olimex-stm32-p407/src/stm32_st7735.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 +#include +#include + +#include "arm_arch.h" +#include "arm_internal.h" + +#include "stm32_gpio.h" +#include "stm32_spi.h" +#include "olimex-stm32-p407.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LCD_SPI_PORTNO 3 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct spi_dev_s *g_spidev; +static struct lcd_dev_s *g_lcd = NULL; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * 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) +{ + stm32_configgpio(GPIO_ST7735_RST); + stm32_configgpio(GPIO_ST7735_AO); + + 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_ST7735_RST, 0); + up_mdelay(1); + stm32_gpiowrite(GPIO_ST7735_RST, 1); + up_mdelay(120); + + g_lcd = st7735_lcdinitialize(g_spidev); + + return OK; +} + +/**************************************************************************** + * Name: board_lcd_getdev + * + * Description: + * Return a a reference to the LCD object for the specified LCD. This + * allows support for multiple LCD devices. + * + ****************************************************************************/ + +FAR struct lcd_dev_s *board_lcd_getdev(int devno) +{ + return g_lcd; +} + +/**************************************************************************** + * Name: board_lcd_uninitialize + * + * Description: + * Uninitialize the LCD support + * + ****************************************************************************/ + +void board_lcd_uninitialize(void) +{ + /* Turn the display off */ + + g_lcd->setpower(g_lcd, 0); +}