mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge #19941
19941: drivers/lcd: add MCU-driven low-level parallel interface r=benpicco a=gschorcht ### Contribution description The PR extends the LCD driver by a low-level interface for MCU-driven implementations of the MCU 8080 16-/8-bit parallel interface, allowing the MCU to use special peripherals for the interface, such as the FMC for STM32 MCUs, which is significantly faster than the integrated GPIO-driven parallel interface implementation of the LCD driver. ### Testing procedure ~Once PR #19938 and PR #19939 are merged, a PRs for these board can be pushed that allow to test this PR.~ Use either PR #19943 or PR #19944 on top of this PR to test, e.g. with PR #19943: ``` BOARD=stm32f723e-disco make -j8 -C tests/drivers/st77xx flash ``` ### Issues/PRs references Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
This commit is contained in:
commit
dd62f419d7
@ -256,8 +256,8 @@ void lcd_ll_release(lcd_t *dev);
|
|||||||
*
|
*
|
||||||
* @param[in] dev device descriptor
|
* @param[in] dev device descriptor
|
||||||
* @param[in] cmd command code
|
* @param[in] cmd command code
|
||||||
* @param[in] data command data to the device
|
* @param[in] data command data to the device or NULL for commands without data
|
||||||
* @param[in] len length of the command 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,
|
void lcd_ll_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||||
size_t len);
|
size_t len);
|
||||||
@ -279,6 +279,18 @@ void lcd_ll_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
|||||||
* @param[in] len length of the returned data
|
* @param[in] len length of the returned data
|
||||||
*/
|
*/
|
||||||
void lcd_ll_read_cmd(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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the LCD work area
|
||||||
|
*
|
||||||
|
* @param[in] dev Pointer to the selected driver
|
||||||
|
* @param[in] x1 x coordinate of the first corner
|
||||||
|
* @param[in] x2 x coordinate of the opposite corner
|
||||||
|
* @param[in] y1 y coordinate of the first corner
|
||||||
|
* @param[in] y2 y coordinate of the opposite corner
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void lcd_ll_set_area(lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -338,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] dev device descriptor
|
||||||
* @param[in] cmd command code
|
* @param[in] cmd command code
|
||||||
* @param[in] data command data to the device
|
* @param[in] data command data to the device or NULL for commands without data
|
||||||
* @param[in] len length of the command 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,
|
void lcd_write_cmd(lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||||
size_t len);
|
size_t len);
|
||||||
@ -375,6 +387,109 @@ void lcd_invert_on(lcd_t *dev);
|
|||||||
void lcd_invert_off(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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,6 +11,8 @@ config MODULE_LCD
|
|||||||
depends on TEST_KCONFIG
|
depends on TEST_KCONFIG
|
||||||
select MODULE_PERIPH_GPIO
|
select MODULE_PERIPH_GPIO
|
||||||
|
|
||||||
|
if MODULE_LCD
|
||||||
|
|
||||||
config MODULE_LCD_MULTI_CNTRL
|
config MODULE_LCD_MULTI_CNTRL
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
@ -21,7 +23,6 @@ config MODULE_LCD_SPI
|
|||||||
default y if !MODULE_LCD_PARALLEL && !MODULE_LCD_PARALLEL_16BIT
|
default y if !MODULE_LCD_PARALLEL && !MODULE_LCD_PARALLEL_16BIT
|
||||||
default y if HAVE_LCD_SPI
|
default y if HAVE_LCD_SPI
|
||||||
depends on HAS_PERIPH_SPI
|
depends on HAS_PERIPH_SPI
|
||||||
depends on MODULE_LCD
|
|
||||||
select MODULE_PERIPH_SPI
|
select MODULE_PERIPH_SPI
|
||||||
help
|
help
|
||||||
SPI serial interface is used
|
SPI serial interface is used
|
||||||
@ -29,17 +30,24 @@ config MODULE_LCD_SPI
|
|||||||
config MODULE_LCD_PARALLEL
|
config MODULE_LCD_PARALLEL
|
||||||
bool
|
bool
|
||||||
default y if HAVE_LCD_PARALLEL || HAVE_LCD_PARALLEL_16BIT
|
default y if HAVE_LCD_PARALLEL || HAVE_LCD_PARALLEL_16BIT
|
||||||
depends on MODULE_LCD
|
|
||||||
help
|
help
|
||||||
MCU 8080 8-/16-bit parallel interface is used
|
MCU 8080 8-/16-bit parallel interface is used
|
||||||
|
|
||||||
config MODULE_LCD_PARALLEL_16BIT
|
config MODULE_LCD_PARALLEL_16BIT
|
||||||
bool
|
bool
|
||||||
default y if HAVE_LCD_PARALLEL_16BIT
|
default y if HAVE_LCD_PARALLEL_16BIT
|
||||||
depends on MODULE_LCD
|
|
||||||
help
|
help
|
||||||
MCU 8080 16-bit paralell interface is used
|
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
|
config HAVE_LCD_SPI
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
@ -58,6 +66,12 @@ config HAVE_LCD_PARALLEL_16BIT
|
|||||||
Indicates that a display with MCU 8080 16-bit parallel interface
|
Indicates that a display with MCU 8080 16-bit parallel interface
|
||||||
is present
|
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
|
menuconfig KCONFIG_USEMODULE_LCD
|
||||||
bool "Configure LCD driver"
|
bool "Configure LCD driver"
|
||||||
depends on USEMODULE_LCD
|
depends on USEMODULE_LCD
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
FEATURES_REQUIRED += periph_gpio
|
FEATURES_REQUIRED += periph_gpio
|
||||||
|
|
||||||
ifneq (,$(filter lcd_parallel_16bit,$(USEMODULE)))
|
ifneq (,$(filter lcd_parallel_%,$(USEMODULE)))
|
||||||
USEMODULE += lcd_parallel
|
USEMODULE += lcd_parallel
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ PSEUDOMODULES += lcd_multi_cntrl
|
|||||||
PSEUDOMODULES += lcd_spi
|
PSEUDOMODULES += lcd_spi
|
||||||
PSEUDOMODULES += lcd_parallel
|
PSEUDOMODULES += lcd_parallel
|
||||||
PSEUDOMODULES += lcd_parallel_16bit
|
PSEUDOMODULES += lcd_parallel_16bit
|
||||||
|
PSEUDOMODULES += lcd_parallel_ll_mcu
|
||||||
|
|
||||||
USEMODULE_INCLUDES_lcd := $(LAST_MAKEFILEDIR)/include
|
USEMODULE_INCLUDES_lcd := $(LAST_MAKEFILEDIR)/include
|
||||||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_lcd)
|
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_lcd)
|
||||||
|
@ -35,6 +35,7 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define LCD_CMD_SWRESET 0x01 /**< Software reset */
|
#define LCD_CMD_SWRESET 0x01 /**< Software reset */
|
||||||
#define LCD_CMD_RDDIDIF 0x04 /**< Read display ID */
|
#define LCD_CMD_RDDIDIF 0x04 /**< Read display ID */
|
||||||
|
#define LCD_CMD_RDDST 0x09 /**< Read display status */
|
||||||
#define LCD_CMD_SLPIN 0x10 /**< Enter sleep mode */
|
#define LCD_CMD_SLPIN 0x10 /**< Enter sleep mode */
|
||||||
#define LCD_CMD_SLPOUT 0x11 /**< Sleep out */
|
#define LCD_CMD_SLPOUT 0x11 /**< Sleep out */
|
||||||
#define LCD_CMD_NORON 0x13 /**< Normal display mode on */
|
#define LCD_CMD_NORON 0x13 /**< Normal display mode on */
|
||||||
|
100
drivers/lcd/include/lcd_ll_par_gpio.h
Normal file
100
drivers/lcd/include/lcd_ll_par_gpio.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 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
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !DOXYGEN /* hide from documentation */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup drivers_lcd
|
||||||
|
*
|
||||||
|
* @brief GPIO-driven low-level parallel interface implementation
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
* @file
|
||||||
|
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LCD_LL_PAR_GPIO_H
|
||||||
|
#define LCD_LL_PAR_GPIO_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "lcd.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the GPIOs of the GPIO-driven low-level parallel interface
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor
|
||||||
|
*/
|
||||||
|
|
||||||
|
void lcd_ll_par_gpio_init(lcd_t *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the direction of the data GPIOs 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 lcd_ll_par_gpio_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 lcd_ll_par_gpio_cmd_start(lcd_t *dev, uint8_t cmd, bool cont);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a byte to the GPIO-driven low-level parallel interface
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor
|
||||||
|
* @param[in] cont operation is continued
|
||||||
|
* @param[in] out byte to be written
|
||||||
|
*/
|
||||||
|
void lcd_ll_par_gpio_write_byte(lcd_t *dev, bool cont, uint8_t out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a word to the GPIO-driven low-level parallel interface
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor
|
||||||
|
* @param[in] cont operation is continued
|
||||||
|
* @param[in] out word to be written
|
||||||
|
*/
|
||||||
|
void lcd_ll_par_gpio_write_word(lcd_t *dev, bool cont, uint16_t out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a byte from the GPIO-driven low-level parallel interface
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor
|
||||||
|
* @param[in] cont operation is continued
|
||||||
|
*
|
||||||
|
* @return read byte
|
||||||
|
*/
|
||||||
|
uint8_t lcd_ll_par_gpio_read_byte(lcd_t *dev, bool cont);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a word from the GPIO-driven low-level parallel interface
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor
|
||||||
|
* @param[in] cont operation is continued
|
||||||
|
*
|
||||||
|
* @return read word
|
||||||
|
*/
|
||||||
|
uint16_t lcd_ll_par_gpio_read_word(lcd_t *dev, bool cont);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* LCD_LL_PAR_GPIO_H */
|
||||||
|
/** @} */
|
||||||
|
#endif /* !DOXYGEN */
|
@ -26,6 +26,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "byteorder.h"
|
#include "byteorder.h"
|
||||||
#include "kernel_defines.h"
|
#include "kernel_defines.h"
|
||||||
|
#include "log.h"
|
||||||
#include "ztimer.h"
|
#include "ztimer.h"
|
||||||
|
|
||||||
#if IS_USED(MODULE_LCD_SPI)
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
@ -34,6 +35,7 @@
|
|||||||
|
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "lcd_internal.h"
|
#include "lcd_internal.h"
|
||||||
|
#include "lcd_ll_par_gpio.h"
|
||||||
|
|
||||||
#define ENABLE_DEBUG 0
|
#define ENABLE_DEBUG 0
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@ -42,125 +44,26 @@
|
|||||||
|
|
||||||
static void lcd_ll_par_write_byte(lcd_t *dev, bool cont, uint8_t out)
|
static void lcd_ll_par_write_byte(lcd_t *dev, bool cont, uint8_t out)
|
||||||
{
|
{
|
||||||
if (gpio_is_valid(dev->params->cs_pin)) {
|
lcd_ll_par_driver.write_byte(dev, cont, out);
|
||||||
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)
|
static uint8_t lcd_ll_par_read_byte(lcd_t *dev, bool cont)
|
||||||
{
|
{
|
||||||
uint8_t in = 0;
|
return lcd_ll_par_driver.read_byte(dev, cont);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||||
|
|
||||||
static void lcd_ll_par_write_word(lcd_t *dev, bool cont, uint16_t out)
|
static void lcd_ll_par_write_word(lcd_t *dev, bool cont, uint16_t out)
|
||||||
{
|
{
|
||||||
if (gpio_is_valid(dev->params->cs_pin)) {
|
lcd_ll_par_driver.write_word(dev, cont, out);
|
||||||
gpio_clear(dev->params->cs_pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_clear(dev->params->wrx_pin);
|
|
||||||
|
|
||||||
gpio_write(dev->params->d0_pin, out & 0x0001);
|
|
||||||
gpio_write(dev->params->d1_pin, out & 0x0002);
|
|
||||||
gpio_write(dev->params->d2_pin, out & 0x0004);
|
|
||||||
gpio_write(dev->params->d3_pin, out & 0x0008);
|
|
||||||
gpio_write(dev->params->d4_pin, out & 0x0010);
|
|
||||||
gpio_write(dev->params->d5_pin, out & 0x0020);
|
|
||||||
gpio_write(dev->params->d6_pin, out & 0x0040);
|
|
||||||
gpio_write(dev->params->d7_pin, out & 0x0080);
|
|
||||||
gpio_write(dev->params->d8_pin, out & 0x0100);
|
|
||||||
gpio_write(dev->params->d9_pin, out & 0x0200);
|
|
||||||
gpio_write(dev->params->d10_pin, out & 0x0400);
|
|
||||||
gpio_write(dev->params->d11_pin, out & 0x0800);
|
|
||||||
gpio_write(dev->params->d12_pin, out & 0x1000);
|
|
||||||
gpio_write(dev->params->d13_pin, out & 0x2000);
|
|
||||||
gpio_write(dev->params->d14_pin, out & 0x4000);
|
|
||||||
gpio_write(dev->params->d15_pin, out & 0x8000);
|
|
||||||
|
|
||||||
gpio_set(dev->params->wrx_pin);
|
|
||||||
|
|
||||||
if (gpio_is_valid(dev->params->cs_pin) && !cont) {
|
|
||||||
gpio_set(dev->params->cs_pin);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t lcd_ll_par_read_word(lcd_t *dev, bool cont)
|
static uint16_t lcd_ll_par_read_word(lcd_t *dev, bool cont)
|
||||||
{
|
{
|
||||||
uint16_t in = 0;
|
return lcd_ll_par_driver.read_word(dev, cont);
|
||||||
|
|
||||||
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) ? 0x0001 : 0;
|
|
||||||
in |= gpio_read(dev->params->d1_pin) ? 0x0002 : 0;
|
|
||||||
in |= gpio_read(dev->params->d2_pin) ? 0x0004 : 0;
|
|
||||||
in |= gpio_read(dev->params->d3_pin) ? 0x0008 : 0;
|
|
||||||
in |= gpio_read(dev->params->d4_pin) ? 0x0010 : 0;
|
|
||||||
in |= gpio_read(dev->params->d5_pin) ? 0x0020 : 0;
|
|
||||||
in |= gpio_read(dev->params->d6_pin) ? 0x0040 : 0;
|
|
||||||
in |= gpio_read(dev->params->d7_pin) ? 0x0080 : 0;
|
|
||||||
in |= gpio_read(dev->params->d8_pin) ? 0x01000 : 0;
|
|
||||||
in |= gpio_read(dev->params->d9_pin) ? 0x02000 : 0;
|
|
||||||
in |= gpio_read(dev->params->d10_pin) ? 0x0400 : 0;
|
|
||||||
in |= gpio_read(dev->params->d11_pin) ? 0x0800 : 0;
|
|
||||||
in |= gpio_read(dev->params->d12_pin) ? 0x1000 : 0;
|
|
||||||
in |= gpio_read(dev->params->d13_pin) ? 0x2000 : 0;
|
|
||||||
in |= gpio_read(dev->params->d14_pin) ? 0x4000 : 0;
|
|
||||||
in |= gpio_read(dev->params->d15_pin) ? 0x8000 : 0;
|
|
||||||
|
|
||||||
gpio_set(dev->params->rdx_pin);
|
|
||||||
|
|
||||||
if (gpio_is_valid(dev->params->cs_pin) && !cont) {
|
|
||||||
gpio_set(dev->params->cs_pin);
|
|
||||||
};
|
|
||||||
|
|
||||||
return in;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||||
|
|
||||||
static void lcd_ll_par_write_bytes(lcd_t *dev, bool cont,
|
static void lcd_ll_par_write_bytes(lcd_t *dev, bool cont,
|
||||||
@ -181,7 +84,7 @@ static void lcd_ll_par_write_bytes(lcd_t *dev, bool cont,
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
lcd_ll_par_write_byte(dev, i == (len - 1) ? cont : true, data_out[i]);
|
lcd_ll_par_write_byte(dev, i == (len - 1) ? cont : true, data_out[i]);
|
||||||
@ -206,7 +109,7 @@ static void lcd_ll_par_read_bytes(lcd_t *dev, bool cont,
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
data_in[i] = lcd_ll_par_read_byte(dev, i == (len - 1) ? cont : true);
|
data_in[i] = lcd_ll_par_read_byte(dev, i == (len - 1) ? cont : true);
|
||||||
@ -227,8 +130,6 @@ static inline void lcd_ll_write_byte(lcd_t *dev, bool cont, uint8_t data)
|
|||||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
lcd_ll_par_write_byte(dev, cont, data);
|
lcd_ll_par_write_byte(dev, cont, data);
|
||||||
#else
|
|
||||||
assert(false);
|
|
||||||
#endif
|
#endif
|
||||||
#if IS_USED(MODULE_LCD_SPI)
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
@ -249,8 +150,6 @@ static inline void lcd_ll_write_bytes(lcd_t *dev, bool cont,
|
|||||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
lcd_ll_par_write_bytes(dev, cont, data, len);
|
lcd_ll_par_write_bytes(dev, cont, data, len);
|
||||||
#else
|
|
||||||
assert(false);
|
|
||||||
#endif
|
#endif
|
||||||
#if IS_USED(MODULE_LCD_SPI)
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
@ -270,59 +169,19 @@ static inline void lcd_ll_read_bytes(lcd_t *dev, bool cont,
|
|||||||
dev->params->cs_pin, cont, NULL, data, len);
|
dev->params->cs_pin, cont, NULL, data, len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#endif
|
#endif /* IS_USED(MODULE_LCD_SPI) */
|
||||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
|
|
||||||
/* switch GPIO mode to input */
|
/* switch GPIO mode to input */
|
||||||
gpio_init(dev->params->d0_pin, GPIO_IN);
|
lcd_ll_par_driver.set_data_dir(dev, false);
|
||||||
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);
|
|
||||||
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
|
||||||
if (dev->params->mode == LCD_IF_PARALLEL_16BIT) {
|
|
||||||
gpio_init(dev->params->d8_pin, GPIO_IN);
|
|
||||||
gpio_init(dev->params->d9_pin, GPIO_IN);
|
|
||||||
gpio_init(dev->params->d10_pin, GPIO_IN);
|
|
||||||
gpio_init(dev->params->d11_pin, GPIO_IN);
|
|
||||||
gpio_init(dev->params->d12_pin, GPIO_IN);
|
|
||||||
gpio_init(dev->params->d13_pin, GPIO_IN);
|
|
||||||
gpio_init(dev->params->d14_pin, GPIO_IN);
|
|
||||||
gpio_init(dev->params->d15_pin, GPIO_IN);
|
|
||||||
}
|
|
||||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
|
||||||
|
|
||||||
/* Dummy read */
|
/* Dummy read */
|
||||||
lcd_ll_par_read_byte(dev, true);
|
lcd_ll_par_read_byte(dev, true);
|
||||||
lcd_ll_par_read_bytes(dev, cont, data, len);
|
lcd_ll_par_read_bytes(dev, cont, data, len);
|
||||||
|
|
||||||
/* switch GPIO mode back to output */
|
/* switch GPIO mode back to output */
|
||||||
gpio_init(dev->params->d0_pin, GPIO_OUT);
|
lcd_ll_par_driver.set_data_dir(dev, true);
|
||||||
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);
|
|
||||||
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
|
||||||
if (dev->params->mode == LCD_IF_PARALLEL_16BIT) {
|
|
||||||
gpio_init(dev->params->d8_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d9_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d10_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d11_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d12_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d13_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d14_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d15_pin, GPIO_OUT);
|
|
||||||
}
|
|
||||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
|
||||||
#else
|
|
||||||
assert(false);
|
|
||||||
#endif
|
#endif
|
||||||
#if IS_USED(MODULE_LCD_SPI)
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
@ -331,9 +190,18 @@ static inline void lcd_ll_read_bytes(lcd_t *dev, bool cont,
|
|||||||
|
|
||||||
static void lcd_ll_cmd_start(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);
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
lcd_ll_write_byte(dev, cont, cmd);
|
if (dev->params->mode != LCD_IF_SPI) {
|
||||||
gpio_set(dev->params->dcx_pin);
|
lcd_ll_par_driver.cmd_start(dev, cmd, cont);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#endif
|
||||||
|
gpio_clear(dev->params->dcx_pin);
|
||||||
|
lcd_ll_write_byte(dev, cont, cmd);
|
||||||
|
gpio_set(dev->params->dcx_pin);
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||||
/* only the RAMRD and RAMRDC commands use 16-bit data access */
|
/* only the RAMRD and RAMRDC commands use 16-bit data access */
|
||||||
@ -369,8 +237,7 @@ static void lcd_ll_set_area_default(lcd_t *dev, uint16_t x1, uint16_t x2,
|
|||||||
sizeof(params));
|
sizeof(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lcd_ll_set_area(lcd_t *dev, uint16_t x1, uint16_t x2,
|
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);
|
||||||
@ -393,8 +260,6 @@ void lcd_ll_acquire(lcd_t *dev)
|
|||||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
mutex_lock(&dev->lock);
|
mutex_lock(&dev->lock);
|
||||||
#else
|
|
||||||
assert(false);
|
|
||||||
#endif
|
#endif
|
||||||
#if IS_USED(MODULE_LCD_SPI)
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
@ -418,8 +283,6 @@ void lcd_ll_release(lcd_t *dev)
|
|||||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
mutex_unlock(&dev->lock);
|
mutex_unlock(&dev->lock);
|
||||||
#else
|
|
||||||
assert(false);
|
|
||||||
#endif
|
#endif
|
||||||
#if IS_USED(MODULE_LCD_SPI)
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
@ -464,11 +327,11 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
|||||||
{
|
{
|
||||||
dev->params = 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 IS_USED(MODULE_LCD_SPI)
|
||||||
if (dev->params->spi != SPI_UNDEF) {
|
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 */
|
/* 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);
|
||||||
|
|
||||||
@ -478,63 +341,25 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#endif
|
#endif /* IS_USED(MODULE_LCD_SPI) */
|
||||||
|
|
||||||
#if IS_USED(MODULE_LCD_PARALLEL)
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
/* MCU 8080 8-/16-bit parallel interface is used */
|
mutex_init(&dev->lock);
|
||||||
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->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);
|
|
||||||
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||||
if (dev->params->mode == LCD_IF_PARALLEL_16BIT) {
|
|
||||||
assert(gpio_is_valid(dev->params->d8_pin));
|
|
||||||
assert(gpio_is_valid(dev->params->d9_pin));
|
|
||||||
assert(gpio_is_valid(dev->params->d10_pin));
|
|
||||||
assert(gpio_is_valid(dev->params->d11_pin));
|
|
||||||
assert(gpio_is_valid(dev->params->d12_pin));
|
|
||||||
assert(gpio_is_valid(dev->params->d13_pin));
|
|
||||||
assert(gpio_is_valid(dev->params->d14_pin));
|
|
||||||
assert(gpio_is_valid(dev->params->d15_pin));
|
|
||||||
gpio_init(dev->params->d8_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d9_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d10_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d11_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d12_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d13_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d14_pin, GPIO_OUT);
|
|
||||||
gpio_init(dev->params->d15_pin, GPIO_OUT);
|
|
||||||
}
|
|
||||||
dev->word_access = false;
|
dev->word_access = false;
|
||||||
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||||
#else
|
|
||||||
|
/* 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);
|
assert(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IS_USED(MODULE_LCD_SPI)
|
#if IS_USED(MODULE_LCD_SPI)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -547,10 +372,6 @@ 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);
|
||||||
|
262
drivers/lcd/lcd_ll_par_gpio.c
Normal file
262
drivers/lcd/lcd_ll_par_gpio.c
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 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
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup drivers_lcd
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief GPIO-driven low-level parallel interface implementation
|
||||||
|
*
|
||||||
|
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "lcd.h"
|
||||||
|
#include "lcd_ll_par_gpio.h"
|
||||||
|
#include "periph/gpio.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG 0
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL)
|
||||||
|
|
||||||
|
void lcd_ll_par_gpio_init(lcd_t *dev)
|
||||||
|
{
|
||||||
|
DEBUG("[lcd] %s\n", __func__);
|
||||||
|
|
||||||
|
/* MCU 8080 8-/16-bit parallel interface is used */
|
||||||
|
assert(gpio_is_valid(dev->params->dcx_pin));
|
||||||
|
gpio_init(dev->params->dcx_pin, GPIO_OUT);
|
||||||
|
|
||||||
|
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->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));
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||||
|
if (dev->params->mode == LCD_IF_PARALLEL_16BIT) {
|
||||||
|
assert(gpio_is_valid(dev->params->d8_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d9_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d10_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d11_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d12_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d13_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d14_pin));
|
||||||
|
assert(gpio_is_valid(dev->params->d15_pin));
|
||||||
|
}
|
||||||
|
dev->word_access = false;
|
||||||
|
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||||
|
|
||||||
|
/* initialize all data GPIOs as outputs */
|
||||||
|
lcd_ll_par_gpio_set_data_dir(dev, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_ll_par_gpio_set_data_dir(lcd_t *dev, bool output)
|
||||||
|
{
|
||||||
|
DEBUG("[lcd] %s %u\n", __func__, output);
|
||||||
|
|
||||||
|
gpio_init(dev->params->d0_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d1_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d2_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d3_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d4_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d5_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d6_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d7_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||||
|
if (dev->params->mode == LCD_IF_PARALLEL_16BIT) {
|
||||||
|
gpio_init(dev->params->d8_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d9_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d10_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d11_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d12_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d13_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d14_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
gpio_init(dev->params->d15_pin, output ? GPIO_OUT : GPIO_IN);
|
||||||
|
}
|
||||||
|
#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_ll_par_gpio_cmd_start(lcd_t *dev, uint8_t cmd, bool cont)
|
||||||
|
{
|
||||||
|
DEBUG("[lcd] %s %02x\n", __func__, cmd);
|
||||||
|
|
||||||
|
gpio_clear(dev->params->dcx_pin);
|
||||||
|
lcd_ll_par_gpio_write_byte(dev, cont, cmd);
|
||||||
|
gpio_set(dev->params->dcx_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_ll_par_gpio_write_byte(lcd_t *dev, bool cont, uint8_t out)
|
||||||
|
{
|
||||||
|
DEBUG("[lcd] %s %02x\n", __func__, 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);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t lcd_ll_par_gpio_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);
|
||||||
|
};
|
||||||
|
|
||||||
|
DEBUG("[lcd] %s %02x\n", __func__, in);
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_LCD_PARALLEL_16BIT)
|
||||||
|
|
||||||
|
void lcd_ll_par_gpio_write_word(lcd_t *dev, bool cont, uint16_t out)
|
||||||
|
{
|
||||||
|
DEBUG("[lcd] %s %04x\n", __func__, 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 & 0x0001);
|
||||||
|
gpio_write(dev->params->d1_pin, out & 0x0002);
|
||||||
|
gpio_write(dev->params->d2_pin, out & 0x0004);
|
||||||
|
gpio_write(dev->params->d3_pin, out & 0x0008);
|
||||||
|
gpio_write(dev->params->d4_pin, out & 0x0010);
|
||||||
|
gpio_write(dev->params->d5_pin, out & 0x0020);
|
||||||
|
gpio_write(dev->params->d6_pin, out & 0x0040);
|
||||||
|
gpio_write(dev->params->d7_pin, out & 0x0080);
|
||||||
|
gpio_write(dev->params->d8_pin, out & 0x0100);
|
||||||
|
gpio_write(dev->params->d9_pin, out & 0x0200);
|
||||||
|
gpio_write(dev->params->d10_pin, out & 0x0400);
|
||||||
|
gpio_write(dev->params->d11_pin, out & 0x0800);
|
||||||
|
gpio_write(dev->params->d12_pin, out & 0x1000);
|
||||||
|
gpio_write(dev->params->d13_pin, out & 0x2000);
|
||||||
|
gpio_write(dev->params->d14_pin, out & 0x4000);
|
||||||
|
gpio_write(dev->params->d15_pin, out & 0x8000);
|
||||||
|
|
||||||
|
gpio_set(dev->params->wrx_pin);
|
||||||
|
|
||||||
|
if (gpio_is_valid(dev->params->cs_pin) && !cont) {
|
||||||
|
gpio_set(dev->params->cs_pin);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t lcd_ll_par_gpio_read_word(lcd_t *dev, bool cont)
|
||||||
|
{
|
||||||
|
uint16_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) ? 0x0001 : 0;
|
||||||
|
in |= gpio_read(dev->params->d1_pin) ? 0x0002 : 0;
|
||||||
|
in |= gpio_read(dev->params->d2_pin) ? 0x0004 : 0;
|
||||||
|
in |= gpio_read(dev->params->d3_pin) ? 0x0008 : 0;
|
||||||
|
in |= gpio_read(dev->params->d4_pin) ? 0x0010 : 0;
|
||||||
|
in |= gpio_read(dev->params->d5_pin) ? 0x0020 : 0;
|
||||||
|
in |= gpio_read(dev->params->d6_pin) ? 0x0040 : 0;
|
||||||
|
in |= gpio_read(dev->params->d7_pin) ? 0x0080 : 0;
|
||||||
|
in |= gpio_read(dev->params->d8_pin) ? 0x01000 : 0;
|
||||||
|
in |= gpio_read(dev->params->d9_pin) ? 0x02000 : 0;
|
||||||
|
in |= gpio_read(dev->params->d10_pin) ? 0x0400 : 0;
|
||||||
|
in |= gpio_read(dev->params->d11_pin) ? 0x0800 : 0;
|
||||||
|
in |= gpio_read(dev->params->d12_pin) ? 0x1000 : 0;
|
||||||
|
in |= gpio_read(dev->params->d13_pin) ? 0x2000 : 0;
|
||||||
|
in |= gpio_read(dev->params->d14_pin) ? 0x4000 : 0;
|
||||||
|
in |= gpio_read(dev->params->d15_pin) ? 0x8000 : 0;
|
||||||
|
|
||||||
|
gpio_set(dev->params->rdx_pin);
|
||||||
|
|
||||||
|
if (gpio_is_valid(dev->params->cs_pin) && !cont) {
|
||||||
|
gpio_set(dev->params->cs_pin);
|
||||||
|
};
|
||||||
|
|
||||||
|
DEBUG("[lcd] %s %04x\n", __func__, in);
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
#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) */
|
@ -142,6 +142,7 @@ static inline uint8_t _st7735_calc_vghl(uint16_t vgh, int16_t vgl, uint16_t avdd
|
|||||||
|
|
||||||
int st7735_init(lcd_t *dev, const lcd_params_t *params)
|
int st7735_init(lcd_t *dev, const lcd_params_t *params)
|
||||||
{
|
{
|
||||||
|
(void)params;
|
||||||
assert(params->lines <= 162);
|
assert(params->lines <= 162);
|
||||||
assert(params->rgb_channels <= 132);
|
assert(params->rgb_channels <= 132);
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ static inline uint8_t _st7789_calc_vrh(int16_t vrh)
|
|||||||
|
|
||||||
int st7789_init(lcd_t *dev, const lcd_params_t *params)
|
int st7789_init(lcd_t *dev, const lcd_params_t *params)
|
||||||
{
|
{
|
||||||
|
(void)params;
|
||||||
assert(params->lines <= 320);
|
assert(params->lines <= 320);
|
||||||
assert(params->rgb_channels <= 240);
|
assert(params->rgb_channels <= 240);
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ static inline uint8_t _st7796_calc_vrh(int16_t vrh)
|
|||||||
|
|
||||||
int st7796_init(lcd_t *dev, const lcd_params_t *params)
|
int st7796_init(lcd_t *dev, const lcd_params_t *params)
|
||||||
{
|
{
|
||||||
|
(void)params;
|
||||||
assert(params->lines <= 480);
|
assert(params->lines <= 480);
|
||||||
assert(params->rgb_channels <= 320);
|
assert(params->rgb_channels <= 320);
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "ztimer.h"
|
#include "ztimer.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
|
#include "lcd_internal.h"
|
||||||
|
|
||||||
#include "riot_logo.h"
|
#include "riot_logo.h"
|
||||||
|
|
||||||
@ -54,6 +55,18 @@ int main(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MODULE_LCD_PARALLEL
|
||||||
|
if (gpio_is_valid(st77xx_params[0].rdx_pin)) {
|
||||||
|
uint8_t data[4];
|
||||||
|
|
||||||
|
lcd_read_cmd(&dev, LCD_CMD_RDDIDIF, data, 3);
|
||||||
|
printf("lcd ID: %02x %02x %02x\n", data[0], data[1], data[2]);
|
||||||
|
|
||||||
|
lcd_read_cmd(&dev, LCD_CMD_RDDST, data, 4);
|
||||||
|
printf("lcd status: %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
puts("lcd TFT display filling map");
|
puts("lcd TFT display filling map");
|
||||||
lcd_fill(&dev, 0, dev.params->lines, 0, dev.params->rgb_channels, 0x0000);
|
lcd_fill(&dev, 0, dev.params->lines, 0, dev.params->rgb_channels, 0x0000);
|
||||||
puts("lcd TFT display map filled");
|
puts("lcd TFT display map filled");
|
||||||
|
Loading…
Reference in New Issue
Block a user