mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/lcd: add common driver for lcd display
This commit is contained in:
parent
e3f9252947
commit
8f2fa772e9
@ -32,6 +32,7 @@ rsource "disp_dev/Kconfig"
|
||||
rsource "dsp0401/Kconfig"
|
||||
rsource "hd44780/Kconfig"
|
||||
rsource "ili9341/Kconfig"
|
||||
rsource "lcd/Kconfig"
|
||||
rsource "touch_dev/Kconfig"
|
||||
endmenu # Display Device Drivers
|
||||
|
||||
|
210
drivers/include/lcd.h
Normal file
210
drivers/include/lcd.h
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Koen Zandberg
|
||||
* 2021 Francisco Molina
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_lcd LCD display driver
|
||||
* @ingroup drivers_display
|
||||
*
|
||||
* @brief Driver for the LCD display
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author Koen Zandberg <koen@bergzand.net>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*
|
||||
* The LCD is a generic display driver for small RGB displays. The driver
|
||||
* implemented here operates over SPI to communicate with the device.
|
||||
*
|
||||
* 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
|
||||
* when strictly necessary. This option will slow down the driver as it
|
||||
* certainly can't use DMA anymore, every short has to be converted before
|
||||
* transfer.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LCD_H
|
||||
#define LCD_H
|
||||
|
||||
#include "board.h"
|
||||
#include "periph/spi.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#ifdef MODULE_DISP_DEV
|
||||
#include "disp_dev.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Convert little endian colors to big endian.
|
||||
*
|
||||
* Compile time switch to change the driver to convert little endian
|
||||
* colors to big endian.
|
||||
*/
|
||||
#ifdef DOXYGEN
|
||||
#define CONFIG_LCD_LE_MODE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device initialization parameters
|
||||
*/
|
||||
typedef struct {
|
||||
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 */
|
||||
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 */
|
||||
bool inverted; /**< Display works in inverted color mode */
|
||||
uint16_t lines; /**< Number of lines, from 16 to 320 in 8 line steps */
|
||||
uint16_t rgb_channels; /**< Display rgb channels */
|
||||
} lcd_params_t;
|
||||
|
||||
/**
|
||||
* @brief LCD driver interface
|
||||
*
|
||||
* This define the functions to access a LCD.
|
||||
*/
|
||||
typedef struct lcd_driver lcd_driver_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for a lcd
|
||||
*/
|
||||
typedef struct {
|
||||
#ifdef MODULE_DISP_DEV
|
||||
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 */
|
||||
} lcd_t;
|
||||
|
||||
/**
|
||||
* @brief LCD driver interface
|
||||
*
|
||||
* This define the functions to access a LCD.
|
||||
*
|
||||
*/
|
||||
struct lcd_driver {
|
||||
/**
|
||||
* @brief Initialize LCD controller
|
||||
*
|
||||
* @param[in] dev Pointer to the selected driver
|
||||
*
|
||||
* @returns 0 on success
|
||||
* @returns < 0 value in error
|
||||
*/
|
||||
int (*init)(lcd_t *dev, const lcd_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Set area 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 (*set_area)(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
||||
uint16_t y2);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Setup an lcd display device
|
||||
*
|
||||
* @param[out] dev device descriptor
|
||||
* @param[in] params parameters for device initialization
|
||||
*/
|
||||
int lcd_init(lcd_t *dev, const lcd_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Fill a rectangular area with a single pixel color
|
||||
*
|
||||
* the rectangular area is defined as x1 being the first column of pixels and
|
||||
* x2 being the last column of pixels to fill. similar to that, y1 is the first
|
||||
* row to fill and y2 is the last row to fill.
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @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
|
||||
* @param[in] color single color to fill the area with
|
||||
*/
|
||||
void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||
uint16_t y1, uint16_t y2, uint16_t color);
|
||||
|
||||
/**
|
||||
* @brief Fill a rectangular area with an array of pixels
|
||||
*
|
||||
* the rectangular area is defined as x1 being the first column of pixels and
|
||||
* x2 being the last column of pixels to fill. similar to that, y1 is the first
|
||||
* row to fill and y2 is the last row to fill.
|
||||
*
|
||||
* @note @p color must have a length equal to `(x2 - x1 + 1) * (y2 - y1 + 1)`
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @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
|
||||
* @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,
|
||||
uint16_t y2, const uint16_t *color);
|
||||
|
||||
/**
|
||||
* @brief Raw write command
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
void lcd_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* @brief Raw read command
|
||||
*
|
||||
* @pre len > 0
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] cmd command
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Invert the display colors
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*/
|
||||
void lcd_invert_on(const lcd_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Disable color inversion
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*/
|
||||
void lcd_invert_off(const lcd_t *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* LCD_H */
|
||||
/** @} */
|
32
drivers/lcd/Kconfig
Normal file
32
drivers/lcd/Kconfig
Normal file
@ -0,0 +1,32 @@
|
||||
# Copyright (c) 2020 HAW Hamburg
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
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
|
||||
|
||||
menuconfig KCONFIG_USEMODULE_LCD
|
||||
bool "Configure LCD driver"
|
||||
depends on USEMODULE_LCD
|
||||
help
|
||||
Configure the LCD display driver using Kconfig.
|
||||
|
||||
if KCONFIG_USEMODULE_LCD
|
||||
|
||||
config LCD_LE_MODE
|
||||
bool "Enable little endian to big endian conversion"
|
||||
help
|
||||
Enable this configuration to convert little endian colors to big endian.
|
||||
LCD device requires colors to be send in big endian RGB-565 format.
|
||||
Enabling this option allows for little endian colors. Enabling this
|
||||
however will slow down the driver as it cannot use DMA anymore.
|
||||
|
||||
endif # KCONFIG_USEMODULE_LCD
|
1
drivers/lcd/Makefile
Normal file
1
drivers/lcd/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
2
drivers/lcd/Makefile.dep
Normal file
2
drivers/lcd/Makefile.dep
Normal file
@ -0,0 +1,2 @@
|
||||
FEATURES_REQUIRED += periph_spi
|
||||
FEATURES_REQUIRED += periph_gpio
|
2
drivers/lcd/Makefile.include
Normal file
2
drivers/lcd/Makefile.include
Normal file
@ -0,0 +1,2 @@
|
||||
USEMODULE_INCLUDES_lcd := $(LAST_MAKEFILEDIR)/include
|
||||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_lcd)
|
38
drivers/lcd/include/lcd_disp_dev.h
Normal file
38
drivers/lcd/include/lcd_disp_dev.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Inria
|
||||
*
|
||||
* 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 Definition of the driver for the disp_dev generic interface
|
||||
*
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef LCD_DISP_DEV_H
|
||||
#define LCD_DISP_DEV_H
|
||||
|
||||
#include "disp_dev.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Reference to the display device driver struct
|
||||
*/
|
||||
extern const disp_dev_driver_t lcd_disp_dev_driver;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LCD_DISP_DEV_H */
|
||||
/** @} */
|
102
drivers/lcd/include/lcd_internal.h
Normal file
102
drivers/lcd/include/lcd_internal.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Koen Zandberg
|
||||
* 2021 Francisco Molina
|
||||
*
|
||||
* 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 Device driver implementation for the lcd display controller
|
||||
*
|
||||
* @author Koen Zandberg <koen@bergzand.net>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef LCD_INTERNAL_H
|
||||
#define LCD_INTERNAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name LCD commands
|
||||
*
|
||||
* Not exhaustive, please extend when required
|
||||
* @{
|
||||
*/
|
||||
#define LCD_CMD_SWRESET 0x01 /**< Software reset */
|
||||
#define LCD_CMD_RDDIDIF 0x04 /**< Read display ID */
|
||||
#define LCD_CMD_SPLIN 0x10 /**< Enter sleep mode */
|
||||
#define LCD_CMD_SLPOUT 0x11 /**< Sleep out */
|
||||
#define LCD_CMD_NORON 0x11 /**< Normal display mode on */
|
||||
#define LCD_CMD_DINVOFF 0x20 /**< Display inversion off */
|
||||
#define LCD_CMD_DINVON 0x21 /**< Display inversion on */
|
||||
|
||||
#define LCD_CMD_GAMSET 0x26 /**< Gamma Set */
|
||||
#define LCD_CMD_DISPOFF 0x28 /**< Display OFF */
|
||||
#define LCD_CMD_DISPON 0x29 /**< Display ON */
|
||||
#define LCD_CMD_CASET 0x2A /**< Column Address Set */
|
||||
#define LCD_CMD_PASET 0x2b /**< Page Address Set */
|
||||
#define LCD_CMD_RAMWR 0x2c /**< Memory Write */
|
||||
#define LCD_CMD_RAMRD 0x2e /**< Memory Read */
|
||||
#define LCD_CMD_MADCTL 0x36 /**< Memory data access control */
|
||||
#define LCD_CMD_IDMOFF 0x38 /**< Idle Mode OFF */
|
||||
#define LCD_CMD_IDMON 0x39 /**< Idle Mode ON */
|
||||
#define LCD_CMD_PIXSET 0x3A /**< COLMOD: Pixel Format Set */
|
||||
#define LCD_CMD_WRDISBV 0x51 /**< Write Display Brightness */
|
||||
#define LCD_CMD_WRCTRLD 0x53 /**< Write Control Display */
|
||||
#define LCD_CMD_RDCTRLD 0x54 /**< Read Control Display */
|
||||
#define LCD_CMD_FRAMECTL1 0xb1 /**< Frame control normal*/
|
||||
#define LCD_CMD_FRAMECTL2 0xb2 /**< Frame control idle */
|
||||
#define LCD_CMD_FRAMECTL3 0xb3 /**< Frame control partial */
|
||||
#define LCD_CMD_DFUNC 0xb6 /**< Display function control */
|
||||
#define LCD_CMD_PWCTRL1 0xc0 /**< Power control 1 */
|
||||
#define LCD_CMD_PWCTRL2 0xc1 /**< Power control 2 */
|
||||
#define LCD_CMD_VMCTRL1 0xc5 /**< VCOM control 1 */
|
||||
#define LCD_CMD_VMCTRL2 0xc7 /**< VCOM control 2 */
|
||||
#define LCD_CMD_PGAMCTRL 0xe0 /**< Positive gamma correction */
|
||||
#define LCD_CMD_NGAMCTRL 0xe1 /**< Negative gamma correction */
|
||||
#define LCD_CMD_IFCTL 0xf6 /**< Interface control */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Memory access control bits
|
||||
* @{
|
||||
*/
|
||||
#define LCD_MADCTL_MY 0x80 /**< Row address order */
|
||||
#define LCD_MADCTL_MX 0x40 /**< Column access order */
|
||||
#define LCD_MADCTL_MV 0x20 /**< Row column exchange */
|
||||
#define LCD_MADCTL_ML 0x10 /**< Vertical refresh order */
|
||||
#define LCD_MADCTL_BGR 0x08 /**< Color selector switch control */
|
||||
#define LCD_MADCTL_MH 0x04 /**< Horizontal refresh direction */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Display rotation modes
|
||||
* @{
|
||||
*/
|
||||
#define LCD_MADCTL_VERT LCD_MADCTL_MX /**< Vertical mode */
|
||||
#define LCD_MADCTL_VERT_FLIP LCD_MADCTL_MY /**< Flipped vertical */
|
||||
#define LCD_MADCTL_HORZ LCD_MADCTL_MV /**< Horizontal mode */
|
||||
#define LCD_MADCTL_HORZ_FLIP LCD_MADCTL_MV | \
|
||||
LCD_MADCTL_MY | \
|
||||
LCD_MADCTL_MX /**< Horizontal flipped */
|
||||
/** @} */
|
||||
|
||||
#define LCD_PIXSET_16BIT 0x55 /**< MCU and RGB 16 bit interface */
|
||||
#define LCD_PIXSET_18BIT 0x66 /**< MCU and RGB 18 bit interface (not implemented) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LCD_INTERNAL_H */
|
184
drivers/lcd/lcd.c
Normal file
184
drivers/lcd/lcd.c
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Koen Zandberg
|
||||
* 2021 Francisco Molina
|
||||
*
|
||||
* 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 Device driver implementation for the lcd display controller
|
||||
*
|
||||
* @author Koen Zandberg <koen@bergzand.net>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "byteorder.h"
|
||||
#include "periph/spi.h"
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#include "lcd.h"
|
||||
#include "lcd_internal.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
static void _lcd_spi_acquire(const lcd_t *dev)
|
||||
{
|
||||
spi_acquire(dev->params->spi, dev->params->cs_pin, dev->params->spi_mode,
|
||||
dev->params->spi_clk);
|
||||
}
|
||||
|
||||
static void _lcd_cmd_start(const lcd_t *dev, uint8_t cmd, bool cont)
|
||||
{
|
||||
gpio_clear(dev->params->dcx_pin);
|
||||
spi_transfer_byte(dev->params->spi, dev->params->cs_pin, cont, cmd);
|
||||
gpio_set(dev->params->dcx_pin);
|
||||
}
|
||||
|
||||
static void _write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||
size_t len)
|
||||
{
|
||||
_lcd_cmd_start(dev, cmd, len ? true : false);
|
||||
if (len) {
|
||||
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, data,
|
||||
NULL, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void _lcd_set_area(const lcd_t *dev, uint16_t x1, uint16_t x2,
|
||||
uint16_t y1, uint16_t y2)
|
||||
{
|
||||
assert(dev->driver->set_area);
|
||||
dev->driver->set_area(dev, x1, x2, y1, y2);
|
||||
}
|
||||
|
||||
int lcd_init(lcd_t *dev, const lcd_params_t *params)
|
||||
{
|
||||
if (dev->driver->init) {
|
||||
return dev->driver->init(dev, params);
|
||||
}
|
||||
else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_write_cmd(const lcd_t *dev, uint8_t cmd, const uint8_t *data,
|
||||
size_t len)
|
||||
{
|
||||
_lcd_spi_acquire(dev);
|
||||
_write_cmd(dev, cmd, data, len);
|
||||
spi_release(dev->params->spi);
|
||||
}
|
||||
|
||||
void lcd_read_cmd(const lcd_t *dev, uint8_t cmd, uint8_t *data, size_t len)
|
||||
{
|
||||
assert(len);
|
||||
_lcd_spi_acquire(dev);
|
||||
_lcd_cmd_start(dev, cmd, true);
|
||||
/* Dummy transfer */
|
||||
spi_transfer_byte(dev->params->spi, dev->params->cs_pin, true, 0x00);
|
||||
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, NULL,
|
||||
data, len);
|
||||
spi_release(dev->params->spi);
|
||||
}
|
||||
|
||||
|
||||
void lcd_fill(const lcd_t *dev, uint16_t x1, uint16_t x2, uint16_t y1,
|
||||
uint16_t y2, uint16_t color)
|
||||
{
|
||||
/* Send fill area to the display */
|
||||
|
||||
/* Calculate number of pixels */
|
||||
int32_t num_pix = (x2 - x1 + 1) * (y2 - y1 + 1);
|
||||
|
||||
DEBUG("[lcd]: Write x1: %" PRIu16 ", x2: %" PRIu16 ", "
|
||||
"y1: %" PRIu16 ", y2: %" PRIu16 ". Num pixels: %lu\n",
|
||||
x1, x2, y1, y2, (unsigned long)num_pix);
|
||||
|
||||
/* Send fill area to the display */
|
||||
_lcd_spi_acquire(dev);
|
||||
|
||||
_lcd_set_area(dev, x1, x2, y1, y2);
|
||||
/* Memory access command */
|
||||
_lcd_cmd_start(dev, LCD_CMD_RAMWR, true);
|
||||
|
||||
if (IS_ACTIVE(CONFIG_LCD_LE_MODE)) {
|
||||
color = htons(color);
|
||||
}
|
||||
|
||||
for (int i = 0; i < (num_pix - 1); i++) {
|
||||
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, true,
|
||||
(uint8_t *)&color, NULL, sizeof(color));
|
||||
}
|
||||
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false,
|
||||
(uint8_t *)&color, NULL, sizeof(color));
|
||||
spi_release(dev->params->spi);
|
||||
}
|
||||
|
||||
void lcd_pixmap(const 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);
|
||||
|
||||
DEBUG("[lcd]: Write x1: %" PRIu16 ", x2: %" PRIu16 ", "
|
||||
"y1: %" PRIu16 ", y2: %" PRIu16 ". Num pixels: %lu\n",
|
||||
x1, x2, y1, y2, (unsigned long)num_pix);
|
||||
|
||||
_lcd_spi_acquire(dev);
|
||||
|
||||
/* Send fill area to the display */
|
||||
_lcd_set_area(dev, x1, x2, y1, y2);
|
||||
|
||||
/* Memory access command */
|
||||
_lcd_cmd_start(dev, LCD_CMD_RAMWR, true);
|
||||
|
||||
if (IS_ACTIVE(CONFIG_LCD_LE_MODE)) {
|
||||
for (size_t i = 0; i < num_pix - 1; i++) {
|
||||
uint16_t ncolor = htons(*(color + i));
|
||||
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, true,
|
||||
&ncolor, NULL, sizeof(uint16_t));
|
||||
}
|
||||
uint16_t ncolor = htons(*(color + num_pix - 1));
|
||||
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false,
|
||||
&ncolor, NULL, sizeof(uint16_t));
|
||||
}
|
||||
else {
|
||||
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false,
|
||||
(const uint8_t *)color, NULL, num_pix * 2);
|
||||
}
|
||||
|
||||
spi_release(dev->params->spi);
|
||||
}
|
||||
|
||||
void lcd_invert_on(const lcd_t *dev)
|
||||
{
|
||||
uint8_t command = (dev->params->inverted) ? LCD_CMD_DINVOFF
|
||||
: LCD_CMD_DINVON;
|
||||
|
||||
lcd_write_cmd(dev, command, NULL, 0);
|
||||
}
|
||||
|
||||
void lcd_invert_off(const lcd_t *dev)
|
||||
{
|
||||
uint8_t command = (dev->params->inverted) ? LCD_CMD_DINVON
|
||||
: LCD_CMD_DINVOFF;
|
||||
|
||||
lcd_write_cmd(dev, command, NULL, 0);
|
||||
}
|
||||
|
||||
void lcd_set_brightness(const lcd_t *dev, uint8_t brightness)
|
||||
{
|
||||
lcd_write_cmd(dev, LCD_CMD_WRDISBV, &brightness, 1);
|
||||
uint8_t param = 0x26;
|
||||
lcd_write_cmd(dev, LCD_CMD_WRCTRLD, ¶m, 1);
|
||||
}
|
79
drivers/lcd/lcd_disp_dev.c
Normal file
79
drivers/lcd/lcd_disp_dev.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Inria
|
||||
*
|
||||
* 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 Driver adaption to disp_dev generic interface
|
||||
*
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lcd.h"
|
||||
#include "lcd_disp_dev.h"
|
||||
|
||||
#ifndef LCD_DISP_COLOR_DEPTH
|
||||
#define LCD_DISP_COLOR_DEPTH (16U)
|
||||
#endif
|
||||
|
||||
static void _lcd_map(const disp_dev_t *dev, uint16_t x1, uint16_t x2,
|
||||
uint16_t y1, uint16_t y2, const uint16_t *color)
|
||||
{
|
||||
lcd_t *lcd = (lcd_t *)dev;
|
||||
lcd_pixmap(lcd, x1, x2, y1, y2, color);
|
||||
}
|
||||
|
||||
static uint16_t _lcd_height(const disp_dev_t *disp_dev)
|
||||
{
|
||||
const lcd_t *dev = (lcd_t *)disp_dev;
|
||||
assert(dev);
|
||||
|
||||
return dev->params->rgb_channels;
|
||||
}
|
||||
|
||||
static uint16_t _lcd_width(const disp_dev_t *disp_dev)
|
||||
{
|
||||
const lcd_t *dev = (lcd_t *)disp_dev;
|
||||
assert(dev);
|
||||
|
||||
return dev->params->lines;
|
||||
}
|
||||
|
||||
static uint8_t _lcd_color_depth(const disp_dev_t *disp_dev)
|
||||
{
|
||||
(void)disp_dev;
|
||||
return LCD_DISP_COLOR_DEPTH;
|
||||
}
|
||||
|
||||
static void _lcd_set_invert(const disp_dev_t *disp_dev, bool invert)
|
||||
{
|
||||
const lcd_t *dev = (lcd_t *)disp_dev;
|
||||
|
||||
assert(dev);
|
||||
|
||||
if (invert) {
|
||||
lcd_invert_on(dev);
|
||||
}
|
||||
else {
|
||||
lcd_invert_off(dev);
|
||||
}
|
||||
}
|
||||
|
||||
const disp_dev_driver_t lcd_disp_dev_driver = {
|
||||
.map = _lcd_map,
|
||||
.height = _lcd_height,
|
||||
.width = _lcd_width,
|
||||
.color_depth = _lcd_color_depth,
|
||||
.set_invert = _lcd_set_invert,
|
||||
};
|
Loading…
Reference in New Issue
Block a user