mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 00:09:46 +01:00
drivers/lcd: add MCU-driven low-level parallel interface
This commit is contained in:
parent
0353e05bc3
commit
e0a76c5768
@ -256,8 +256,8 @@ void lcd_ll_release(lcd_t *dev);
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] cmd command code
|
||||
* @param[in] data command data to the device
|
||||
* @param[in] len length of the command data
|
||||
* @param[in] data command data to the device or NULL for commands without data
|
||||
* @param[in] len length of the command data or 0 for commands without data
|
||||
*/
|
||||
void lcd_ll_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||
size_t len);
|
||||
@ -350,8 +350,8 @@ void lcd_pixmap(lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] cmd command code
|
||||
* @param[in] data command data to the device
|
||||
* @param[in] len length of the command data
|
||||
* @param[in] data command data to the device or NULL for commands without data
|
||||
* @param[in] len length of the command data or 0 for commands without data
|
||||
*/
|
||||
void lcd_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||
size_t len);
|
||||
@ -387,6 +387,109 @@ void lcd_invert_on(lcd_t *dev);
|
||||
void lcd_invert_off(lcd_t *dev);
|
||||
/** @} */
|
||||
|
||||
#if MODULE_LCD_PARALLEL || DOXYGEN
|
||||
/**
|
||||
* @name Low-level MCU 8080 8-/16-bit parallel interface
|
||||
*
|
||||
* The low-level MCU 8080 8-/16-bit parallel interface (low-level parallel
|
||||
* interface for short) is used when the LCD device is connected via a parallel
|
||||
* interface. Either the GPIO-driven low-level parallel interface provided by
|
||||
* this LCD driver or a low-level parallel interface implemented by the MCU,
|
||||
* such as the STM32 FMC peripheral, can be used. If the MCU provides its
|
||||
* own implementation of the low-level parallel interface, it can be used
|
||||
* by implementing the following low-level parallel interface driver functions,
|
||||
* enabling the `lcd_parallel_ll_mcu` module and defining the
|
||||
* @ref lcd_ll_par_driver variable of type @ref lcd_ll_par_driver_t.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Low-level MCU 8080 8-/16-bit parallel interface driver
|
||||
*
|
||||
* If the MCU-driven low-level parallel interface is enabled by
|
||||
* module `lcd_ll_parallel_mcu`, the implementation of the MCU low-level
|
||||
* parallel interface has to define a variable @ref lcd_ll_par_driver of this
|
||||
* type. All or a set of members have to point to the low-level parallel
|
||||
* interface functions implemented by the MCU. For functions that are not
|
||||
* implemented by the MCU, the members have to be set to the corresponding
|
||||
* GPIO-driven low-level parallel interface functions provided by the LCD
|
||||
* driver.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Initialize the MCU-driven low-level parallel interface
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*/
|
||||
void (*init)(lcd_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set the data direction of the low-level parallel interface
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] output set to output mode if true and to input mode otherwise
|
||||
*/
|
||||
void (*set_data_dir)(lcd_t *dev, bool output);
|
||||
|
||||
/**
|
||||
* @brief Write command using the MCU-driven low-level parallel interface
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] cmd command
|
||||
* @param[in] cont operation is continued
|
||||
*/
|
||||
void (*cmd_start)(lcd_t *dev, uint8_t cmd, bool cont);
|
||||
|
||||
/**
|
||||
* @brief Write a byte using the MCU-driven low-level parallel interface
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] cont operation is continued
|
||||
* @param[in] out byte to be written
|
||||
*/
|
||||
void (*write_byte)(lcd_t *dev, bool cont, uint8_t out);
|
||||
|
||||
/**
|
||||
* @brief Read a byte using the MCU-driven low-level parallel interface
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] cont operation is continued
|
||||
*
|
||||
* @return byte read
|
||||
*/
|
||||
uint8_t (*read_byte)(lcd_t *dev, bool cont);
|
||||
|
||||
#if MODULE_LCD_PARALLEL_16BIT || DOXYGEN
|
||||
/**
|
||||
* @brief Write a word using the MCU-driven low-level parallel interface
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] cont operation is continued
|
||||
* @param[in] out word to be written
|
||||
*/
|
||||
void (*write_word)(lcd_t *dev, bool cont, uint16_t out);
|
||||
|
||||
/**
|
||||
* @brief Read a word using the MCU-driven low-level parallel interface
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] cont operation is continued
|
||||
*
|
||||
* @return word read
|
||||
*/
|
||||
uint16_t (*read_word)(lcd_t *dev, bool cont);
|
||||
#endif
|
||||
} lcd_ll_par_driver_t;
|
||||
|
||||
/**
|
||||
* @brief Low-level parallel interface driver instance
|
||||
*/
|
||||
extern const lcd_ll_par_driver_t lcd_ll_par_driver;
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -11,6 +11,8 @@ config MODULE_LCD
|
||||
depends on TEST_KCONFIG
|
||||
select MODULE_PERIPH_GPIO
|
||||
|
||||
if MODULE_LCD
|
||||
|
||||
config MODULE_LCD_MULTI_CNTRL
|
||||
bool
|
||||
help
|
||||
@ -21,7 +23,6 @@ config MODULE_LCD_SPI
|
||||
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
|
||||
@ -29,17 +30,24 @@ config MODULE_LCD_SPI
|
||||
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 MODULE_LCD_PARALLEL_LL_MCU
|
||||
bool
|
||||
default y if HAVE_LCD_PARALLEL_LL_MCU
|
||||
depends on MODULE_LCD_PARALLEL
|
||||
help
|
||||
MCU 8080 8-/16-bit low-level parallel interface is provided by the MCU.
|
||||
|
||||
endif
|
||||
|
||||
config HAVE_LCD_SPI
|
||||
bool
|
||||
help
|
||||
@ -58,6 +66,12 @@ config HAVE_LCD_PARALLEL_16BIT
|
||||
Indicates that a display with MCU 8080 16-bit parallel interface
|
||||
is present
|
||||
|
||||
config HAVE_LCD_PARALLEL_LL_MCU
|
||||
bool
|
||||
help
|
||||
Indicates that the MCU provides the MCU 8080 8-/16-bit low-level
|
||||
parallel interface implementation.
|
||||
|
||||
menuconfig KCONFIG_USEMODULE_LCD
|
||||
bool "Configure LCD driver"
|
||||
depends on USEMODULE_LCD
|
||||
|
@ -1,6 +1,6 @@
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
|
||||
ifneq (,$(filter lcd_parallel_16bit,$(USEMODULE)))
|
||||
ifneq (,$(filter lcd_parallel_%,$(USEMODULE)))
|
||||
USEMODULE += lcd_parallel
|
||||
endif
|
||||
|
||||
|
@ -3,6 +3,7 @@ PSEUDOMODULES += lcd_multi_cntrl
|
||||
PSEUDOMODULES += lcd_spi
|
||||
PSEUDOMODULES += lcd_parallel
|
||||
PSEUDOMODULES += lcd_parallel_16bit
|
||||
PSEUDOMODULES += lcd_parallel_ll_mcu
|
||||
|
||||
USEMODULE_INCLUDES_lcd := $(LAST_MAKEFILEDIR)/include
|
||||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_lcd)
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
#include "byteorder.h"
|
||||
#include "kernel_defines.h"
|
||||
#include "log.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
@ -43,24 +44,24 @@
|
||||
|
||||
static void lcd_ll_par_write_byte(lcd_t *dev, bool cont, uint8_t out)
|
||||
{
|
||||
lcd_ll_par_gpio_write_byte(dev, cont, out);
|
||||
lcd_ll_par_driver.write_byte(dev, cont, out);
|
||||
}
|
||||
|
||||
static uint8_t lcd_ll_par_read_byte(lcd_t *dev, bool cont)
|
||||
{
|
||||
return lcd_ll_par_gpio_read_byte(dev, cont);
|
||||
return lcd_ll_par_driver.read_byte(dev, cont);
|
||||
}
|
||||
|
||||
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||
|
||||
static void lcd_ll_par_write_word(lcd_t *dev, bool cont, uint16_t out)
|
||||
{
|
||||
lcd_ll_par_gpio_write_word(dev, cont, out);
|
||||
lcd_ll_par_driver.write_word(dev, cont, out);
|
||||
}
|
||||
|
||||
static uint16_t lcd_ll_par_read_word(lcd_t *dev, bool cont)
|
||||
{
|
||||
return lcd_ll_par_gpio_read_word(dev, cont);
|
||||
return lcd_ll_par_driver.read_word(dev, cont);
|
||||
}
|
||||
|
||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||
@ -83,7 +84,7 @@ static void lcd_ll_par_write_bytes(lcd_t *dev, bool cont,
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
lcd_ll_par_write_byte(dev, i == (len - 1) ? cont : true, data_out[i]);
|
||||
@ -108,7 +109,7 @@ static void lcd_ll_par_read_bytes(lcd_t *dev, bool cont,
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
data_in[i] = lcd_ll_par_read_byte(dev, i == (len - 1) ? cont : true);
|
||||
@ -129,8 +130,6 @@ static inline void lcd_ll_write_byte(lcd_t *dev, bool cont, uint8_t data)
|
||||
#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)
|
||||
}
|
||||
@ -151,8 +150,6 @@ static inline void lcd_ll_write_bytes(lcd_t *dev, bool cont,
|
||||
#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)
|
||||
}
|
||||
@ -172,21 +169,19 @@ static inline void lcd_ll_read_bytes(lcd_t *dev, bool cont,
|
||||
dev->params->cs_pin, cont, NULL, data, len);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#endif /* IS_USED(MODULE_LCD_SPI) */
|
||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||
|
||||
/* switch GPIO mode to input */
|
||||
lcd_ll_par_gpio_set_data_dir(dev, false);
|
||||
lcd_ll_par_driver.set_data_dir(dev, false);
|
||||
|
||||
/* Dummy read */
|
||||
lcd_ll_par_read_byte(dev, true);
|
||||
lcd_ll_par_read_bytes(dev, cont, data, len);
|
||||
|
||||
/* switch GPIO mode back to output */
|
||||
lcd_ll_par_gpio_set_data_dir(dev, true);
|
||||
#else
|
||||
assert(false);
|
||||
lcd_ll_par_driver.set_data_dir(dev, true);
|
||||
#endif
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
}
|
||||
@ -197,7 +192,7 @@ static void lcd_ll_cmd_start(lcd_t *dev, uint8_t cmd, bool cont)
|
||||
{
|
||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||
if (dev->params->mode != LCD_IF_SPI) {
|
||||
lcd_ll_par_gpio_cmd_start(dev, cmd, cont);
|
||||
lcd_ll_par_driver.cmd_start(dev, cmd, cont);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
@ -265,8 +260,6 @@ void lcd_ll_acquire(lcd_t *dev)
|
||||
#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)
|
||||
}
|
||||
@ -290,8 +283,6 @@ void lcd_ll_release(lcd_t *dev)
|
||||
#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)
|
||||
}
|
||||
@ -336,11 +327,11 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
||||
{
|
||||
dev->params = 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) {
|
||||
assert(gpio_is_valid(dev->params->dcx_pin));
|
||||
gpio_init(dev->params->dcx_pin, GPIO_OUT);
|
||||
|
||||
/* SPI serial interface is used */
|
||||
int res = spi_init_cs(dev->params->spi, dev->params->cs_pin);
|
||||
|
||||
@ -350,12 +341,25 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
#endif /* IS_USED(MODULE_LCD_SPI) */
|
||||
|
||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||
lcd_ll_par_gpio_init(dev);
|
||||
#else
|
||||
mutex_init(&dev->lock);
|
||||
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||
dev->word_access = false;
|
||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||
|
||||
/* Low-level parallel interface initialization */
|
||||
lcd_ll_par_driver.init(dev);
|
||||
/* set output data direction */
|
||||
lcd_ll_par_driver.set_data_dir(dev, true);
|
||||
|
||||
#else /* IS_USED(MODULE_LCD_PARALLEL) */
|
||||
|
||||
LOG_ERROR("[lcd] either lcd_parallel or lcd_spi has to be enabled");
|
||||
assert(false);
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_LCD_SPI)
|
||||
}
|
||||
#endif
|
||||
@ -368,10 +372,6 @@ 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);
|
||||
|
@ -243,4 +243,20 @@ uint16_t lcd_ll_par_gpio_read_word(lcd_t *dev, bool cont)
|
||||
}
|
||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||
|
||||
#if !IS_USED(MODULE_LCD_PARALLEL_LL_MCU)
|
||||
/* If MCU-driven low-level implementation is not used, the GPIO-driven
|
||||
* implementation is used as driver. */
|
||||
const lcd_ll_par_driver_t lcd_ll_par_driver = {
|
||||
.init = lcd_ll_par_gpio_init,
|
||||
.set_data_dir = lcd_ll_par_gpio_set_data_dir,
|
||||
.cmd_start = lcd_ll_par_gpio_cmd_start,
|
||||
.write_byte = lcd_ll_par_gpio_write_byte,
|
||||
.read_byte = lcd_ll_par_gpio_read_byte,
|
||||
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||
.write_word = lcd_ll_par_gpio_write_word,
|
||||
.read_word = lcd_ll_par_gpio_read_word,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* IS_USED(MODULE_LCD_PARALLEL) */
|
||||
|
Loading…
Reference in New Issue
Block a user