mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/lcd: add MCU 8080 8-/16-bit parallel mode support
For the parallel interface support the following changes were made: 1. Additional `lcd_*` pseudomodules are defined to control whether SPI serial or MCU 8080 8-/16-bit parallel interface is used. 2. The low level function implementation was extended for parallel interfaces so that the now can use either the SPI serial interface or the MCU 8080 8-/16-bit parallel interface. Using the `lcc_*` modules, either the SPI serial interface or the MCU 8080 8-/16-bit interface or even both for multiple display can be used simultaneously.
This commit is contained in:
parent
f03bc3327c
commit
04c3facd8e
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Koen Zandberg
|
||||
* 2021 Francisco Molina
|
||||
* 2023 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -13,8 +14,22 @@
|
||||
*
|
||||
* @brief Driver for the LCD display
|
||||
*
|
||||
* The LCD is a generic display driver for small RGB displays. The driver
|
||||
* implemented here operates over SPI to communicate with the device.
|
||||
* The LCD is a generic display driver for small RGB displays. It communicates
|
||||
* 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
|
||||
* @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 Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
*/
|
||||
|
||||
@ -35,6 +51,7 @@
|
||||
#define LCD_H
|
||||
|
||||
#include "board.h"
|
||||
#include "mutex.h"
|
||||
#include "periph/spi.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
@ -70,18 +87,58 @@ extern "C" {
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
#if MODULE_LCD_SPI || DOXYGEN
|
||||
/* Interface parameters used for serial interface */
|
||||
spi_t spi; /**< SPI device that the display is connected to */
|
||||
spi_clk_t spi_clk; /**< SPI clock speed to use */
|
||||
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 dcx_pin; /**< pin connected to the DC line */
|
||||
gpio_t rst_pin; /**< pin connected to the reset line */
|
||||
bool rgb; /**< True when display is connected in RGB mode
|
||||
* False when display is connected in BGR mode */
|
||||
gpio_t rst_pin; /**< pin connected to the RESET line */
|
||||
bool rgb; /**< True when display is connected in RGB mode\n
|
||||
False when display is connected in BGR 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 */
|
||||
uint8_t rotation; /**< Display rotation mode */
|
||||
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
|
||||
*/
|
||||
typedef struct {
|
||||
#ifdef MODULE_DISP_DEV
|
||||
#if MODULE_DISP_DEV || DOXYGEN
|
||||
disp_dev_t *dev; /**< Pointer to the generic display device */
|
||||
#endif
|
||||
const lcd_driver_t *driver; /**< LCD driver */
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -142,7 +203,7 @@ struct lcd_driver {
|
||||
* @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);
|
||||
};
|
||||
|
||||
@ -162,14 +223,14 @@ struct lcd_driver {
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @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
|
||||
@ -182,7 +243,7 @@ void lcd_ll_release(const lcd_t *dev);
|
||||
* @param[in] data command data to the device
|
||||
* @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);
|
||||
|
||||
/**
|
||||
@ -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[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] 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);
|
||||
|
||||
/**
|
||||
@ -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] 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);
|
||||
|
||||
/**
|
||||
@ -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] 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);
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @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[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
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*/
|
||||
void lcd_invert_on(const lcd_t *dev);
|
||||
void lcd_invert_on(lcd_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Disable color inversion
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*/
|
||||
void lcd_invert_off(const lcd_t *dev);
|
||||
void lcd_invert_off(lcd_t *dev);
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -7,10 +7,8 @@
|
||||
|
||||
config MODULE_LCD
|
||||
bool "LCD display driver"
|
||||
depends on HAS_PERIPH_SPI
|
||||
depends on HAS_PERIPH_GPIO
|
||||
depends on TEST_KCONFIG
|
||||
select MODULE_PERIPH_SPI
|
||||
select MODULE_PERIPH_GPIO
|
||||
|
||||
config MODULE_LCD_MULTI_CNTRL
|
||||
@ -18,6 +16,48 @@ config MODULE_LCD_MULTI_CNTRL
|
||||
help
|
||||
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
|
||||
bool "Configure LCD driver"
|
||||
depends on USEMODULE_LCD
|
||||
|
@ -1,2 +1,14 @@
|
||||
FEATURES_REQUIRED += periph_spi
|
||||
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_spi
|
||||
PSEUDOMODULES += lcd_parallel
|
||||
PSEUDOMODULES += lcd_parallel_16bit
|
||||
|
||||
USEMODULE_INCLUDES_lcd := $(LAST_MAKEFILEDIR)/include
|
||||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_lcd)
|
||||
|
@ -25,43 +25,149 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "byteorder.h"
|
||||
#include "periph/spi.h"
|
||||
#include "kernel_defines.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
#include "periph/spi.h"
|
||||
#endif
|
||||
|
||||
#include "lcd.h"
|
||||
#include "lcd_internal.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
static inline void lcd_ll_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) {
|
||||
/* SPI serial interface is used */
|
||||
spi_transfer_byte(dev->params->spi, dev->params->cs_pin, cont, data);
|
||||
}
|
||||
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);
|
||||
#endif
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void lcd_ll_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)
|
||||
{
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
if (dev->params->spi != SPI_UNDEF) {
|
||||
/* SPI serial interface is used */
|
||||
spi_transfer_bytes(dev->params->spi,
|
||||
dev->params->cs_pin, cont, data, NULL, len);
|
||||
}
|
||||
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);
|
||||
#endif
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void lcd_ll_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)
|
||||
{
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
if (dev->params->spi != SPI_UNDEF) {
|
||||
/* SPI serial interface is used */
|
||||
/* Dummy read */
|
||||
@ -71,18 +177,49 @@ static inline void lcd_ll_read_bytes(const lcd_t *dev, bool cont,
|
||||
dev->params->cs_pin, cont, NULL, data, len);
|
||||
}
|
||||
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);
|
||||
#endif
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void lcd_ll_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);
|
||||
lcd_ll_write_byte(dev, cont, cmd);
|
||||
gpio_set(dev->params->dcx_pin);
|
||||
}
|
||||
|
||||
static void lcd_ll_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)
|
||||
{
|
||||
be_uint16_t params[2];
|
||||
@ -106,7 +243,7 @@ static void lcd_ll_set_area_default(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||
sizeof(params));
|
||||
}
|
||||
|
||||
static void lcd_ll_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)
|
||||
{
|
||||
if (dev->driver->set_area) {
|
||||
@ -117,30 +254,48 @@ static void lcd_ll_set_area(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
/* SPI serial interface is used */
|
||||
spi_acquire(dev->params->spi, dev->params->cs_pin,
|
||||
dev->params->spi_mode, dev->params->spi_clk);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||
mutex_lock(&dev->lock);
|
||||
#else
|
||||
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) {
|
||||
/* SPI serial interface is used */
|
||||
spi_release(dev->params->spi);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||
mutex_unlock(&dev->lock);
|
||||
#else
|
||||
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)
|
||||
{
|
||||
lcd_ll_cmd_start(dev, cmd, len ? true : false);
|
||||
@ -149,7 +304,7 @@ void lcd_ll_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *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)
|
||||
{
|
||||
assert(len);
|
||||
lcd_ll_cmd_start(dev, cmd, len ? true : false);
|
||||
@ -163,6 +318,7 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
||||
assert(gpio_is_valid(dev->params->dcx_pin));
|
||||
gpio_init(dev->params->dcx_pin, GPIO_OUT);
|
||||
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
if (dev->params->spi != SPI_UNDEF) {
|
||||
/* SPI serial interface is used */
|
||||
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 {
|
||||
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)) {
|
||||
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);
|
||||
|
||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||
mutex_init(&dev->lock);
|
||||
#endif
|
||||
|
||||
/* controller-specific init function has to be defined */
|
||||
assert(dev->driver->init);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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_read_cmd(dev, cmd, data, len);
|
||||
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)
|
||||
{
|
||||
/* Send fill area to the display */
|
||||
@ -234,7 +436,7 @@ void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
||||
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)
|
||||
{
|
||||
size_t num_pix = (x2 - x1 + 1) * (y2 - y1 + 1);
|
||||
@ -266,7 +468,7 @@ void lcd_pixmap(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||
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
|
||||
: LCD_CMD_DINVON;
|
||||
@ -274,7 +476,7 @@ void lcd_invert_on(const lcd_t *dev)
|
||||
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
|
||||
: LCD_CMD_DINVOFF;
|
||||
@ -282,7 +484,7 @@ void lcd_invert_off(const lcd_t *dev)
|
||||
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);
|
||||
uint8_t param = 0x26;
|
||||
|
Loading…
Reference in New Issue
Block a user