1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/lcd/lcd_ll_par_gpio.c

263 lines
8.5 KiB
C

/*
* 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) */