mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
19914: boards: complete SD Card MTD definition for several bords r=benpicco a=gschorcht ### Contribution description This PR completes the MTD definition for the following boards: - `seeedstudio-gd32` - `sipeed-longan-nano` including `sipeed-longan-nano-tft` - `waveshare-nrf52840-eval-kit` - ESP32x boards that have an SPI SD Card interface and use `mtd_sdcard_default` ### Testing procedure Green CI ### Issues/PRs references#19465 Prerequisite for PR #19465 19915: drivers/lcd: support MCU 8080 8-bit parallel mode r=benpicco a=gschorcht ### Contribution description LCD driver ICs usually support - SPI serial mode, - MCU 8080 8-bit parallel mode and - MCU 8080 16-bit parallel mode. This PR extends the LCD display driver API to support the MCU 8080 8-/16-bit parallel modes and implements a GPIO-driven MCU 8080 8-bit parallel mode. The following features are already working locally and will be provided as follow-on PRs for which this PR is a prerequisite. - GPIO-driven bit-banging implementation of the 16-bit mode of the MCU 8080 parallel interface - Enabling the display on `stm32f723e-disco` and `stm32l496g-disco` using the feature above - Definition of a low-level API for the parallel modes using the LCD controller of the MCU - Using FMC for the display on `stm32f723e-disco` and `stm32l496g-disco` - Using LCD controller for the display of `esp32-wt32-sc01-plus` (PR #19917) ### Testing procedure The PR can be tested with PR #19917 on top of this PR. ``` BOARD=esp32s3-wt32-sc01-plus make -j8 -C tests/drivers/st77xx flash ``` The following video shows the test. **Please note** The test is pretty slow because the display has 480 x 320 pixels and the MCU 8080 8-bit parallel interface is realized by a GPIO-driven bit-banging implementation where each GPIO of the data bus is set separately. A follow-up PR will use the ESP32-S3 LCD controller and DMA for this board. This PR just defines the extension of the driver by the parallel interface and provides the bit-banging implementation for MCUs that don't have a LCD controller on chip. https://github.com/RIOT-OS/RIOT/assets/31932013/c1e3e3d7-05d9-4ca5-8fff-9a5eaca50fba ### Issues/PRs references Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
This commit is contained in:
commit
1691dbe0d3
@ -103,11 +103,15 @@ extern "C" {
|
|||||||
#define SPI_FLASH_DRIVE_START 0
|
#define SPI_FLASH_DRIVE_START 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Default MTD drive definition */
|
#define MTD_0 mtd0 /**< Flash MTD device */
|
||||||
#define MTD_0 mtd0
|
extern mtd_dev_t *mtd0; /**< Flash MTD device pointer */
|
||||||
|
|
||||||
/** Pointer to the default MTD drive structure */
|
#if MODULE_MTD_SDCARD_DEFAULT || DOXYGEN
|
||||||
extern mtd_dev_t *mtd0;
|
|
||||||
|
#define MTD_1 mtd1 /**< SD Card MTD device */
|
||||||
|
extern mtd_dev_t *mtd1; /**< SD Card MTD device pointer */
|
||||||
|
|
||||||
|
#endif /* MODULE_MTD_SDCARD_DEFAULT || DOXYGEN */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MTD offset for SD Card interfaces
|
* @brief MTD offset for SD Card interfaces
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#define BOARD_H
|
#define BOARD_H
|
||||||
|
|
||||||
#include "board_common.h"
|
#include "board_common.h"
|
||||||
|
#include "mtd.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -67,6 +68,25 @@ extern "C" {
|
|||||||
#define LED_BLUE_PIN LED2_PIN /**< LED2 is blue */
|
#define LED_BLUE_PIN LED2_PIN /**< LED2 is blue */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name MTD configuration
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MTD_0 mtd0 /**< MTD device for SD Card */
|
||||||
|
extern mtd_dev_t *mtd0; /**< MTD device pointer for SD Card */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SD-Card interface configuration
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SDCARD_SPI_PARAM_SPI SPI_DEV(0)
|
||||||
|
#define SDCARD_SPI_PARAM_CS GPIO_PIN(PORT_B, 12)
|
||||||
|
#define SDCARD_SPI_PARAM_CLK GPIO_PIN(PORT_B, 13)
|
||||||
|
#define SDCARD_SPI_PARAM_MISO GPIO_PIN(PORT_B, 14)
|
||||||
|
#define SDCARD_SPI_PARAM_MOSI GPIO_PIN(PORT_B, 15)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define BOARD_H
|
#define BOARD_H
|
||||||
|
|
||||||
#include "board_common.h"
|
#include "board_common.h"
|
||||||
|
#include "mtd.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -62,13 +63,24 @@ extern "C" {
|
|||||||
#define LED_BLUE_PIN LED2_PIN /**< LED2 is blue */
|
#define LED_BLUE_PIN LED2_PIN /**< LED2 is blue */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#if defined(MODULE_SDCARD_SPI)
|
/**
|
||||||
|
* @name MTD configuration
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MTD_0 mtd0 /**< MTD device for SD Card */
|
||||||
|
extern mtd_dev_t *mtd0; /**< MTD device pointer for SD Card */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name SD-Card interface configuration
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
#define SDCARD_SPI_PARAM_SPI SPI_DEV(0)
|
#define SDCARD_SPI_PARAM_SPI SPI_DEV(0)
|
||||||
#define SDCARD_SPI_PARAM_CS GPIO_PIN(PORT_B, 12)
|
#define SDCARD_SPI_PARAM_CS GPIO_PIN(PORT_B, 12)
|
||||||
#define SDCARD_SPI_PARAM_CLK GPIO_PIN(PORT_B, 13)
|
#define SDCARD_SPI_PARAM_CLK GPIO_PIN(PORT_B, 13)
|
||||||
#define SDCARD_SPI_PARAM_MISO GPIO_PIN(PORT_B, 14)
|
#define SDCARD_SPI_PARAM_MISO GPIO_PIN(PORT_B, 14)
|
||||||
#define SDCARD_SPI_PARAM_MOSI GPIO_PIN(PORT_B, 15)
|
#define SDCARD_SPI_PARAM_MOSI GPIO_PIN(PORT_B, 15)
|
||||||
#endif
|
/** @} */
|
||||||
|
|
||||||
#if defined(MODULE_ST77XX) && defined(BOARD_SIPEED_LONGAN_NANO_TFT)
|
#if defined(MODULE_ST77XX) && defined(BOARD_SIPEED_LONGAN_NANO_TFT)
|
||||||
#define ST77XX_PARAM_SPI SPI_DEV(1) /**< SPI device */
|
#define ST77XX_PARAM_SPI SPI_DEV(1) /**< SPI device */
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define BOARD_H
|
#define BOARD_H
|
||||||
|
|
||||||
#include "board_common.h"
|
#include "board_common.h"
|
||||||
|
#include "mtd.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -82,6 +83,14 @@ extern "C" {
|
|||||||
#define SDCARD_SPI_PARAM_MISO GPIO_PIN(0, 20)
|
#define SDCARD_SPI_PARAM_MISO GPIO_PIN(0, 20)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name MTD configuration
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MTD_0 mtd0 /**< MTD device for SD Card */
|
||||||
|
extern mtd_dev_t *mtd0; /**< MTD device pointer for SD Card */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -71,13 +71,45 @@ extern "C" {
|
|||||||
#define ILI9341_PARAM_OFFSET_Y 0 /**< Vertival offset */
|
#define ILI9341_PARAM_OFFSET_Y 0 /**< Vertival offset */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MODULE_LCD_SPI || DOXYGEN
|
||||||
|
/** Default interface params if SPI serial interface is enabled */
|
||||||
|
#define ILI9341_PARAM_IF_SPI .spi = ILI9341_PARAM_SPI, \
|
||||||
|
.spi_clk = ILI9341_PARAM_SPI_CLK, \
|
||||||
|
.spi_mode = ILI9341_PARAM_SPI_MODE,
|
||||||
|
#else
|
||||||
|
#define ILI9341_PARAM_IF_SPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MODULE_LCD_PARALLEL || DOXYGEN
|
||||||
|
/** Default interface params if MCU 8080 8-bit parallel interface is enabled */
|
||||||
|
#define ILI9341_PARAM_IF_PAR .d0_pin = ILI9341_PARAM_D0, \
|
||||||
|
.d1_pin = ILI9341_PARAM_D1, \
|
||||||
|
.d2_pin = ILI9341_PARAM_D2, \
|
||||||
|
.d3_pin = ILI9341_PARAM_D3, \
|
||||||
|
.d4_pin = ILI9341_PARAM_D4, \
|
||||||
|
.d5_pin = ILI9341_PARAM_D5, \
|
||||||
|
.d6_pin = ILI9341_PARAM_D6, \
|
||||||
|
.d7_pin = ILI9341_PARAM_D7, \
|
||||||
|
.wrx_pin = ILI9341_PARAM_WRX, \
|
||||||
|
.rdx_pin = ILI9341_PARAM_RDX,
|
||||||
|
#else
|
||||||
|
#define ILI9341_PARAM_IF_PAR
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default params
|
* @brief Default params
|
||||||
|
*
|
||||||
|
* @note The default parameter set defined here can only be used if a single
|
||||||
|
* ILI9341 display and only one interface mode is used. If multiple
|
||||||
|
* ILI9341 displays are used or if multiple interface modes are enabled
|
||||||
|
* by the modules `lcd_spi`, lcd_parallel and `lcd_parallel_16bit`, a user
|
||||||
|
* defined parameter set @ref ILI9341_PARAMS has to be defined. In the
|
||||||
|
* latter case @ref lcd_params_t::spi must then be set to @ref SPI_UNDEF
|
||||||
|
* for displays with MCU 8080 8-/16-bit parallel interfaces.
|
||||||
*/
|
*/
|
||||||
#ifndef ILI9341_PARAMS
|
#ifndef ILI9341_PARAMS
|
||||||
#define ILI9341_PARAMS { .spi = ILI9341_PARAM_SPI, \
|
#define ILI9341_PARAMS { ILI9341_PARAM_IF_SPI \
|
||||||
.spi_clk = ILI9341_PARAM_SPI_CLK, \
|
ILI9341_PARAM_IF_PAR \
|
||||||
.spi_mode = ILI9341_PARAM_SPI_MODE, \
|
|
||||||
.cs_pin = ILI9341_PARAM_CS, \
|
.cs_pin = ILI9341_PARAM_CS, \
|
||||||
.dcx_pin = ILI9341_PARAM_DCX, \
|
.dcx_pin = ILI9341_PARAM_DCX, \
|
||||||
.rst_pin = ILI9341_PARAM_RST, \
|
.rst_pin = ILI9341_PARAM_RST, \
|
||||||
@ -124,7 +156,6 @@ static const uint8_t ili9341_screen_ids[] =
|
|||||||
*/
|
*/
|
||||||
#define ILI9341_SCREEN_NUMOF ARRAY_SIZE(ili9341_screen_ids)
|
#define ILI9341_SCREEN_NUMOF ARRAY_SIZE(ili9341_screen_ids)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Koen Zandberg
|
* Copyright (C) 2018 Koen Zandberg
|
||||||
* 2021 Francisco Molina
|
* 2021 Francisco Molina
|
||||||
|
* 2023 Gunar Schorcht
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
* General Public License v2.1. See the file LICENSE in the top level
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -13,8 +14,22 @@
|
|||||||
*
|
*
|
||||||
* @brief Driver for the LCD display
|
* @brief Driver for the LCD display
|
||||||
*
|
*
|
||||||
* The LCD is a generic display driver for small RGB displays. The driver
|
* The LCD is a generic display driver for small RGB displays. It communicates
|
||||||
* implemented here operates over SPI to communicate with the device.
|
* with the device either via an
|
||||||
|
*
|
||||||
|
* - SPI serial interface (if module `lcd_spi` enabled) or an
|
||||||
|
* - MCU 8080 8-/16-bit parallel interface (if module `lcd_parallel` or
|
||||||
|
* module `lcd_parallel_16` is enabled).
|
||||||
|
*
|
||||||
|
* Usually the device driver is used either for a single display with SPI serial
|
||||||
|
* interface or for a display with parallel MCU 8080 8-/16-bit parallel
|
||||||
|
* interface. However, the device driver can also be used simultaneously for
|
||||||
|
* multiple displays with different interfaces if several of the `lcd_spi`,
|
||||||
|
* `lcd_parallel` and `lcd_parallel_16bit` modules are enabled at the same time.
|
||||||
|
* In this case, please refer to the notes in @ref lcd_params_t.
|
||||||
|
*
|
||||||
|
* @warning MCU 8080 16-bit parallel interface (module `lcd_parallel_16bit`) is
|
||||||
|
* not supported yet.
|
||||||
*
|
*
|
||||||
* The device requires colors to be send in big endian RGB-565 format. The
|
* The device requires colors to be send in big endian RGB-565 format. The
|
||||||
* @ref CONFIG_LCD_LE_MODE compile time option can switch this, but only use this
|
* @ref CONFIG_LCD_LE_MODE compile time option can switch this, but only use this
|
||||||
@ -28,6 +43,7 @@
|
|||||||
*
|
*
|
||||||
* @author Koen Zandberg <koen@bergzand.net>
|
* @author Koen Zandberg <koen@bergzand.net>
|
||||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||||
|
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -35,6 +51,7 @@
|
|||||||
#define LCD_H
|
#define LCD_H
|
||||||
|
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
#include "mutex.h"
|
||||||
#include "periph/spi.h"
|
#include "periph/spi.h"
|
||||||
#include "periph/gpio.h"
|
#include "periph/gpio.h"
|
||||||
|
|
||||||
@ -70,18 +87,58 @@ extern "C" {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device initialization parameters
|
* @brief Device initialization parameters
|
||||||
|
*
|
||||||
|
* @note The device driver can be used simultaneously for displays with
|
||||||
|
* SPI serial interface and parallel MCU 8080 8-/16-bit interfaces
|
||||||
|
* if the modules `lcd_spi` and `lcd_parallel` or `lcd_parallel_16bit`
|
||||||
|
* are enabled at the same time. In this case the interface parameters
|
||||||
|
* for the SPI serial interface and the MCU 8080 parallel 8-/16-bit
|
||||||
|
* interfaces are defined. @ref lcd_params_t::spi must then be set to
|
||||||
|
* @ref SPI_UNDEF for displays that use the MCU-8080-parallel-8-/16-bit
|
||||||
|
* interface, i.e. @ref lcd_params_t::spi is then used to detect the
|
||||||
|
* interface mode.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
#if MODULE_LCD_SPI || DOXYGEN
|
||||||
|
/* Interface parameters used for serial interface */
|
||||||
spi_t spi; /**< SPI device that the display is connected to */
|
spi_t spi; /**< SPI device that the display is connected to */
|
||||||
spi_clk_t spi_clk; /**< SPI clock speed to use */
|
spi_clk_t spi_clk; /**< SPI clock speed to use */
|
||||||
spi_mode_t spi_mode; /**< SPI mode */
|
spi_mode_t spi_mode; /**< SPI mode */
|
||||||
|
#endif
|
||||||
|
#if MODULE_LCD_PARALLEL || DOXYGEN
|
||||||
|
/* Interface parameters used for MCU 8080 8-bit parallel interface */
|
||||||
|
gpio_t wrx_pin; /**< pin connected to the WRITE ENABLE line */
|
||||||
|
gpio_t rdx_pin; /**< pin connected to the READ ENABLE line */
|
||||||
|
gpio_t d0_pin; /**< pin connected to the D0 line */
|
||||||
|
gpio_t d1_pin; /**< pin connected to the D1 line */
|
||||||
|
gpio_t d2_pin; /**< pin connected to the D2 line */
|
||||||
|
gpio_t d3_pin; /**< pin connected to the D3 line */
|
||||||
|
gpio_t d4_pin; /**< pin connected to the D4 line */
|
||||||
|
gpio_t d5_pin; /**< pin connected to the D5 line */
|
||||||
|
gpio_t d6_pin; /**< pin connected to the D6 line */
|
||||||
|
gpio_t d7_pin; /**< pin connected to the D7 line */
|
||||||
|
#if MODULE_LCD_PARALLEL_16BIT || DOXYGEN
|
||||||
|
/* Interface parameters used for MCU 8080 16-bit parallel interface */
|
||||||
|
gpio_t d8_pin; /**< pin connected to the D8 line */
|
||||||
|
gpio_t d9_pin; /**< pin connected to the D9 line */
|
||||||
|
gpio_t d10_pin; /**< pin connected to the D10 line */
|
||||||
|
gpio_t d11_pin; /**< pin connected to the D11 line */
|
||||||
|
gpio_t d12_pin; /**< pin connected to the D12 line */
|
||||||
|
gpio_t d13_pin; /**< pin connected to the D13 line */
|
||||||
|
gpio_t d14_pin; /**< pin connected to the D14 line */
|
||||||
|
gpio_t d15_pin; /**< pin connected to the D15 line */
|
||||||
|
#endif /* MODULE_LCD_PARALLEL_16BIT */
|
||||||
|
#endif /* MODULE_LCD_PARALLEL */
|
||||||
|
/* Common interface parameters */
|
||||||
gpio_t cs_pin; /**< pin connected to the CHIP SELECT line */
|
gpio_t cs_pin; /**< pin connected to the CHIP SELECT line */
|
||||||
gpio_t dcx_pin; /**< pin connected to the DC line */
|
gpio_t dcx_pin; /**< pin connected to the DC line */
|
||||||
gpio_t rst_pin; /**< pin connected to the reset line */
|
gpio_t rst_pin; /**< pin connected to the RESET line */
|
||||||
bool rgb; /**< True when display is connected in RGB mode
|
bool rgb; /**< True when display is connected in RGB mode\n
|
||||||
* False when display is connected in BGR mode */
|
False when display is connected in BGR mode */
|
||||||
bool inverted; /**< Display works in inverted color mode */
|
bool inverted; /**< Display works in inverted color mode */
|
||||||
uint16_t lines; /**< Number of lines, from 16 to 320 in 8 line steps */
|
uint16_t lines; /**< Number of lines, from 16 to the number of
|
||||||
|
lines supported by the driver IC in 8 line
|
||||||
|
steps */
|
||||||
uint16_t rgb_channels; /**< Display rgb channels */
|
uint16_t rgb_channels; /**< Display rgb channels */
|
||||||
uint8_t rotation; /**< Display rotation mode */
|
uint8_t rotation; /**< Display rotation mode */
|
||||||
uint8_t offset_x; /**< LCD offset to apply on x axis. */
|
uint8_t offset_x; /**< LCD offset to apply on x axis. */
|
||||||
@ -104,11 +161,15 @@ typedef struct lcd_driver lcd_driver_t;
|
|||||||
* @brief Device descriptor for a lcd
|
* @brief Device descriptor for a lcd
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
#ifdef MODULE_DISP_DEV
|
#if MODULE_DISP_DEV || DOXYGEN
|
||||||
disp_dev_t *dev; /**< Pointer to the generic display device */
|
disp_dev_t *dev; /**< Pointer to the generic display device */
|
||||||
#endif
|
#endif
|
||||||
const lcd_driver_t *driver; /**< LCD driver */
|
const lcd_driver_t *driver; /**< LCD driver */
|
||||||
const lcd_params_t *params; /**< Device initialization parameters */
|
const lcd_params_t *params; /**< Device initialization parameters */
|
||||||
|
#if MODULE_LCD_PARALLEL || DOXYGEN
|
||||||
|
mutex_t lock; /**< Mutex used to lock the device in
|
||||||
|
MCU 8080 parallel interface mode */
|
||||||
|
#endif
|
||||||
} lcd_t;
|
} lcd_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,7 +203,7 @@ struct lcd_driver {
|
|||||||
* @param[in] y2 y coordinate of the opposite corner
|
* @param[in] y2 y coordinate of the opposite corner
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void (*set_area)(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
void (*set_area)(lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
||||||
uint16_t y2);
|
uint16_t y2);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -162,14 +223,14 @@ struct lcd_driver {
|
|||||||
*
|
*
|
||||||
* @param[out] dev device descriptor
|
* @param[out] dev device descriptor
|
||||||
*/
|
*/
|
||||||
void lcd_ll_acquire(const lcd_t *dev);
|
void lcd_ll_acquire(lcd_t *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Low-level function to release the device
|
* @brief Low-level function to release the device
|
||||||
*
|
*
|
||||||
* @param[out] dev device descriptor
|
* @param[out] dev device descriptor
|
||||||
*/
|
*/
|
||||||
void lcd_ll_release(const lcd_t *dev);
|
void lcd_ll_release(lcd_t *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Low-level function to write a command
|
* @brief Low-level function to write a command
|
||||||
@ -182,7 +243,7 @@ void lcd_ll_release(const lcd_t *dev);
|
|||||||
* @param[in] data command data to the device
|
* @param[in] data command data to the device
|
||||||
* @param[in] len length of the command data
|
* @param[in] len length of the command data
|
||||||
*/
|
*/
|
||||||
void lcd_ll_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
void lcd_ll_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -201,7 +262,7 @@ void lcd_ll_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
|||||||
* @param[out] data data from the device
|
* @param[out] data data from the device
|
||||||
* @param[in] len length of the returned data
|
* @param[in] len length of the returned data
|
||||||
*/
|
*/
|
||||||
void lcd_ll_read_cmd(const lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len);
|
void lcd_ll_read_cmd(lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -234,7 +295,7 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params);
|
|||||||
* @param[in] y2 y coordinate of the opposite corner
|
* @param[in] y2 y coordinate of the opposite corner
|
||||||
* @param[in] color single color to fill the area with
|
* @param[in] color single color to fill the area with
|
||||||
*/
|
*/
|
||||||
void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
void lcd_fill(lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||||
uint16_t y1, uint16_t y2, uint16_t color);
|
uint16_t y1, uint16_t y2, uint16_t color);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,7 +314,7 @@ void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
|||||||
* @param[in] y2 y coordinate of the opposite corner
|
* @param[in] y2 y coordinate of the opposite corner
|
||||||
* @param[in] color array of colors to fill the area with
|
* @param[in] color array of colors to fill the area with
|
||||||
*/
|
*/
|
||||||
void lcd_pixmap(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
void lcd_pixmap(lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
||||||
uint16_t y2, const uint16_t *color);
|
uint16_t y2, const uint16_t *color);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -264,12 +325,16 @@ void lcd_pixmap(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
|||||||
* @param[in] data command data to the device
|
* @param[in] data command data to the device
|
||||||
* @param[in] len length of the command data
|
* @param[in] len length of the command data
|
||||||
*/
|
*/
|
||||||
void lcd_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
void lcd_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raw read command
|
* @brief Raw read command
|
||||||
*
|
*
|
||||||
|
* @note Very often the SPI MISO signal of the serial interface or the RDX
|
||||||
|
* signal of the MCU 8080 parallel interface are not connected to the
|
||||||
|
* display. In this case the read command does not provide valid data.
|
||||||
|
*
|
||||||
* @pre len > 0
|
* @pre len > 0
|
||||||
*
|
*
|
||||||
* @param[in] dev device descriptor
|
* @param[in] dev device descriptor
|
||||||
@ -277,21 +342,21 @@ void lcd_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
|||||||
* @param[out] data data from the device
|
* @param[out] data data from the device
|
||||||
* @param[in] len length of the returned data
|
* @param[in] len length of the returned data
|
||||||
*/
|
*/
|
||||||
void lcd_read_cmd(const lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len);
|
void lcd_read_cmd(lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Invert the display colors
|
* @brief Invert the display colors
|
||||||
*
|
*
|
||||||
* @param[in] dev device descriptor
|
* @param[in] dev device descriptor
|
||||||
*/
|
*/
|
||||||
void lcd_invert_on(const lcd_t *dev);
|
void lcd_invert_on(lcd_t *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable color inversion
|
* @brief Disable color inversion
|
||||||
*
|
*
|
||||||
* @param[in] dev device descriptor
|
* @param[in] dev device descriptor
|
||||||
*/
|
*/
|
||||||
void lcd_invert_off(const lcd_t *dev);
|
void lcd_invert_off(lcd_t *dev);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -22,8 +22,18 @@
|
|||||||
* @ref lcd_params_t::cntrl or as macro @ref ST77XX_PARAM_CNTRL if the
|
* @ref lcd_params_t::cntrl or as macro @ref ST77XX_PARAM_CNTRL if the
|
||||||
* default parameter set @ref ST77XX_PARAMS is used.
|
* default parameter set @ref ST77XX_PARAMS is used.
|
||||||
*
|
*
|
||||||
* The driver uses the SPI serial interface to communicate with the display
|
* The driver communicates with the device either via an
|
||||||
* controller.
|
*
|
||||||
|
* - SPI serial interface (if module `lcd_spi` enabled) or an
|
||||||
|
* - MCU 8080 8-/16-bit parallel interface (if module `lcd_parallel` or
|
||||||
|
* module `lcd_parallel_16` is enabled).
|
||||||
|
*
|
||||||
|
* Usually the device driver is used either for a single display with SPI serial
|
||||||
|
* interface or for a display with parallel MCU 8080 8-/16-bit parallel
|
||||||
|
* interface. However, the device driver can also be used simultaneously for
|
||||||
|
* multiple displays with different interfaces if several of the `lcd_spi`,
|
||||||
|
* `lcd_parallel` and `lcd_parallel_16bit` modules are enabled at the same time.
|
||||||
|
* In this case, please refer to the notes in @ref lcd_params_t.
|
||||||
*
|
*
|
||||||
* The device requires colors to be send in big endian RGB-565 format. The
|
* The device requires colors to be send in big endian RGB-565 format. The
|
||||||
* @ref CONFIG_LCD_LE_MODE compile time option can switch this, but only use this
|
* @ref CONFIG_LCD_LE_MODE compile time option can switch this, but only use this
|
||||||
|
@ -7,10 +7,8 @@
|
|||||||
|
|
||||||
config MODULE_LCD
|
config MODULE_LCD
|
||||||
bool "LCD display driver"
|
bool "LCD display driver"
|
||||||
depends on HAS_PERIPH_SPI
|
|
||||||
depends on HAS_PERIPH_GPIO
|
depends on HAS_PERIPH_GPIO
|
||||||
depends on TEST_KCONFIG
|
depends on TEST_KCONFIG
|
||||||
select MODULE_PERIPH_SPI
|
|
||||||
select MODULE_PERIPH_GPIO
|
select MODULE_PERIPH_GPIO
|
||||||
|
|
||||||
config MODULE_LCD_MULTI_CNTRL
|
config MODULE_LCD_MULTI_CNTRL
|
||||||
@ -18,6 +16,48 @@ config MODULE_LCD_MULTI_CNTRL
|
|||||||
help
|
help
|
||||||
The controller-specific driver supports multiple controller variants.
|
The controller-specific driver supports multiple controller variants.
|
||||||
|
|
||||||
|
config MODULE_LCD_SPI
|
||||||
|
bool
|
||||||
|
default y if !MODULE_LCD_PARALLEL && !MODULE_LCD_PARALLEL_16BIT
|
||||||
|
default y if HAVE_LCD_SPI
|
||||||
|
depends on HAS_PERIPH_SPI
|
||||||
|
depends on MODULE_LCD
|
||||||
|
select MODULE_PERIPH_SPI
|
||||||
|
help
|
||||||
|
SPI serial interface is used
|
||||||
|
|
||||||
|
config MODULE_LCD_PARALLEL
|
||||||
|
bool
|
||||||
|
default y if HAVE_LCD_PARALLEL || HAVE_LCD_PARALLEL_16BIT
|
||||||
|
depends on MODULE_LCD
|
||||||
|
help
|
||||||
|
MCU 8080 8-/16-bit parallel interface is used
|
||||||
|
|
||||||
|
config MODULE_LCD_PARALLEL_16BIT
|
||||||
|
bool
|
||||||
|
default y if HAVE_LCD_PARALLEL_16BIT
|
||||||
|
depends on MODULE_LCD
|
||||||
|
help
|
||||||
|
MCU 8080 16-bit paralell interface is used
|
||||||
|
|
||||||
|
config HAVE_LCD_SPI
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Indicates that a display with MCU 8080 8-/16-bit parallel interface
|
||||||
|
is present
|
||||||
|
|
||||||
|
config HAVE_LCD_PARALLEL
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Indicates that a display with MCU 8080 8-/16-bit parallel interface
|
||||||
|
is present
|
||||||
|
|
||||||
|
config HAVE_LCD_PARALLEL_16BIT
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Indicates that a display with MCU 8080 16-bit parallel interface
|
||||||
|
is present
|
||||||
|
|
||||||
menuconfig KCONFIG_USEMODULE_LCD
|
menuconfig KCONFIG_USEMODULE_LCD
|
||||||
bool "Configure LCD driver"
|
bool "Configure LCD driver"
|
||||||
depends on USEMODULE_LCD
|
depends on USEMODULE_LCD
|
||||||
|
@ -1,2 +1,14 @@
|
|||||||
FEATURES_REQUIRED += periph_spi
|
|
||||||
FEATURES_REQUIRED += periph_gpio
|
FEATURES_REQUIRED += periph_gpio
|
||||||
|
|
||||||
|
ifneq (,$(filter lcd_parallel_16bit,$(USEMODULE)))
|
||||||
|
USEMODULE += lcd_parallel
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (,$(filter lcd_parallel%,$(USEMODULE)))
|
||||||
|
# default to SPI serial interface if no MCU 8080 parallel interface is enabled
|
||||||
|
USEMODULE += lcd_spi
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter lcd_spi,$(USEMODULE)))
|
||||||
|
FEATURES_REQUIRED += periph_spi
|
||||||
|
endif
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
PSEUDOMODULES += lcd_multi_cntrl
|
PSEUDOMODULES += lcd_multi_cntrl
|
||||||
|
|
||||||
|
PSEUDOMODULES += lcd_spi
|
||||||
|
PSEUDOMODULES += lcd_parallel
|
||||||
|
PSEUDOMODULES += lcd_parallel_16bit
|
||||||
|
|
||||||
USEMODULE_INCLUDES_lcd := $(LAST_MAKEFILEDIR)/include
|
USEMODULE_INCLUDES_lcd := $(LAST_MAKEFILEDIR)/include
|
||||||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_lcd)
|
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_lcd)
|
||||||
|
@ -25,43 +25,149 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "byteorder.h"
|
#include "byteorder.h"
|
||||||
#include "periph/spi.h"
|
|
||||||
#include "kernel_defines.h"
|
#include "kernel_defines.h"
|
||||||
#include "ztimer.h"
|
#include "ztimer.h"
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
|
#include "periph/spi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "lcd_internal.h"
|
#include "lcd_internal.h"
|
||||||
|
|
||||||
#define ENABLE_DEBUG 0
|
#define ENABLE_DEBUG 0
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static inline void _lcd_write_byte(const lcd_t *dev, bool cont, uint8_t data)
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
|
||||||
|
#if MODULE_LCD_PARALLEL_16BIT
|
||||||
|
#error "MCU 8080 16-bit parallel interface is not supported yet"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void lcd_ll_par_write_byte(lcd_t *dev, bool cont, uint8_t out)
|
||||||
{
|
{
|
||||||
|
if (gpio_is_valid(dev->params->cs_pin)) {
|
||||||
|
gpio_clear(dev->params->cs_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_clear(dev->params->wrx_pin);
|
||||||
|
|
||||||
|
gpio_write(dev->params->d0_pin, out & 0x01);
|
||||||
|
gpio_write(dev->params->d1_pin, out & 0x02);
|
||||||
|
gpio_write(dev->params->d2_pin, out & 0x04);
|
||||||
|
gpio_write(dev->params->d3_pin, out & 0x08);
|
||||||
|
gpio_write(dev->params->d4_pin, out & 0x10);
|
||||||
|
gpio_write(dev->params->d5_pin, out & 0x20);
|
||||||
|
gpio_write(dev->params->d6_pin, out & 0x40);
|
||||||
|
gpio_write(dev->params->d7_pin, out & 0x80);
|
||||||
|
|
||||||
|
gpio_set(dev->params->wrx_pin);
|
||||||
|
|
||||||
|
if (gpio_is_valid(dev->params->cs_pin) && !cont) {
|
||||||
|
gpio_set(dev->params->cs_pin);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t lcd_ll_par_read_byte(lcd_t *dev, bool cont)
|
||||||
|
{
|
||||||
|
uint8_t in = 0;
|
||||||
|
|
||||||
|
if (gpio_is_valid(dev->params->cs_pin)) {
|
||||||
|
gpio_clear(dev->params->cs_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_clear(dev->params->rdx_pin);
|
||||||
|
|
||||||
|
in |= gpio_read(dev->params->d0_pin) ? 0x01 : 0;
|
||||||
|
in |= gpio_read(dev->params->d1_pin) ? 0x02 : 0;
|
||||||
|
in |= gpio_read(dev->params->d2_pin) ? 0x04 : 0;
|
||||||
|
in |= gpio_read(dev->params->d3_pin) ? 0x08 : 0;
|
||||||
|
in |= gpio_read(dev->params->d4_pin) ? 0x10 : 0;
|
||||||
|
in |= gpio_read(dev->params->d5_pin) ? 0x20 : 0;
|
||||||
|
in |= gpio_read(dev->params->d6_pin) ? 0x40 : 0;
|
||||||
|
in |= gpio_read(dev->params->d7_pin) ? 0x80 : 0;
|
||||||
|
|
||||||
|
gpio_set(dev->params->rdx_pin);
|
||||||
|
|
||||||
|
if (gpio_is_valid(dev->params->cs_pin) && !cont) {
|
||||||
|
gpio_set(dev->params->cs_pin);
|
||||||
|
};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lcd_ll_par_read_bytes(lcd_t *dev, bool cont,
|
||||||
|
void *data, size_t len)
|
||||||
|
{
|
||||||
|
assert(len);
|
||||||
|
|
||||||
|
uint8_t *data_in = data;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
data_in[i] = lcd_ll_par_read_byte(dev, i == (len - 1) ? cont : true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lcd_ll_par_write_bytes(lcd_t *dev, bool cont,
|
||||||
|
const void *data, size_t len)
|
||||||
|
{
|
||||||
|
assert(len);
|
||||||
|
|
||||||
|
const uint8_t *data_out = data;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
lcd_ll_par_write_byte(dev, i == (len - 1) ? cont : true, data_out[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* IS_USED(MODULE_LCD_PARALLEL) */
|
||||||
|
|
||||||
|
static inline void lcd_ll_write_byte(lcd_t *dev, bool cont, uint8_t data)
|
||||||
|
{
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
if (dev->params->spi != SPI_UNDEF) {
|
if (dev->params->spi != SPI_UNDEF) {
|
||||||
/* SPI serial interface is used */
|
/* SPI serial interface is used */
|
||||||
spi_transfer_byte(dev->params->spi, dev->params->cs_pin, cont, data);
|
spi_transfer_byte(dev->params->spi, dev->params->cs_pin, cont, data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
|
lcd_ll_par_write_byte(dev, cont, data);
|
||||||
|
#else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _lcd_write_bytes(const lcd_t *dev, bool cont,
|
static inline void lcd_ll_write_bytes(lcd_t *dev, bool cont,
|
||||||
const void *data, size_t len)
|
const void *data, size_t len)
|
||||||
{
|
{
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
if (dev->params->spi != SPI_UNDEF) {
|
if (dev->params->spi != SPI_UNDEF) {
|
||||||
/* SPI serial interface is used */
|
/* SPI serial interface is used */
|
||||||
spi_transfer_bytes(dev->params->spi,
|
spi_transfer_bytes(dev->params->spi,
|
||||||
dev->params->cs_pin, cont, data, NULL, len);
|
dev->params->cs_pin, cont, data, NULL, len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
|
lcd_ll_par_write_bytes(dev, cont, data, len);
|
||||||
|
#else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _lcd_read_bytes(const lcd_t *dev, bool cont,
|
static inline void lcd_ll_read_bytes(lcd_t *dev, bool cont,
|
||||||
void *data, size_t len)
|
void *data, size_t len)
|
||||||
{
|
{
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
if (dev->params->spi != SPI_UNDEF) {
|
if (dev->params->spi != SPI_UNDEF) {
|
||||||
/* SPI serial interface is used */
|
/* SPI serial interface is used */
|
||||||
/* Dummy read */
|
/* Dummy read */
|
||||||
@ -71,19 +177,50 @@ static inline void _lcd_read_bytes(const lcd_t *dev, bool cont,
|
|||||||
dev->params->cs_pin, cont, NULL, data, len);
|
dev->params->cs_pin, cont, NULL, data, len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
|
|
||||||
|
/* switch GPIO mode to input */
|
||||||
|
gpio_init(dev->params->d0_pin, GPIO_IN);
|
||||||
|
gpio_init(dev->params->d1_pin, GPIO_IN);
|
||||||
|
gpio_init(dev->params->d2_pin, GPIO_IN);
|
||||||
|
gpio_init(dev->params->d3_pin, GPIO_IN);
|
||||||
|
gpio_init(dev->params->d4_pin, GPIO_IN);
|
||||||
|
gpio_init(dev->params->d5_pin, GPIO_IN);
|
||||||
|
gpio_init(dev->params->d6_pin, GPIO_IN);
|
||||||
|
gpio_init(dev->params->d7_pin, GPIO_IN);
|
||||||
|
|
||||||
|
/* Dummy read */
|
||||||
|
lcd_ll_par_read_byte(dev, true);
|
||||||
|
lcd_ll_par_read_bytes(dev, cont, data, len);
|
||||||
|
|
||||||
|
/* switch GPIO mode back to output */
|
||||||
|
gpio_init(dev->params->d0_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d1_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d2_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d3_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d4_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d5_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d6_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d7_pin, GPIO_OUT);
|
||||||
|
#else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _lcd_cmd_start(const lcd_t *dev, uint8_t cmd, bool cont)
|
static void lcd_ll_cmd_start(lcd_t *dev, uint8_t cmd, bool cont)
|
||||||
{
|
{
|
||||||
gpio_clear(dev->params->dcx_pin);
|
gpio_clear(dev->params->dcx_pin);
|
||||||
_lcd_write_byte(dev, cont, cmd);
|
lcd_ll_write_byte(dev, cont, cmd);
|
||||||
gpio_set(dev->params->dcx_pin);
|
gpio_set(dev->params->dcx_pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _lcd_set_area_default(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
static void lcd_ll_set_area_default(lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||||
uint16_t y1, uint16_t y2)
|
uint16_t y1, uint16_t y2)
|
||||||
{
|
{
|
||||||
be_uint16_t params[2];
|
be_uint16_t params[2];
|
||||||
|
|
||||||
@ -106,54 +243,72 @@ static void _lcd_set_area_default(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
|||||||
sizeof(params));
|
sizeof(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _lcd_set_area(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
static void lcd_ll_set_area(lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||||
uint16_t y1, uint16_t y2)
|
uint16_t y1, uint16_t y2)
|
||||||
{
|
{
|
||||||
if (dev->driver->set_area) {
|
if (dev->driver->set_area) {
|
||||||
dev->driver->set_area(dev, x1, x2, y1, y2);
|
dev->driver->set_area(dev, x1, x2, y1, y2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_lcd_set_area_default(dev, x1, x2, y1, y2);
|
lcd_ll_set_area_default(dev, x1, x2, y1, y2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_ll_acquire(const lcd_t *dev)
|
void lcd_ll_acquire(lcd_t *dev)
|
||||||
{
|
{
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
if (dev->params->spi != SPI_UNDEF) {
|
if (dev->params->spi != SPI_UNDEF) {
|
||||||
/* SPI serial interface is used */
|
/* SPI serial interface is used */
|
||||||
spi_acquire(dev->params->spi, dev->params->cs_pin,
|
spi_acquire(dev->params->spi, dev->params->cs_pin,
|
||||||
dev->params->spi_mode, dev->params->spi_clk);
|
dev->params->spi_mode, dev->params->spi_clk);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
|
mutex_lock(&dev->lock);
|
||||||
|
#else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_ll_release(const lcd_t *dev)
|
void lcd_ll_release(lcd_t *dev)
|
||||||
{
|
{
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
if (dev->params->spi != SPI_UNDEF) {
|
if (dev->params->spi != SPI_UNDEF) {
|
||||||
/* SPI serial interface is used */
|
/* SPI serial interface is used */
|
||||||
spi_release(dev->params->spi);
|
spi_release(dev->params->spi);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
|
mutex_unlock(&dev->lock);
|
||||||
|
#else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_ll_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
void lcd_ll_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
_lcd_cmd_start(dev, cmd, len ? true : false);
|
lcd_ll_cmd_start(dev, cmd, len ? true : false);
|
||||||
if (len) {
|
if (len) {
|
||||||
_lcd_write_bytes(dev, false, data, len);
|
lcd_ll_write_bytes(dev, false, data, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_ll_read_cmd(const lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len)
|
void lcd_ll_read_cmd(lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
assert(len);
|
assert(len);
|
||||||
_lcd_cmd_start(dev, cmd, len ? true : false);
|
lcd_ll_cmd_start(dev, cmd, len ? true : false);
|
||||||
_lcd_read_bytes(dev, false, data, len);
|
lcd_ll_read_bytes(dev, false, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
||||||
@ -163,6 +318,7 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
|||||||
assert(gpio_is_valid(dev->params->dcx_pin));
|
assert(gpio_is_valid(dev->params->dcx_pin));
|
||||||
gpio_init(dev->params->dcx_pin, GPIO_OUT);
|
gpio_init(dev->params->dcx_pin, GPIO_OUT);
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
if (dev->params->spi != SPI_UNDEF) {
|
if (dev->params->spi != SPI_UNDEF) {
|
||||||
/* SPI serial interface is used */
|
/* SPI serial interface is used */
|
||||||
int res = spi_init_cs(dev->params->spi, dev->params->cs_pin);
|
int res = spi_init_cs(dev->params->spi, dev->params->cs_pin);
|
||||||
@ -173,8 +329,50 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(false);
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
|
if (gpio_is_valid(dev->params->cs_pin)) {
|
||||||
|
gpio_init(dev->params->cs_pin, GPIO_OUT);
|
||||||
|
gpio_set(dev->params->cs_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(gpio_is_valid(dev->params->wrx_pin));
|
||||||
|
gpio_init(dev->params->wrx_pin, GPIO_OUT);
|
||||||
|
gpio_set(dev->params->wrx_pin);
|
||||||
|
|
||||||
|
if (gpio_is_valid(dev->params->wrx_pin)) {
|
||||||
|
gpio_init(dev->params->wrx_pin, GPIO_OUT);
|
||||||
|
gpio_set(dev->params->wrx_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpio_is_valid(dev->params->rdx_pin)) {
|
||||||
|
gpio_init(dev->params->rdx_pin, GPIO_OUT);
|
||||||
|
gpio_set(dev->params->rdx_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(gpio_is_valid(dev->params->d0_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d1_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d2_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d3_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d4_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d5_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d6_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d7_pin));
|
||||||
|
gpio_init(dev->params->d0_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d1_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d2_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d3_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d4_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d5_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d6_pin, GPIO_OUT);
|
||||||
|
gpio_init(dev->params->d7_pin, GPIO_OUT);
|
||||||
|
#else
|
||||||
|
assert(false);
|
||||||
|
#endif
|
||||||
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (gpio_is_valid(dev->params->rst_pin)) {
|
if (gpio_is_valid(dev->params->rst_pin)) {
|
||||||
gpio_init(dev->params->rst_pin, GPIO_OUT);
|
gpio_init(dev->params->rst_pin, GPIO_OUT);
|
||||||
@ -184,12 +382,16 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
|||||||
}
|
}
|
||||||
ztimer_sleep(ZTIMER_MSEC, 120);
|
ztimer_sleep(ZTIMER_MSEC, 120);
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
mutex_init(&dev->lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* controller-specific init function has to be defined */
|
/* controller-specific init function has to be defined */
|
||||||
assert(dev->driver->init);
|
assert(dev->driver->init);
|
||||||
return dev->driver->init(dev, params);
|
return dev->driver->init(dev, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
void lcd_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
lcd_ll_acquire(dev);
|
lcd_ll_acquire(dev);
|
||||||
@ -197,14 +399,14 @@ void lcd_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
|||||||
lcd_ll_release(dev);
|
lcd_ll_release(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_read_cmd(const lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len)
|
void lcd_read_cmd(lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
lcd_ll_acquire(dev);
|
lcd_ll_acquire(dev);
|
||||||
lcd_ll_read_cmd(dev, cmd, data, len);
|
lcd_ll_read_cmd(dev, cmd, data, len);
|
||||||
lcd_ll_release(dev);
|
lcd_ll_release(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
void lcd_fill(lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
||||||
uint16_t y2, uint16_t color)
|
uint16_t y2, uint16_t color)
|
||||||
{
|
{
|
||||||
/* Send fill area to the display */
|
/* Send fill area to the display */
|
||||||
@ -219,22 +421,22 @@ void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
|||||||
/* Send fill area to the display */
|
/* Send fill area to the display */
|
||||||
lcd_ll_acquire(dev);
|
lcd_ll_acquire(dev);
|
||||||
|
|
||||||
_lcd_set_area(dev, x1, x2, y1, y2);
|
lcd_ll_set_area(dev, x1, x2, y1, y2);
|
||||||
/* Memory access command */
|
/* Memory access command */
|
||||||
_lcd_cmd_start(dev, LCD_CMD_RAMWR, true);
|
lcd_ll_cmd_start(dev, LCD_CMD_RAMWR, true);
|
||||||
|
|
||||||
if (IS_ACTIVE(CONFIG_LCD_LE_MODE)) {
|
if (IS_ACTIVE(CONFIG_LCD_LE_MODE)) {
|
||||||
color = htons(color);
|
color = htons(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (num_pix - 1); i++) {
|
for (int i = 0; i < (num_pix - 1); i++) {
|
||||||
_lcd_write_bytes(dev, true, (uint8_t *)&color, sizeof(color));
|
lcd_ll_write_bytes(dev, true, (uint8_t *)&color, sizeof(color));
|
||||||
}
|
}
|
||||||
_lcd_write_bytes(dev, false, (uint8_t *)&color, sizeof(color));
|
lcd_ll_write_bytes(dev, false, (uint8_t *)&color, sizeof(color));
|
||||||
lcd_ll_release(dev);
|
lcd_ll_release(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_pixmap(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
void lcd_pixmap(lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||||
uint16_t y1, uint16_t y2, const uint16_t *color)
|
uint16_t y1, uint16_t y2, const uint16_t *color)
|
||||||
{
|
{
|
||||||
size_t num_pix = (x2 - x1 + 1) * (y2 - y1 + 1);
|
size_t num_pix = (x2 - x1 + 1) * (y2 - y1 + 1);
|
||||||
@ -246,27 +448,27 @@ void lcd_pixmap(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
|||||||
lcd_ll_acquire(dev);
|
lcd_ll_acquire(dev);
|
||||||
|
|
||||||
/* Send fill area to the display */
|
/* Send fill area to the display */
|
||||||
_lcd_set_area(dev, x1, x2, y1, y2);
|
lcd_ll_set_area(dev, x1, x2, y1, y2);
|
||||||
|
|
||||||
/* Memory access command */
|
/* Memory access command */
|
||||||
_lcd_cmd_start(dev, LCD_CMD_RAMWR, true);
|
lcd_ll_cmd_start(dev, LCD_CMD_RAMWR, true);
|
||||||
|
|
||||||
if (IS_ACTIVE(CONFIG_LCD_LE_MODE)) {
|
if (IS_ACTIVE(CONFIG_LCD_LE_MODE)) {
|
||||||
for (size_t i = 0; i < num_pix - 1; i++) {
|
for (size_t i = 0; i < num_pix - 1; i++) {
|
||||||
uint16_t ncolor = htons(*(color + i));
|
uint16_t ncolor = htons(*(color + i));
|
||||||
_lcd_write_bytes(dev, true, &ncolor, sizeof(uint16_t));
|
lcd_ll_write_bytes(dev, true, &ncolor, sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
uint16_t ncolor = htons(*(color + num_pix - 1));
|
uint16_t ncolor = htons(*(color + num_pix - 1));
|
||||||
_lcd_write_bytes(dev, false, &ncolor, sizeof(uint16_t));
|
lcd_ll_write_bytes(dev, false, &ncolor, sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_lcd_write_bytes(dev, false, (const uint8_t *)color, num_pix * 2);
|
lcd_ll_write_bytes(dev, false, (const uint8_t *)color, num_pix * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_ll_release(dev);
|
lcd_ll_release(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_invert_on(const lcd_t *dev)
|
void lcd_invert_on(lcd_t *dev)
|
||||||
{
|
{
|
||||||
uint8_t command = (dev->params->inverted) ? LCD_CMD_DINVOFF
|
uint8_t command = (dev->params->inverted) ? LCD_CMD_DINVOFF
|
||||||
: LCD_CMD_DINVON;
|
: LCD_CMD_DINVON;
|
||||||
@ -274,7 +476,7 @@ void lcd_invert_on(const lcd_t *dev)
|
|||||||
lcd_write_cmd(dev, command, NULL, 0);
|
lcd_write_cmd(dev, command, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_invert_off(const lcd_t *dev)
|
void lcd_invert_off(lcd_t *dev)
|
||||||
{
|
{
|
||||||
uint8_t command = (dev->params->inverted) ? LCD_CMD_DINVON
|
uint8_t command = (dev->params->inverted) ? LCD_CMD_DINVON
|
||||||
: LCD_CMD_DINVOFF;
|
: LCD_CMD_DINVOFF;
|
||||||
@ -282,7 +484,7 @@ void lcd_invert_off(const lcd_t *dev)
|
|||||||
lcd_write_cmd(dev, command, NULL, 0);
|
lcd_write_cmd(dev, command, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_brightness(const lcd_t *dev, uint8_t brightness)
|
void lcd_set_brightness(lcd_t *dev, uint8_t brightness)
|
||||||
{
|
{
|
||||||
lcd_write_cmd(dev, LCD_CMD_WRDISBV, &brightness, 1);
|
lcd_write_cmd(dev, LCD_CMD_WRDISBV, &brightness, 1);
|
||||||
uint8_t param = 0x26;
|
uint8_t param = 0x26;
|
||||||
|
@ -57,7 +57,7 @@ static uint8_t _lcd_color_depth(const disp_dev_t *disp_dev)
|
|||||||
|
|
||||||
static void _lcd_set_invert(const disp_dev_t *disp_dev, bool invert)
|
static void _lcd_set_invert(const disp_dev_t *disp_dev, bool invert)
|
||||||
{
|
{
|
||||||
const lcd_t *dev = (lcd_t *)disp_dev;
|
lcd_t *dev = (lcd_t *)disp_dev;
|
||||||
|
|
||||||
assert(dev);
|
assert(dev);
|
||||||
|
|
||||||
|
@ -137,14 +137,46 @@ extern "C" {
|
|||||||
#define ST77XX_PARAM_OFFSET_Y 0 /**< Vertival offset */
|
#define ST77XX_PARAM_OFFSET_Y 0 /**< Vertival offset */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MODULE_LCD_SPI || DOXYGEN
|
||||||
|
/** Default interface params if SPI serial interface is enabled */
|
||||||
|
#define ST77XX_PARAM_IF_SPI .spi = ST77XX_PARAM_SPI, \
|
||||||
|
.spi_clk = ST77XX_PARAM_SPI_CLK, \
|
||||||
|
.spi_mode = ST77XX_PARAM_SPI_MODE,
|
||||||
|
#else
|
||||||
|
#define ST77XX_PARAM_IF_SPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MODULE_LCD_PARALLEL || DOXYGEN
|
||||||
|
/** Default interface params if MCU 8080 8-bit parallel interface is enabled */
|
||||||
|
#define ST77XX_PARAM_IF_PAR .d0_pin = ST77XX_PARAM_D0, \
|
||||||
|
.d1_pin = ST77XX_PARAM_D1, \
|
||||||
|
.d2_pin = ST77XX_PARAM_D2, \
|
||||||
|
.d3_pin = ST77XX_PARAM_D3, \
|
||||||
|
.d4_pin = ST77XX_PARAM_D4, \
|
||||||
|
.d5_pin = ST77XX_PARAM_D5, \
|
||||||
|
.d6_pin = ST77XX_PARAM_D6, \
|
||||||
|
.d7_pin = ST77XX_PARAM_D7, \
|
||||||
|
.wrx_pin = ST77XX_PARAM_WRX, \
|
||||||
|
.rdx_pin = ST77XX_PARAM_RDX,
|
||||||
|
#else
|
||||||
|
#define ST77XX_PARAM_IF_PAR
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default params
|
* @brief Default params
|
||||||
|
*
|
||||||
|
* @note The default parameter set defined here can only be used if a single
|
||||||
|
* ST77xx display and only one interface mode is used. If multiple
|
||||||
|
* ST77xx displays are used or if multiple interface modes are enabled
|
||||||
|
* by the modules `lcd_spi`, lcd_parallel and `lcd_parallel_16bit`, a user
|
||||||
|
* defined parameter set @ref ST77XX_PARAMS has to be defined. In the
|
||||||
|
* latter case @ref lcd_params_t::spi must then be set to @ref SPI_UNDEF
|
||||||
|
* for displays with MCU 8080 8-/16-bit parallel interfaces.
|
||||||
*/
|
*/
|
||||||
#ifndef ST77XX_PARAMS
|
#ifndef ST77XX_PARAMS
|
||||||
#define ST77XX_PARAMS { .cntrl = ST77XX_PARAM_CNTRL, \
|
#define ST77XX_PARAMS { .cntrl = ST77XX_PARAM_CNTRL, \
|
||||||
.spi = ST77XX_PARAM_SPI, \
|
ST77XX_PARAM_IF_SPI \
|
||||||
.spi_clk = ST77XX_PARAM_SPI_CLK, \
|
ST77XX_PARAM_IF_PAR \
|
||||||
.spi_mode = ST77XX_PARAM_SPI_MODE, \
|
|
||||||
.cs_pin = ST77XX_PARAM_CS, \
|
.cs_pin = ST77XX_PARAM_CS, \
|
||||||
.dcx_pin = ST77XX_PARAM_DCX, \
|
.dcx_pin = ST77XX_PARAM_DCX, \
|
||||||
.rst_pin = ST77XX_PARAM_RST, \
|
.rst_pin = ST77XX_PARAM_RST, \
|
||||||
@ -156,7 +188,7 @@ extern "C" {
|
|||||||
.offset_x = ST77XX_PARAM_OFFSET_X, \
|
.offset_x = ST77XX_PARAM_OFFSET_X, \
|
||||||
.offset_y = ST77XX_PARAM_OFFSET_Y, \
|
.offset_y = ST77XX_PARAM_OFFSET_Y, \
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* ST77XX_PARAMS */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user