Add support to transparent OLED SSD1309

This patch adds support to transparent OLED powered by SSD1309.
SSD1309 uses the driver from SSD1306.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
This commit is contained in:
Alan Carvalho de Assis
2024-05-26 15:26:49 -03:00
committed by Xiang Xiao
parent 1cacc70f75
commit 8d7d687e86
8 changed files with 447 additions and 2 deletions
@@ -554,4 +554,47 @@ Configures the NuttShell (nsh) over USB Serial (check usbserial configuration) a
You can convert the value using following::
Convert to cm: value/58
Converto to inches: value/148
Convert to inches: value/148
ssd1309
-------
This config is used to enable support to the transparent OLED display powered by SSD1309.
The resolution of this display is 128x64 (although the effective view is 128x56).
You can wire the display to your board this way:
======= =====
OLED PINS
======= =====
CS PB7
DC PB8
RESET PB6
SDA PA7
SCK PA5
======= =====
The board profile configures the NSH over USB and you can use the fb command to test::
NuttShell (NSH) NuttX-12.5.1
nsh> fb
VideoInfo:
fmt: 0
xres: 128
yres: 64
nplanes: 1
PlaneInfo (plane 0):
fbmem: 0x200034f8
fblen: 1024
stride: 16
display: 0
bpp: 1
Mapped FB: 0x200034f8
0: ( 0, 0) (128, 64)
1: ( 11, 5) (106, 54)
2: ( 22, 10) ( 84, 44)
3: ( 33, 15) ( 62, 34)
4: ( 44, 20) ( 40, 24)
5: ( 55, 25) ( 18, 14)
Test finished
nsh>
@@ -0,0 +1,71 @@
#
# 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_ARCH_FPU is not set
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="stm32f401rc-rs485"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_STM32F401RC_RS485=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="stm32"
CONFIG_ARCH_CHIP_STM32=y
CONFIG_ARCH_CHIP_STM32F401RC=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_IRQBUTTONS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_USBDEVCTRL=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=8499
CONFIG_BUILTIN=y
CONFIG_CDCACM=y
CONFIG_CDCACM_CONSOLE=y
CONFIG_DRIVERS_VIDEO=y
CONFIG_EXAMPLES_BUTTONS=y
CONFIG_EXAMPLES_BUTTONS_NAME0="SW3"
CONFIG_EXAMPLES_BUTTONS_NAME1="SW4"
CONFIG_EXAMPLES_BUTTONS_NAME2="SW5"
CONFIG_EXAMPLES_BUTTONS_NAMES=y
CONFIG_EXAMPLES_BUTTONS_QTD=3
CONFIG_EXAMPLES_FB=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INPUT=y
CONFIG_INPUT_BUTTONS=y
CONFIG_INPUT_BUTTONS_LOWER=y
CONFIG_INTELHEX_BINARY=y
CONFIG_LCD=y
CONFIG_LCD_DD12864WO4A=y
CONFIG_LCD_FRAMEBUFFER=y
CONFIG_LCD_NOGETRUN=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_IFUPDOWN=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=98304
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=5
CONFIG_START_MONTH=5
CONFIG_START_YEAR=2014
CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_OTGFS=y
CONFIG_STM32_PWR=y
CONFIG_STM32_SPI1=y
CONFIG_STM32_USART6=y
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_USBDEV=y
CONFIG_VIDEO_FB=y
@@ -20,8 +20,13 @@
include $(TOPDIR)/Make.defs
CSRCS = stm32_boot.c stm32_bringup.c
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
endif
ifeq ($(CONFIG_ARCH_LEDS),y)
CSRCS += stm32_autoleds.c
@@ -57,6 +57,16 @@ void stm32_boardinitialize(void)
#ifdef CONFIG_ARCH_LEDS
board_autoled_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)
stm32_spidev_initialize();
#endif
}
/****************************************************************************
@@ -201,6 +201,16 @@ int stm32_bringup(void)
}
#endif
#ifdef CONFIG_VIDEO_FB
/* Initialize and register the framebuffer driver */
ret = fb_register(0, 0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: fb_register() failed: %d\n", ret);
}
#endif
#ifdef HAVE_SDIO
/* Initialize the SDIO block driver */
@@ -0,0 +1,103 @@
/****************************************************************************
* boards/arm/stm32/stm32f401rc-rs485/src/stm32_lcd_ssd1306.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 <nuttx/config.h>
#include <stdio.h>
#include <stdbool.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <nuttx/spi/spi.h>
#include <nuttx/lcd/lcd.h>
#include <nuttx/lcd/ssd1306.h>
#include "stm32.h"
#include "stm32f401rc-rs485.h"
#include "stm32_ssd1306.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define OLED_SPI_PORT 1 /* OLED display connected to SPI1 */
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_lcd_initialize
****************************************************************************/
int board_lcd_initialize(void)
{
int ret;
/* Initialize the RESET and DC pins */
stm32_configgpio(GPIO_OLED_RESET);
stm32_configgpio(GPIO_OLED_DC);
/* Reset the OLED display */
stm32_gpiowrite(GPIO_OLED_RESET, 0);
up_mdelay(1);
stm32_gpiowrite(GPIO_OLED_RESET, 1);
up_mdelay(120);
ret = board_ssd1306_initialize(OLED_SPI_PORT);
if (ret < 0)
{
lcderr("ERROR: Failed to initialize SSD1306\n");
return ret;
}
return OK;
}
/****************************************************************************
* Name: board_lcd_getdev
****************************************************************************/
struct lcd_dev_s *board_lcd_getdev(int devno)
{
return board_ssd1306_getdev();
}
/****************************************************************************
* Name: board_lcd_uninitialize
****************************************************************************/
void board_lcd_uninitialize(void)
{
/* TO-FIX */
}
@@ -0,0 +1,192 @@
/****************************************************************************
* boards/arm/stm32/stm32f401rc-rs485/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 <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/spi/spi.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "chip.h"
#include "stm32.h"
#include "stm32f401rc-rs485.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 stm32f401rc-rs485
* board.
*
****************************************************************************/
void weak_function stm32_spidev_initialize(void)
{
#ifdef CONFIG_STM32_SPI1
stm32_configgpio(GPIO_OLED_CS); /* OLED chip select */
#endif
}
/****************************************************************************
* 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 calls 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(struct spi_dev_s *dev,
uint32_t devid, bool selected)
{
spiinfo("devid: %d CS: %s\n",
(int)devid, selected ? "assert" : "de-assert");
stm32_gpiowrite(GPIO_OLED_CS, !selected);
}
uint8_t stm32_spi1status(struct spi_dev_s *dev, uint32_t devid)
{
return 0;
}
#endif
#ifdef CONFIG_STM32_SPI2
void stm32_spi2select(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(struct spi_dev_s *dev, uint32_t devid)
{
return 0;
}
#endif
#ifdef CONFIG_STM32_SPI3
void stm32_spi3select(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_spi3status(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(struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
#if defined(CONFIG_LCD_SSD1306)
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);
return OK;
}
#endif
return -ENODEV;
}
#endif
#ifdef CONFIG_STM32_SPI2
int stm32_spi2cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
#ifdef CONFIG_STM32_SPI3
int stm32_spi3cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
#endif /* CONFIG_SPI_CMDDATA */
#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 */
@@ -92,6 +92,17 @@
#define GPIO_BTN_SW5 \
(GPIO_INPUT |GPIO_FLOAT |GPIO_EXTI | GPIO_PORTB | GPIO_PIN15)
/* OLED SSD1309 */
#if defined(CONFIG_LCD_SSD1306)
# define GPIO_OLED_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|\
GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN7)
# define GPIO_OLED_DC (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN8)
#endif
/* SPI1 off */
#define GPIO_SPI1_MOSI_OFF (GPIO_INPUT | GPIO_PULLDOWN | \