diff --git a/drivers/lcd/include/lcd_ll_par_gpio.h b/drivers/lcd/include/lcd_ll_par_gpio.h new file mode 100644 index 0000000000..5cc64e52c6 --- /dev/null +++ b/drivers/lcd/include/lcd_ll_par_gpio.h @@ -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 + */ + +#ifndef LCD_LL_PAR_GPIO_H +#define LCD_LL_PAR_GPIO_H + +#include + +#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 */ diff --git a/drivers/lcd/lcd.c b/drivers/lcd/lcd.c index b715bf65af..aa7858e4f4 100644 --- a/drivers/lcd/lcd.c +++ b/drivers/lcd/lcd.c @@ -34,6 +34,7 @@ #include "lcd.h" #include "lcd_internal.h" +#include "lcd_ll_par_gpio.h" #define ENABLE_DEBUG 0 #include "debug.h" @@ -42,125 +43,26 @@ 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); - }; + lcd_ll_par_gpio_write_byte(dev, cont, out); } 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; + return lcd_ll_par_gpio_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) { - 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); - }; + lcd_ll_par_gpio_write_word(dev, cont, out); } static uint16_t lcd_ll_par_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); - }; - - return in; + return lcd_ll_par_gpio_read_word(dev, cont); } + #endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */ static void lcd_ll_par_write_bytes(lcd_t *dev, bool cont, @@ -275,52 +177,14 @@ static inline void lcd_ll_read_bytes(lcd_t *dev, bool cont, /* 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); -#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) */ + lcd_ll_par_gpio_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 */ - 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 (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) */ + lcd_ll_par_gpio_set_data_dir(dev, true); #else assert(false); #endif @@ -331,9 +195,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) { - 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) + if (dev->params->mode != LCD_IF_SPI) { + lcd_ll_par_gpio_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) /* only the RAMRD and RAMRDC commands use 16-bit data access */ @@ -479,58 +352,7 @@ int lcd_init(lcd_t *dev, const lcd_params_t *params) else { #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->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 (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; -#endif /* IS_USED(MODULE_LCD_PARALLEL_16BIT) */ + lcd_ll_par_gpio_init(dev); #else assert(false); #endif diff --git a/drivers/lcd/lcd_ll_par_gpio.c b/drivers/lcd/lcd_ll_par_gpio.c new file mode 100644 index 0000000000..3a246322bc --- /dev/null +++ b/drivers/lcd/lcd_ll_par_gpio.c @@ -0,0 +1,246 @@ +/* + * 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 + * + * @} + */ + +#include + +#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) */ + +#endif /* IS_USED(MODULE_LCD_PARALLEL) */