drivers: ssd1673: rename driver to ssd16xx
ssd1673 driver supports different controllers, rename it to more generic ssd16xx. Signed-off-by: Johann Fischer <j.fischer@phytec.de>
This commit is contained in:
parent
ab9a1c9f61
commit
fc57ea8d3c
27 changed files with 797 additions and 793 deletions
|
@ -117,9 +117,9 @@
|
||||||
miso-pin = <21>;
|
miso-pin = <21>;
|
||||||
cs-gpios = <&gpio0 17 0>;
|
cs-gpios = <&gpio0 17 0>;
|
||||||
|
|
||||||
ssd1673fb@0 {
|
ssd16xxfb@0 {
|
||||||
compatible = "solomon,ssd1673fb", "gd,gde0213b1";
|
compatible = "solomon,ssd16xxfb", "gd,gde0213b1";
|
||||||
label = "SSD1673";
|
label = "SSD16XX";
|
||||||
spi-max-frequency = <4000000>;
|
spi-max-frequency = <4000000>;
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
width = <250>;
|
width = <250>;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
zephyr_sources_ifdef(CONFIG_DISPLAY_MCUX_ELCDIF display_mcux_elcdif.c)
|
zephyr_sources_ifdef(CONFIG_DISPLAY_MCUX_ELCDIF display_mcux_elcdif.c)
|
||||||
zephyr_sources_ifdef(CONFIG_GROVE_LCD_RGB grove_lcd_rgb.c)
|
zephyr_sources_ifdef(CONFIG_GROVE_LCD_RGB grove_lcd_rgb.c)
|
||||||
zephyr_sources_ifdef(CONFIG_SSD1306 ssd1306.c)
|
zephyr_sources_ifdef(CONFIG_SSD1306 ssd1306.c)
|
||||||
zephyr_sources_ifdef(CONFIG_SSD1673 ssd1673.c)
|
zephyr_sources_ifdef(CONFIG_SSD16XX ssd16xx.c)
|
||||||
zephyr_sources_ifdef(CONFIG_SDL_DISPLAY display_sdl.c)
|
zephyr_sources_ifdef(CONFIG_SDL_DISPLAY display_sdl.c)
|
||||||
zephyr_sources_ifdef(CONFIG_DUMMY_DISPLAY display_dummy.c)
|
zephyr_sources_ifdef(CONFIG_DUMMY_DISPLAY display_dummy.c)
|
||||||
zephyr_sources_ifdef(CONFIG_FRAMEBUF_DISPLAY display_framebuf.c)
|
zephyr_sources_ifdef(CONFIG_FRAMEBUF_DISPLAY display_framebuf.c)
|
||||||
|
|
|
@ -23,7 +23,7 @@ source "drivers/display/Kconfig.microbit"
|
||||||
source "drivers/display/Kconfig.ili9340"
|
source "drivers/display/Kconfig.ili9340"
|
||||||
source "drivers/display/Kconfig.sdl"
|
source "drivers/display/Kconfig.sdl"
|
||||||
source "drivers/display/Kconfig.ssd1306"
|
source "drivers/display/Kconfig.ssd1306"
|
||||||
source "drivers/display/Kconfig.ssd1673"
|
source "drivers/display/Kconfig.ssd16xx"
|
||||||
source "drivers/display/Kconfig.dummy"
|
source "drivers/display/Kconfig.dummy"
|
||||||
|
|
||||||
config FRAMEBUF_DISPLAY
|
config FRAMEBUF_DISPLAY
|
||||||
|
|
|
@ -19,7 +19,7 @@ config SSD1306_DEFAULT_CONTRAST
|
||||||
default 128
|
default 128
|
||||||
range 0 255
|
range 0 255
|
||||||
help
|
help
|
||||||
SSD1673 default contrast.
|
SSD16XX default contrast.
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Display controller type"
|
prompt "Display controller type"
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
# Kconfig - SSD1673 display controller configuration options
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2018 Phytec Messtechnik GmbH
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
#
|
|
||||||
|
|
||||||
menuconfig SSD1673
|
|
||||||
bool "SSD1673 display driver"
|
|
||||||
depends on SPI
|
|
||||||
help
|
|
||||||
Enable driver for SSD1673 display driver.
|
|
||||||
|
|
||||||
if SSD1673
|
|
||||||
|
|
||||||
choice
|
|
||||||
prompt "EPD display"
|
|
||||||
default SSD1673_EPD_GDE0213B1
|
|
||||||
help
|
|
||||||
Specify the type of EPD connected to the SSD1673 controller.
|
|
||||||
|
|
||||||
config SSD1673_EPD_GDE0213B1
|
|
||||||
bool "GDE0213B1 2.13\""
|
|
||||||
|
|
||||||
endchoice
|
|
||||||
|
|
||||||
endif #SSD1673
|
|
28
drivers/display/Kconfig.ssd16xx
Normal file
28
drivers/display/Kconfig.ssd16xx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# Kconfig - SSD16XX display controller configuration options
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Phytec Messtechnik GmbH
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
menuconfig SSD16XX
|
||||||
|
bool "SSD16XX display driver"
|
||||||
|
depends on SPI
|
||||||
|
help
|
||||||
|
Enable driver for SSD16XX display driver.
|
||||||
|
|
||||||
|
if SSD16XX
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "EPD display"
|
||||||
|
default SSD16XX_EPD_GDE0213B1
|
||||||
|
help
|
||||||
|
Specify the type of EPD connected to the SSD16XX controller.
|
||||||
|
|
||||||
|
config SSD16XX_EPD_GDE0213B1
|
||||||
|
bool "GDE0213B1 2.13\""
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
endif #SSD16XX
|
|
@ -1,658 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 PHYTEC Messtechnik GmbH
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LOG_LEVEL CONFIG_DISPLAY_LOG_LEVEL
|
|
||||||
#include <logging/log.h>
|
|
||||||
LOG_MODULE_REGISTER(ssd1673);
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <device.h>
|
|
||||||
#include <drivers/display.h>
|
|
||||||
#include <init.h>
|
|
||||||
#include <drivers/gpio.h>
|
|
||||||
#include <drivers/spi.h>
|
|
||||||
#include <sys/byteorder.h>
|
|
||||||
|
|
||||||
#include "ssd1673_regs.h"
|
|
||||||
#include <display/cfb.h>
|
|
||||||
|
|
||||||
#define EPD_PANEL_WIDTH DT_INST_0_SOLOMON_SSD1673FB_WIDTH
|
|
||||||
#define EPD_PANEL_HEIGHT DT_INST_0_SOLOMON_SSD1673FB_HEIGHT
|
|
||||||
#define EPD_PANEL_NUMOF_COLUMS EPD_PANEL_WIDTH
|
|
||||||
#define EPD_PANEL_NUMOF_ROWS_PER_PAGE 8
|
|
||||||
#define EPD_PANEL_NUMOF_PAGES (EPD_PANEL_HEIGHT / \
|
|
||||||
EPD_PANEL_NUMOF_ROWS_PER_PAGE)
|
|
||||||
|
|
||||||
#define SSD1673_PANEL_FIRST_PAGE 0
|
|
||||||
#define SSD1673_PANEL_LAST_PAGE (EPD_PANEL_NUMOF_PAGES - 1)
|
|
||||||
#define SSD1673_PANEL_FIRST_GATE 0
|
|
||||||
#define SSD1673_PANEL_LAST_GATE (EPD_PANEL_NUMOF_COLUMS - 1)
|
|
||||||
|
|
||||||
#define SSD1673_PIXELS_PER_BYTE 8
|
|
||||||
|
|
||||||
struct ssd1673_data {
|
|
||||||
struct device *reset;
|
|
||||||
struct device *dc;
|
|
||||||
struct device *busy;
|
|
||||||
struct device *spi_dev;
|
|
||||||
struct spi_config spi_config;
|
|
||||||
#if defined(DT_INST_0_SOLOMON_SSD1673FB_CS_GPIOS_CONTROLLER)
|
|
||||||
struct spi_cs_control cs_ctrl;
|
|
||||||
#endif
|
|
||||||
u8_t scan_mode;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(DT_GD_GDE0213B1_0)
|
|
||||||
static u8_t ssd1673_lut_initial[] = {
|
|
||||||
0x22, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x11,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
|
|
||||||
0x01, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
static u8_t ssd1673_lut_default[] = {
|
|
||||||
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
#elif defined(DT_GD_GDE029A1_0)
|
|
||||||
static u8_t ssd1673_lut_initial[] = {
|
|
||||||
0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
static u8_t ssd1673_lut_default[] = {
|
|
||||||
0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
#elif defined(DT_HINK_E0154A05_0)
|
|
||||||
static u8_t ssd1673_lut_initial[] = {
|
|
||||||
0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22,
|
|
||||||
0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51,
|
|
||||||
0x35, 0x51, 0x51, 0x19, 0x01, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
static u8_t ssd1673_lut_default[] = {
|
|
||||||
0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
#error "No waveform look up table (LUT) selected!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int ssd1673_write_cmd(struct ssd1673_data *driver,
|
|
||||||
u8_t cmd, u8_t *data, size_t len)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
struct spi_buf buf = {.buf = &cmd, .len = sizeof(cmd)};
|
|
||||||
struct spi_buf_set buf_set = {.buffers = &buf, .count = 1};
|
|
||||||
|
|
||||||
gpio_pin_write(driver->dc, DT_INST_0_SOLOMON_SSD1673FB_DC_GPIOS_PIN, 0);
|
|
||||||
err = spi_write(driver->spi_dev, &driver->spi_config, &buf_set);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data != NULL) {
|
|
||||||
buf.buf = data;
|
|
||||||
buf.len = len;
|
|
||||||
gpio_pin_write(driver->dc, DT_INST_0_SOLOMON_SSD1673FB_DC_GPIOS_PIN, 1);
|
|
||||||
err = spi_write(driver->spi_dev, &driver->spi_config, &buf_set);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ssd1673_busy_wait(struct ssd1673_data *driver)
|
|
||||||
{
|
|
||||||
u32_t val = 0U;
|
|
||||||
|
|
||||||
gpio_pin_read(driver->busy, DT_INST_0_SOLOMON_SSD1673FB_BUSY_GPIOS_PIN, &val);
|
|
||||||
while (val) {
|
|
||||||
k_sleep(SSD1673_BUSY_DELAY);
|
|
||||||
gpio_pin_read(driver->busy, DT_INST_0_SOLOMON_SSD1673FB_BUSY_GPIOS_PIN, &val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline size_t push_x_param(u8_t *data, u16_t x)
|
|
||||||
{
|
|
||||||
#if DT_INST_0_SOLOMON_SSD1673FB_PP_WIDTH_BITS == 8
|
|
||||||
data[0] = (u8_t)x;
|
|
||||||
return 1;
|
|
||||||
#elif DT_INST_0_SOLOMON_SSD1673FB_PP_WIDTH_BITS == 16
|
|
||||||
sys_put_le16(sys_cpu_to_le16(x), data);
|
|
||||||
return 2;
|
|
||||||
#else
|
|
||||||
#error Unsupported DT_INST_0_SOLOMON_SSD1673FB_PP_WIDTH_BITS value
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline size_t push_y_param(u8_t *data, u16_t y)
|
|
||||||
{
|
|
||||||
#if DT_INST_0_SOLOMON_SSD1673FB_PP_HEIGHT_BITS == 8
|
|
||||||
data[0] = (u8_t)y;
|
|
||||||
return 1;
|
|
||||||
#elif DT_INST_0_SOLOMON_SSD1673FB_PP_HEIGHT_BITS == 16
|
|
||||||
sys_put_le16(sys_cpu_to_le16(y), data);
|
|
||||||
return 2;
|
|
||||||
#else
|
|
||||||
#error Unsupported DT_INST_0_SOLOMON_SSD1673FB_PP_HEIGHT_BITS value
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline int ssd1673_set_ram_param(struct ssd1673_data *driver,
|
|
||||||
u16_t sx, u16_t ex, u16_t sy, u16_t ey)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
u8_t tmp[4];
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = push_x_param(tmp, sx);
|
|
||||||
len += push_x_param(tmp + len, ex);
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_RAM_XPOS_CTRL, tmp, len);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = push_y_param(tmp, sy);
|
|
||||||
len += push_y_param(tmp + len, ey);
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_RAM_YPOS_CTRL, tmp, len);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ssd1673_set_ram_ptr(struct ssd1673_data *driver,
|
|
||||||
u16_t x, u16_t y)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
u8_t tmp[2];
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = push_x_param(tmp, x);
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_RAM_XPOS_CNTR, tmp, len);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = push_y_param(tmp, y);
|
|
||||||
return ssd1673_write_cmd(driver, SSD1673_CMD_RAM_YPOS_CNTR, tmp, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ssd1673_set_orientation_internall(struct ssd1673_data *driver)
|
|
||||||
|
|
||||||
{
|
|
||||||
#if DT_INST_0_SOLOMON_SSD1673FB_ORIENTATION_FLIPPED == 1
|
|
||||||
driver->scan_mode = SSD1673_DATA_ENTRY_XIYDY;
|
|
||||||
#else
|
|
||||||
driver->scan_mode = SSD1673_DATA_ENTRY_XDYIY;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int ssd1673_resume(const struct device *dev)
|
|
||||||
{
|
|
||||||
struct ssd1673_data *driver = dev->driver_data;
|
|
||||||
u8_t tmp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Uncomment for voltage measurement
|
|
||||||
* tmp = SSD1673_CTRL2_ENABLE_CLK;
|
|
||||||
* ssd1673_write_cmd(SSD1673_CMD_UPDATE_CTRL2, &tmp, sizeof(tmp));
|
|
||||||
* ssd1673_write_cmd(SSD1673_CMD_MASTER_ACTIVATION, NULL, 0);
|
|
||||||
*/
|
|
||||||
|
|
||||||
tmp = SSD1673_SLEEP_MODE_PON;
|
|
||||||
return ssd1673_write_cmd(driver, SSD1673_CMD_SLEEP_MODE,
|
|
||||||
&tmp, sizeof(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_suspend(const struct device *dev)
|
|
||||||
{
|
|
||||||
struct ssd1673_data *driver = dev->driver_data;
|
|
||||||
u8_t tmp = SSD1673_SLEEP_MODE_DSM;
|
|
||||||
|
|
||||||
return ssd1673_write_cmd(driver, SSD1673_CMD_SLEEP_MODE,
|
|
||||||
&tmp, sizeof(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_update_display(const struct device *dev)
|
|
||||||
{
|
|
||||||
struct ssd1673_data *driver = dev->driver_data;
|
|
||||||
u8_t tmp;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
tmp = SSD1673_CTRL1_INITIAL_UPDATE_LH;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_UPDATE_CTRL1,
|
|
||||||
&tmp, sizeof(tmp));
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = (SSD1673_CTRL2_ENABLE_CLK |
|
|
||||||
SSD1673_CTRL2_ENABLE_ANALOG |
|
|
||||||
SSD1673_CTRL2_TO_PATTERN |
|
|
||||||
SSD1673_CTRL2_DISABLE_ANALOG |
|
|
||||||
SSD1673_CTRL2_DISABLE_CLK);
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_UPDATE_CTRL2, &tmp,
|
|
||||||
sizeof(tmp));
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ssd1673_write_cmd(driver, SSD1673_CMD_MASTER_ACTIVATION,
|
|
||||||
NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_write(const struct device *dev, const u16_t x,
|
|
||||||
const u16_t y,
|
|
||||||
const struct display_buffer_descriptor *desc,
|
|
||||||
const void *buf)
|
|
||||||
{
|
|
||||||
struct ssd1673_data *driver = dev->driver_data;
|
|
||||||
int err;
|
|
||||||
u16_t x_start;
|
|
||||||
u16_t x_end;
|
|
||||||
u16_t y_start;
|
|
||||||
u16_t y_end;
|
|
||||||
|
|
||||||
if (desc->pitch < desc->width) {
|
|
||||||
LOG_ERR("Pitch is smaller than width");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf == NULL || desc->buf_size == 0U) {
|
|
||||||
LOG_ERR("Display buffer is not available");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc->pitch > desc->width) {
|
|
||||||
LOG_ERR("Unsupported mode");
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((y + desc->height) > EPD_PANEL_HEIGHT) {
|
|
||||||
LOG_ERR("Buffer out of bounds (height)");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x + desc->width) > EPD_PANEL_WIDTH) {
|
|
||||||
LOG_ERR("Buffer out of bounds (width)");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((desc->height % EPD_PANEL_NUMOF_ROWS_PER_PAGE) != 0U) {
|
|
||||||
LOG_ERR("Buffer height not multiple of %d",
|
|
||||||
EPD_PANEL_NUMOF_ROWS_PER_PAGE);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((y % EPD_PANEL_NUMOF_ROWS_PER_PAGE) != 0U) {
|
|
||||||
LOG_ERR("Y coordinate not multiple of %d",
|
|
||||||
EPD_PANEL_NUMOF_ROWS_PER_PAGE);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (driver->scan_mode) {
|
|
||||||
case SSD1673_DATA_ENTRY_XIYDY:
|
|
||||||
x_start = y / SSD1673_PIXELS_PER_BYTE;
|
|
||||||
x_end = (y + desc->height - 1) / SSD1673_PIXELS_PER_BYTE;
|
|
||||||
y_start = (x + desc->width - 1);
|
|
||||||
y_end = x;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SSD1673_DATA_ENTRY_XDYIY:
|
|
||||||
x_start = (EPD_PANEL_HEIGHT - 1 - y) / SSD1673_PIXELS_PER_BYTE;
|
|
||||||
x_end = (EPD_PANEL_HEIGHT - 1 - (y + desc->height - 1)) /
|
|
||||||
SSD1673_PIXELS_PER_BYTE;
|
|
||||||
y_start = x;
|
|
||||||
y_end = (x + desc->width - 1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssd1673_busy_wait(driver);
|
|
||||||
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_ENTRY_MODE,
|
|
||||||
&driver->scan_mode, sizeof(driver->scan_mode));
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ssd1673_set_ram_param(driver, x_start, x_end, y_start, y_end);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ssd1673_set_ram_ptr(driver, x_start, y_start);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_WRITE_RAM, (u8_t *)buf,
|
|
||||||
desc->buf_size);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ssd1673_update_display(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_read(const struct device *dev, const u16_t x,
|
|
||||||
const u16_t y,
|
|
||||||
const struct display_buffer_descriptor *desc,
|
|
||||||
void *buf)
|
|
||||||
{
|
|
||||||
LOG_ERR("not supported");
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *ssd1673_get_framebuffer(const struct device *dev)
|
|
||||||
{
|
|
||||||
LOG_ERR("not supported");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_set_brightness(const struct device *dev,
|
|
||||||
const u8_t brightness)
|
|
||||||
{
|
|
||||||
LOG_WRN("not supported");
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_set_contrast(const struct device *dev, u8_t contrast)
|
|
||||||
{
|
|
||||||
LOG_WRN("not supported");
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ssd1673_get_capabilities(const struct device *dev,
|
|
||||||
struct display_capabilities *caps)
|
|
||||||
{
|
|
||||||
memset(caps, 0, sizeof(struct display_capabilities));
|
|
||||||
caps->x_resolution = EPD_PANEL_WIDTH;
|
|
||||||
caps->y_resolution = EPD_PANEL_HEIGHT;
|
|
||||||
caps->supported_pixel_formats = PIXEL_FORMAT_MONO10;
|
|
||||||
caps->current_pixel_format = PIXEL_FORMAT_MONO10;
|
|
||||||
caps->screen_info = SCREEN_INFO_MONO_VTILED |
|
|
||||||
SCREEN_INFO_MONO_MSB_FIRST |
|
|
||||||
SCREEN_INFO_EPD |
|
|
||||||
SCREEN_INFO_DOUBLE_BUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_set_orientation(const struct device *dev,
|
|
||||||
const enum display_orientation
|
|
||||||
orientation)
|
|
||||||
{
|
|
||||||
LOG_ERR("Unsupported");
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_set_pixel_format(const struct device *dev,
|
|
||||||
const enum display_pixel_format pf)
|
|
||||||
{
|
|
||||||
if (pf == PIXEL_FORMAT_MONO10) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_ERR("not supported");
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_clear_and_write_buffer(struct device *dev)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
u8_t clear_page[EPD_PANEL_WIDTH];
|
|
||||||
u8_t page;
|
|
||||||
struct spi_buf sbuf;
|
|
||||||
struct spi_buf_set buf_set = {.buffers = &sbuf, .count = 1};
|
|
||||||
struct ssd1673_data *driver = dev->driver_data;
|
|
||||||
u8_t tmp;
|
|
||||||
|
|
||||||
tmp = SSD1673_DATA_ENTRY_XIYDY;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_ENTRY_MODE, &tmp, 1);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ssd1673_set_ram_param(driver, SSD1673_PANEL_FIRST_PAGE,
|
|
||||||
SSD1673_PANEL_LAST_PAGE + 1,
|
|
||||||
SSD1673_PANEL_LAST_GATE,
|
|
||||||
SSD1673_PANEL_FIRST_GATE);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ssd1673_set_ram_ptr(driver, SSD1673_PANEL_FIRST_PAGE,
|
|
||||||
SSD1673_PANEL_LAST_GATE);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_pin_write(driver->dc, DT_INST_0_SOLOMON_SSD1673FB_DC_GPIOS_PIN, 0);
|
|
||||||
|
|
||||||
tmp = SSD1673_CMD_WRITE_RAM;
|
|
||||||
sbuf.buf = &tmp;
|
|
||||||
sbuf.len = 1;
|
|
||||||
err = spi_write(driver->spi_dev, &driver->spi_config, &buf_set);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_pin_write(driver->dc, DT_INST_0_SOLOMON_SSD1673FB_DC_GPIOS_PIN, 1);
|
|
||||||
|
|
||||||
memset(clear_page, 0xff, sizeof(clear_page));
|
|
||||||
sbuf.buf = clear_page;
|
|
||||||
sbuf.len = sizeof(clear_page);
|
|
||||||
for (page = 0U; page <= (SSD1673_PANEL_LAST_PAGE + 1); ++page) {
|
|
||||||
err = spi_write(driver->spi_dev, &driver->spi_config, &buf_set);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ssd1673_update_display(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_controller_init(struct device *dev)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
u8_t tmp[3];
|
|
||||||
size_t len;
|
|
||||||
struct ssd1673_data *driver = dev->driver_data;
|
|
||||||
|
|
||||||
LOG_DBG("");
|
|
||||||
|
|
||||||
gpio_pin_write(driver->reset, DT_INST_0_SOLOMON_SSD1673FB_RESET_GPIOS_PIN, 0);
|
|
||||||
k_sleep(SSD1673_RESET_DELAY);
|
|
||||||
gpio_pin_write(driver->reset, DT_INST_0_SOLOMON_SSD1673FB_RESET_GPIOS_PIN, 1);
|
|
||||||
k_sleep(SSD1673_RESET_DELAY);
|
|
||||||
ssd1673_busy_wait(driver);
|
|
||||||
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_SW_RESET, NULL, 0);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
ssd1673_busy_wait(driver);
|
|
||||||
|
|
||||||
len = push_y_param(tmp, SSD1673_PANEL_LAST_GATE);
|
|
||||||
tmp[len++] = 0U;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_GDO_CTRL, tmp, len);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DT_INST_0_SOLOMON_SSD1673FB_SOFTSTART_1)
|
|
||||||
tmp[0] = DT_INST_0_SOLOMON_SSD1673FB_SOFTSTART_1;
|
|
||||||
tmp[1] = DT_INST_0_SOLOMON_SSD1673FB_SOFTSTART_2;
|
|
||||||
tmp[2] = DT_INST_0_SOLOMON_SSD1673FB_SOFTSTART_3;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_SOFTSTART, tmp, 3);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tmp[0] = DT_INST_0_SOLOMON_SSD1673FB_GDV_A;
|
|
||||||
#if defined(DT_INST_0_SOLOMON_SSD1673FB_GDV_B)
|
|
||||||
tmp[1] = DT_INST_0_SOLOMON_SSD1673FB_GDV_B;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_GDV_CTRL, tmp, 2);
|
|
||||||
#else
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_GDV_CTRL, tmp, 1);
|
|
||||||
#endif
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[0] = DT_INST_0_SOLOMON_SSD1673FB_SDV;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_SDV_CTRL, tmp, 1);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[0] = DT_INST_0_SOLOMON_SSD1673FB_VCOM;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_VCOM_VOLTAGE, tmp, 1);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[0] = SSD1673_VAL_DUMMY_LINE;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_DUMMY_LINE, tmp, 1);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[0] = SSD1673_VAL_GATE_LWIDTH;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_GATE_LINE_WIDTH, tmp, 1);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[0] = DT_INST_0_SOLOMON_SSD1673FB_BORDER_WAVEFORM;
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_BWF_CTRL, tmp, 1);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssd1673_set_orientation_internall(driver);
|
|
||||||
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_UPDATE_LUT,
|
|
||||||
ssd1673_lut_initial,
|
|
||||||
sizeof(ssd1673_lut_initial));
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ssd1673_clear_and_write_buffer(dev);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssd1673_busy_wait(driver);
|
|
||||||
|
|
||||||
err = ssd1673_write_cmd(driver, SSD1673_CMD_UPDATE_LUT,
|
|
||||||
ssd1673_lut_default,
|
|
||||||
sizeof(ssd1673_lut_default));
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ssd1673_clear_and_write_buffer(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssd1673_init(struct device *dev)
|
|
||||||
{
|
|
||||||
struct ssd1673_data *driver = dev->driver_data;
|
|
||||||
|
|
||||||
LOG_DBG("");
|
|
||||||
|
|
||||||
driver->spi_dev = device_get_binding(DT_INST_0_SOLOMON_SSD1673FB_BUS_NAME);
|
|
||||||
if (driver->spi_dev == NULL) {
|
|
||||||
LOG_ERR("Could not get SPI device for SSD1673");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
driver->spi_config.frequency = DT_INST_0_SOLOMON_SSD1673FB_SPI_MAX_FREQUENCY;
|
|
||||||
driver->spi_config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8);
|
|
||||||
driver->spi_config.slave = DT_INST_0_SOLOMON_SSD1673FB_BASE_ADDRESS;
|
|
||||||
driver->spi_config.cs = NULL;
|
|
||||||
|
|
||||||
driver->reset = device_get_binding(DT_INST_0_SOLOMON_SSD1673FB_RESET_GPIOS_CONTROLLER);
|
|
||||||
if (driver->reset == NULL) {
|
|
||||||
LOG_ERR("Could not get GPIO port for SSD1673 reset");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_pin_configure(driver->reset, DT_INST_0_SOLOMON_SSD1673FB_RESET_GPIOS_PIN,
|
|
||||||
GPIO_DIR_OUT);
|
|
||||||
|
|
||||||
driver->dc = device_get_binding(DT_INST_0_SOLOMON_SSD1673FB_DC_GPIOS_CONTROLLER);
|
|
||||||
if (driver->dc == NULL) {
|
|
||||||
LOG_ERR("Could not get GPIO port for SSD1673 DC signal");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_pin_configure(driver->dc, DT_INST_0_SOLOMON_SSD1673FB_DC_GPIOS_PIN,
|
|
||||||
GPIO_DIR_OUT);
|
|
||||||
|
|
||||||
driver->busy = device_get_binding(DT_INST_0_SOLOMON_SSD1673FB_BUSY_GPIOS_CONTROLLER);
|
|
||||||
if (driver->busy == NULL) {
|
|
||||||
LOG_ERR("Could not get GPIO port for SSD1673 busy signal");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_pin_configure(driver->busy, DT_INST_0_SOLOMON_SSD1673FB_BUSY_GPIOS_PIN,
|
|
||||||
GPIO_DIR_IN);
|
|
||||||
|
|
||||||
#if defined(DT_INST_0_SOLOMON_SSD1673FB_CS_GPIOS_CONTROLLER)
|
|
||||||
driver->cs_ctrl.gpio_dev = device_get_binding(
|
|
||||||
DT_INST_0_SOLOMON_SSD1673FB_CS_GPIOS_CONTROLLER);
|
|
||||||
if (!driver->cs_ctrl.gpio_dev) {
|
|
||||||
LOG_ERR("Unable to get SPI GPIO CS device");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
driver->cs_ctrl.gpio_pin = DT_INST_0_SOLOMON_SSD1673FB_CS_GPIOS_PIN;
|
|
||||||
driver->cs_ctrl.delay = 0U;
|
|
||||||
driver->spi_config.cs = &driver->cs_ctrl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ssd1673_controller_init(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ssd1673_data ssd1673_driver;
|
|
||||||
|
|
||||||
static struct display_driver_api ssd1673_driver_api = {
|
|
||||||
.blanking_on = ssd1673_resume,
|
|
||||||
.blanking_off = ssd1673_suspend,
|
|
||||||
.write = ssd1673_write,
|
|
||||||
.read = ssd1673_read,
|
|
||||||
.get_framebuffer = ssd1673_get_framebuffer,
|
|
||||||
.set_brightness = ssd1673_set_brightness,
|
|
||||||
.set_contrast = ssd1673_set_contrast,
|
|
||||||
.get_capabilities = ssd1673_get_capabilities,
|
|
||||||
.set_pixel_format = ssd1673_set_pixel_format,
|
|
||||||
.set_orientation = ssd1673_set_orientation,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(ssd1673, DT_INST_0_SOLOMON_SSD1673FB_LABEL, ssd1673_init,
|
|
||||||
&ssd1673_driver, NULL,
|
|
||||||
POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY,
|
|
||||||
&ssd1673_driver_api);
|
|
|
@ -1,77 +0,0 @@
|
||||||
/* ssd1673_regs.h - Registers definition for SSD1673 controller */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 PHYTEC Messtechnik GmbH
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SSD1673_REGS_H__
|
|
||||||
#define __SSD1673_REGS_H__
|
|
||||||
|
|
||||||
#define SSD1673_CMD_GDO_CTRL 0x01
|
|
||||||
#define SSD1673_CMD_GDV_CTRL 0x03
|
|
||||||
#define SSD1673_CMD_SDV_CTRL 0x04
|
|
||||||
#define SSD1673_CMD_SOFTSTART 0x0c
|
|
||||||
#define SSD1673_CMD_GSCAN_START 0x0f
|
|
||||||
#define SSD1673_CMD_SLEEP_MODE 0x10
|
|
||||||
#define SSD1673_CMD_ENTRY_MODE 0x11
|
|
||||||
#define SSD1673_CMD_SW_RESET 0x12
|
|
||||||
#define SSD1673_CMD_TSENS_CTRL 0x1a
|
|
||||||
#define SSD1673_CMD_MASTER_ACTIVATION 0x20
|
|
||||||
#define SSD1673_CMD_UPDATE_CTRL1 0x21
|
|
||||||
#define SSD1673_CMD_UPDATE_CTRL2 0x22
|
|
||||||
#define SSD1673_CMD_WRITE_RAM 0x24
|
|
||||||
#define SSD1673_CMD_VCOM_SENSE 0x28
|
|
||||||
#define SSD1673_CMD_VCOM_SENSE_DURATON 0x29
|
|
||||||
#define SSD1673_CMD_PRGM_VCOM_OTP 0x2a
|
|
||||||
#define SSD1673_CMD_VCOM_VOLTAGE 0x2c
|
|
||||||
#define SSD1673_CMD_PRGM_WS_OTP 0x30
|
|
||||||
#define SSD1673_CMD_UPDATE_LUT 0x32
|
|
||||||
#define SSD1673_CMD_PRGM_OTP_SELECTION 0x36
|
|
||||||
#define SSD1673_CMD_OTP_SELECTION_CTRL 0x37
|
|
||||||
#define SSD1673_CMD_DUMMY_LINE 0x3a
|
|
||||||
#define SSD1673_CMD_GATE_LINE_WIDTH 0x3b
|
|
||||||
#define SSD1673_CMD_BWF_CTRL 0x3c
|
|
||||||
#define SSD1673_CMD_RAM_XPOS_CTRL 0x44
|
|
||||||
#define SSD1673_CMD_RAM_YPOS_CTRL 0x45
|
|
||||||
#define SSD1673_CMD_RAM_XPOS_CNTR 0x4e
|
|
||||||
#define SSD1673_CMD_RAM_YPOS_CNTR 0x4f
|
|
||||||
|
|
||||||
/* Data entry sequence modes */
|
|
||||||
#define SSD1673_DATA_ENTRY_MASK 0x07
|
|
||||||
#define SSD1673_DATA_ENTRY_XDYDX 0x00
|
|
||||||
#define SSD1673_DATA_ENTRY_XIYDX 0x01
|
|
||||||
#define SSD1673_DATA_ENTRY_XDYIX 0x02
|
|
||||||
#define SSD1673_DATA_ENTRY_XIYIX 0x03
|
|
||||||
#define SSD1673_DATA_ENTRY_XDYDY 0x04
|
|
||||||
#define SSD1673_DATA_ENTRY_XIYDY 0x05
|
|
||||||
#define SSD1673_DATA_ENTRY_XDYIY 0x06
|
|
||||||
#define SSD1673_DATA_ENTRY_XIYIY 0x07
|
|
||||||
|
|
||||||
/* Options for display update */
|
|
||||||
#define SSD1673_CTRL1_INITIAL_UPDATE_LL 0x00
|
|
||||||
#define SSD1673_CTRL1_INITIAL_UPDATE_LH 0x01
|
|
||||||
#define SSD1673_CTRL1_INITIAL_UPDATE_HL 0x02
|
|
||||||
#define SSD1673_CTRL1_INITIAL_UPDATE_HH 0x03
|
|
||||||
|
|
||||||
/* Options for display update sequence */
|
|
||||||
#define SSD1673_CTRL2_ENABLE_CLK 0x80
|
|
||||||
#define SSD1673_CTRL2_ENABLE_ANALOG 0x40
|
|
||||||
#define SSD1673_CTRL2_TO_INITIAL 0x08
|
|
||||||
#define SSD1673_CTRL2_TO_PATTERN 0x04
|
|
||||||
#define SSD1673_CTRL2_DISABLE_ANALOG 0x02
|
|
||||||
#define SSD1673_CTRL2_DISABLE_CLK 0x01
|
|
||||||
|
|
||||||
#define SSD1673_SLEEP_MODE_DSM 0x01
|
|
||||||
#define SSD1673_SLEEP_MODE_PON 0x00
|
|
||||||
|
|
||||||
/* Default values */
|
|
||||||
#define SSD1673_VAL_DUMMY_LINE 0x1a
|
|
||||||
#define SSD1673_VAL_GATE_LWIDTH 0x08
|
|
||||||
|
|
||||||
/* time constants in ms */
|
|
||||||
#define SSD1673_RESET_DELAY 1
|
|
||||||
#define SSD1673_BUSY_DELAY 1
|
|
||||||
|
|
||||||
#endif /* __SSD1673_REGS_H__ */
|
|
662
drivers/display/ssd16xx.c
Normal file
662
drivers/display/ssd16xx.c
Normal file
|
@ -0,0 +1,662 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 PHYTEC Messtechnik GmbH
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_DISPLAY_LOG_LEVEL
|
||||||
|
#include <logging/log.h>
|
||||||
|
LOG_MODULE_REGISTER(ssd16xx);
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include <drivers/display.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <drivers/spi.h>
|
||||||
|
#include <sys/byteorder.h>
|
||||||
|
|
||||||
|
#include "ssd16xx_regs.h"
|
||||||
|
#include <display/cfb.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSD1673, SSD1608 compatible EPD controller driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EPD_PANEL_WIDTH DT_INST_0_SOLOMON_SSD16XXFB_WIDTH
|
||||||
|
#define EPD_PANEL_HEIGHT DT_INST_0_SOLOMON_SSD16XXFB_HEIGHT
|
||||||
|
#define EPD_PANEL_NUMOF_COLUMS EPD_PANEL_WIDTH
|
||||||
|
#define EPD_PANEL_NUMOF_ROWS_PER_PAGE 8
|
||||||
|
#define EPD_PANEL_NUMOF_PAGES (EPD_PANEL_HEIGHT / \
|
||||||
|
EPD_PANEL_NUMOF_ROWS_PER_PAGE)
|
||||||
|
|
||||||
|
#define SSD16XX_PANEL_FIRST_PAGE 0
|
||||||
|
#define SSD16XX_PANEL_LAST_PAGE (EPD_PANEL_NUMOF_PAGES - 1)
|
||||||
|
#define SSD16XX_PANEL_FIRST_GATE 0
|
||||||
|
#define SSD16XX_PANEL_LAST_GATE (EPD_PANEL_NUMOF_COLUMS - 1)
|
||||||
|
|
||||||
|
#define SSD16XX_PIXELS_PER_BYTE 8
|
||||||
|
|
||||||
|
struct ssd16xx_data {
|
||||||
|
struct device *reset;
|
||||||
|
struct device *dc;
|
||||||
|
struct device *busy;
|
||||||
|
struct device *spi_dev;
|
||||||
|
struct spi_config spi_config;
|
||||||
|
#if defined(DT_INST_0_SOLOMON_SSD16XXFB_CS_GPIOS_CONTROLLER)
|
||||||
|
struct spi_cs_control cs_ctrl;
|
||||||
|
#endif
|
||||||
|
u8_t scan_mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(DT_GD_GDE0213B1_0)
|
||||||
|
static u8_t ssd16xx_lut_initial[] = {
|
||||||
|
0x22, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x11,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static u8_t ssd16xx_lut_default[] = {
|
||||||
|
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
#elif defined(DT_GD_GDE029A1_0)
|
||||||
|
static u8_t ssd16xx_lut_initial[] = {
|
||||||
|
0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static u8_t ssd16xx_lut_default[] = {
|
||||||
|
0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
#elif defined(DT_HINK_E0154A05_0)
|
||||||
|
static u8_t ssd16xx_lut_initial[] = {
|
||||||
|
0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22,
|
||||||
|
0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51,
|
||||||
|
0x35, 0x51, 0x51, 0x19, 0x01, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static u8_t ssd16xx_lut_default[] = {
|
||||||
|
0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
#error "No waveform look up table (LUT) selected!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int ssd16xx_write_cmd(struct ssd16xx_data *driver,
|
||||||
|
u8_t cmd, u8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct spi_buf buf = {.buf = &cmd, .len = sizeof(cmd)};
|
||||||
|
struct spi_buf_set buf_set = {.buffers = &buf, .count = 1};
|
||||||
|
|
||||||
|
gpio_pin_write(driver->dc, DT_INST_0_SOLOMON_SSD16XXFB_DC_GPIOS_PIN, 0);
|
||||||
|
err = spi_write(driver->spi_dev, &driver->spi_config, &buf_set);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != NULL) {
|
||||||
|
buf.buf = data;
|
||||||
|
buf.len = len;
|
||||||
|
gpio_pin_write(driver->dc, DT_INST_0_SOLOMON_SSD16XXFB_DC_GPIOS_PIN, 1);
|
||||||
|
err = spi_write(driver->spi_dev, &driver->spi_config, &buf_set);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ssd16xx_busy_wait(struct ssd16xx_data *driver)
|
||||||
|
{
|
||||||
|
u32_t val = 0U;
|
||||||
|
|
||||||
|
gpio_pin_read(driver->busy, DT_INST_0_SOLOMON_SSD16XXFB_BUSY_GPIOS_PIN, &val);
|
||||||
|
while (val) {
|
||||||
|
k_sleep(SSD16XX_BUSY_DELAY);
|
||||||
|
gpio_pin_read(driver->busy, DT_INST_0_SOLOMON_SSD16XXFB_BUSY_GPIOS_PIN, &val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t push_x_param(u8_t *data, u16_t x)
|
||||||
|
{
|
||||||
|
#if DT_INST_0_SOLOMON_SSD16XXFB_PP_WIDTH_BITS == 8
|
||||||
|
data[0] = (u8_t)x;
|
||||||
|
return 1;
|
||||||
|
#elif DT_INST_0_SOLOMON_SSD16XXFB_PP_WIDTH_BITS == 16
|
||||||
|
sys_put_le16(sys_cpu_to_le16(x), data);
|
||||||
|
return 2;
|
||||||
|
#else
|
||||||
|
#error Unsupported DT_INST_0_SOLOMON_SSD16XXFB_PP_WIDTH_BITS value
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t push_y_param(u8_t *data, u16_t y)
|
||||||
|
{
|
||||||
|
#if DT_INST_0_SOLOMON_SSD16XXFB_PP_HEIGHT_BITS == 8
|
||||||
|
data[0] = (u8_t)y;
|
||||||
|
return 1;
|
||||||
|
#elif DT_INST_0_SOLOMON_SSD16XXFB_PP_HEIGHT_BITS == 16
|
||||||
|
sys_put_le16(sys_cpu_to_le16(y), data);
|
||||||
|
return 2;
|
||||||
|
#else
|
||||||
|
#error Unsupported DT_INST_0_SOLOMON_SSD16XXFB_PP_HEIGHT_BITS value
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int ssd16xx_set_ram_param(struct ssd16xx_data *driver,
|
||||||
|
u16_t sx, u16_t ex, u16_t sy, u16_t ey)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
u8_t tmp[4];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = push_x_param(tmp, sx);
|
||||||
|
len += push_x_param(tmp + len, ex);
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_RAM_XPOS_CTRL, tmp, len);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = push_y_param(tmp, sy);
|
||||||
|
len += push_y_param(tmp + len, ey);
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_RAM_YPOS_CTRL, tmp, len);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ssd16xx_set_ram_ptr(struct ssd16xx_data *driver,
|
||||||
|
u16_t x, u16_t y)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
u8_t tmp[2];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = push_x_param(tmp, x);
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_RAM_XPOS_CNTR, tmp, len);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = push_y_param(tmp, y);
|
||||||
|
return ssd16xx_write_cmd(driver, SSD16XX_CMD_RAM_YPOS_CNTR, tmp, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ssd16xx_set_orientation_internall(struct ssd16xx_data *driver)
|
||||||
|
|
||||||
|
{
|
||||||
|
#if DT_INST_0_SOLOMON_SSD16XXFB_ORIENTATION_FLIPPED == 1
|
||||||
|
driver->scan_mode = SSD16XX_DATA_ENTRY_XIYDY;
|
||||||
|
#else
|
||||||
|
driver->scan_mode = SSD16XX_DATA_ENTRY_XDYIY;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssd16xx_resume(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct ssd16xx_data *driver = dev->driver_data;
|
||||||
|
u8_t tmp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment for voltage measurement
|
||||||
|
* tmp = SSD16XX_CTRL2_ENABLE_CLK;
|
||||||
|
* ssd16xx_write_cmd(SSD16XX_CMD_UPDATE_CTRL2, &tmp, sizeof(tmp));
|
||||||
|
* ssd16xx_write_cmd(SSD16XX_CMD_MASTER_ACTIVATION, NULL, 0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
tmp = SSD16XX_SLEEP_MODE_PON;
|
||||||
|
return ssd16xx_write_cmd(driver, SSD16XX_CMD_SLEEP_MODE,
|
||||||
|
&tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_suspend(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct ssd16xx_data *driver = dev->driver_data;
|
||||||
|
u8_t tmp = SSD16XX_SLEEP_MODE_DSM;
|
||||||
|
|
||||||
|
return ssd16xx_write_cmd(driver, SSD16XX_CMD_SLEEP_MODE,
|
||||||
|
&tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_update_display(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct ssd16xx_data *driver = dev->driver_data;
|
||||||
|
u8_t tmp;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
tmp = SSD16XX_CTRL1_INITIAL_UPDATE_LH;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_CTRL1,
|
||||||
|
&tmp, sizeof(tmp));
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = (SSD16XX_CTRL2_ENABLE_CLK |
|
||||||
|
SSD16XX_CTRL2_ENABLE_ANALOG |
|
||||||
|
SSD16XX_CTRL2_TO_PATTERN |
|
||||||
|
SSD16XX_CTRL2_DISABLE_ANALOG |
|
||||||
|
SSD16XX_CTRL2_DISABLE_CLK);
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_CTRL2, &tmp,
|
||||||
|
sizeof(tmp));
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ssd16xx_write_cmd(driver, SSD16XX_CMD_MASTER_ACTIVATION,
|
||||||
|
NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_write(const struct device *dev, const u16_t x,
|
||||||
|
const u16_t y,
|
||||||
|
const struct display_buffer_descriptor *desc,
|
||||||
|
const void *buf)
|
||||||
|
{
|
||||||
|
struct ssd16xx_data *driver = dev->driver_data;
|
||||||
|
int err;
|
||||||
|
u16_t x_start;
|
||||||
|
u16_t x_end;
|
||||||
|
u16_t y_start;
|
||||||
|
u16_t y_end;
|
||||||
|
|
||||||
|
if (desc->pitch < desc->width) {
|
||||||
|
LOG_ERR("Pitch is smaller than width");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf == NULL || desc->buf_size == 0U) {
|
||||||
|
LOG_ERR("Display buffer is not available");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc->pitch > desc->width) {
|
||||||
|
LOG_ERR("Unsupported mode");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((y + desc->height) > EPD_PANEL_HEIGHT) {
|
||||||
|
LOG_ERR("Buffer out of bounds (height)");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((x + desc->width) > EPD_PANEL_WIDTH) {
|
||||||
|
LOG_ERR("Buffer out of bounds (width)");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((desc->height % EPD_PANEL_NUMOF_ROWS_PER_PAGE) != 0U) {
|
||||||
|
LOG_ERR("Buffer height not multiple of %d",
|
||||||
|
EPD_PANEL_NUMOF_ROWS_PER_PAGE);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((y % EPD_PANEL_NUMOF_ROWS_PER_PAGE) != 0U) {
|
||||||
|
LOG_ERR("Y coordinate not multiple of %d",
|
||||||
|
EPD_PANEL_NUMOF_ROWS_PER_PAGE);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (driver->scan_mode) {
|
||||||
|
case SSD16XX_DATA_ENTRY_XIYDY:
|
||||||
|
x_start = y / SSD16XX_PIXELS_PER_BYTE;
|
||||||
|
x_end = (y + desc->height - 1) / SSD16XX_PIXELS_PER_BYTE;
|
||||||
|
y_start = (x + desc->width - 1);
|
||||||
|
y_end = x;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSD16XX_DATA_ENTRY_XDYIY:
|
||||||
|
x_start = (EPD_PANEL_HEIGHT - 1 - y) / SSD16XX_PIXELS_PER_BYTE;
|
||||||
|
x_end = (EPD_PANEL_HEIGHT - 1 - (y + desc->height - 1)) /
|
||||||
|
SSD16XX_PIXELS_PER_BYTE;
|
||||||
|
y_start = x;
|
||||||
|
y_end = (x + desc->width - 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssd16xx_busy_wait(driver);
|
||||||
|
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_ENTRY_MODE,
|
||||||
|
&driver->scan_mode, sizeof(driver->scan_mode));
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ssd16xx_set_ram_param(driver, x_start, x_end, y_start, y_end);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ssd16xx_set_ram_ptr(driver, x_start, y_start);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_WRITE_RAM, (u8_t *)buf,
|
||||||
|
desc->buf_size);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ssd16xx_update_display(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_read(const struct device *dev, const u16_t x,
|
||||||
|
const u16_t y,
|
||||||
|
const struct display_buffer_descriptor *desc,
|
||||||
|
void *buf)
|
||||||
|
{
|
||||||
|
LOG_ERR("not supported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *ssd16xx_get_framebuffer(const struct device *dev)
|
||||||
|
{
|
||||||
|
LOG_ERR("not supported");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_set_brightness(const struct device *dev,
|
||||||
|
const u8_t brightness)
|
||||||
|
{
|
||||||
|
LOG_WRN("not supported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_set_contrast(const struct device *dev, u8_t contrast)
|
||||||
|
{
|
||||||
|
LOG_WRN("not supported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ssd16xx_get_capabilities(const struct device *dev,
|
||||||
|
struct display_capabilities *caps)
|
||||||
|
{
|
||||||
|
memset(caps, 0, sizeof(struct display_capabilities));
|
||||||
|
caps->x_resolution = EPD_PANEL_WIDTH;
|
||||||
|
caps->y_resolution = EPD_PANEL_HEIGHT;
|
||||||
|
caps->supported_pixel_formats = PIXEL_FORMAT_MONO10;
|
||||||
|
caps->current_pixel_format = PIXEL_FORMAT_MONO10;
|
||||||
|
caps->screen_info = SCREEN_INFO_MONO_VTILED |
|
||||||
|
SCREEN_INFO_MONO_MSB_FIRST |
|
||||||
|
SCREEN_INFO_EPD |
|
||||||
|
SCREEN_INFO_DOUBLE_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_set_orientation(const struct device *dev,
|
||||||
|
const enum display_orientation
|
||||||
|
orientation)
|
||||||
|
{
|
||||||
|
LOG_ERR("Unsupported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_set_pixel_format(const struct device *dev,
|
||||||
|
const enum display_pixel_format pf)
|
||||||
|
{
|
||||||
|
if (pf == PIXEL_FORMAT_MONO10) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERR("not supported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_clear_and_write_buffer(struct device *dev)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
u8_t clear_page[EPD_PANEL_WIDTH];
|
||||||
|
u8_t page;
|
||||||
|
struct spi_buf sbuf;
|
||||||
|
struct spi_buf_set buf_set = {.buffers = &sbuf, .count = 1};
|
||||||
|
struct ssd16xx_data *driver = dev->driver_data;
|
||||||
|
u8_t tmp;
|
||||||
|
|
||||||
|
tmp = SSD16XX_DATA_ENTRY_XIYDY;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_ENTRY_MODE, &tmp, 1);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ssd16xx_set_ram_param(driver, SSD16XX_PANEL_FIRST_PAGE,
|
||||||
|
SSD16XX_PANEL_LAST_PAGE + 1,
|
||||||
|
SSD16XX_PANEL_LAST_GATE,
|
||||||
|
SSD16XX_PANEL_FIRST_GATE);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ssd16xx_set_ram_ptr(driver, SSD16XX_PANEL_FIRST_PAGE,
|
||||||
|
SSD16XX_PANEL_LAST_GATE);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_write(driver->dc, DT_INST_0_SOLOMON_SSD16XXFB_DC_GPIOS_PIN, 0);
|
||||||
|
|
||||||
|
tmp = SSD16XX_CMD_WRITE_RAM;
|
||||||
|
sbuf.buf = &tmp;
|
||||||
|
sbuf.len = 1;
|
||||||
|
err = spi_write(driver->spi_dev, &driver->spi_config, &buf_set);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_write(driver->dc, DT_INST_0_SOLOMON_SSD16XXFB_DC_GPIOS_PIN, 1);
|
||||||
|
|
||||||
|
memset(clear_page, 0xff, sizeof(clear_page));
|
||||||
|
sbuf.buf = clear_page;
|
||||||
|
sbuf.len = sizeof(clear_page);
|
||||||
|
for (page = 0U; page <= (SSD16XX_PANEL_LAST_PAGE + 1); ++page) {
|
||||||
|
err = spi_write(driver->spi_dev, &driver->spi_config, &buf_set);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ssd16xx_update_display(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_controller_init(struct device *dev)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
u8_t tmp[3];
|
||||||
|
size_t len;
|
||||||
|
struct ssd16xx_data *driver = dev->driver_data;
|
||||||
|
|
||||||
|
LOG_DBG("");
|
||||||
|
|
||||||
|
gpio_pin_write(driver->reset, DT_INST_0_SOLOMON_SSD16XXFB_RESET_GPIOS_PIN, 0);
|
||||||
|
k_sleep(SSD16XX_RESET_DELAY);
|
||||||
|
gpio_pin_write(driver->reset, DT_INST_0_SOLOMON_SSD16XXFB_RESET_GPIOS_PIN, 1);
|
||||||
|
k_sleep(SSD16XX_RESET_DELAY);
|
||||||
|
ssd16xx_busy_wait(driver);
|
||||||
|
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_SW_RESET, NULL, 0);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
ssd16xx_busy_wait(driver);
|
||||||
|
|
||||||
|
len = push_y_param(tmp, SSD16XX_PANEL_LAST_GATE);
|
||||||
|
tmp[len++] = 0U;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_GDO_CTRL, tmp, len);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DT_INST_0_SOLOMON_SSD16XXFB_SOFTSTART_1)
|
||||||
|
tmp[0] = DT_INST_0_SOLOMON_SSD16XXFB_SOFTSTART_1;
|
||||||
|
tmp[1] = DT_INST_0_SOLOMON_SSD16XXFB_SOFTSTART_2;
|
||||||
|
tmp[2] = DT_INST_0_SOLOMON_SSD16XXFB_SOFTSTART_3;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_SOFTSTART, tmp, 3);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tmp[0] = DT_INST_0_SOLOMON_SSD16XXFB_GDV_A;
|
||||||
|
#if defined(DT_INST_0_SOLOMON_SSD16XXFB_GDV_B)
|
||||||
|
tmp[1] = DT_INST_0_SOLOMON_SSD16XXFB_GDV_B;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_GDV_CTRL, tmp, 2);
|
||||||
|
#else
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_GDV_CTRL, tmp, 1);
|
||||||
|
#endif
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[0] = DT_INST_0_SOLOMON_SSD16XXFB_SDV;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_SDV_CTRL, tmp, 1);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[0] = DT_INST_0_SOLOMON_SSD16XXFB_VCOM;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_VCOM_VOLTAGE, tmp, 1);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[0] = SSD16XX_VAL_DUMMY_LINE;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_DUMMY_LINE, tmp, 1);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[0] = SSD16XX_VAL_GATE_LWIDTH;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_GATE_LINE_WIDTH, tmp, 1);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[0] = DT_INST_0_SOLOMON_SSD16XXFB_BORDER_WAVEFORM;
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_BWF_CTRL, tmp, 1);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssd16xx_set_orientation_internall(driver);
|
||||||
|
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_LUT,
|
||||||
|
ssd16xx_lut_initial,
|
||||||
|
sizeof(ssd16xx_lut_initial));
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ssd16xx_clear_and_write_buffer(dev);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssd16xx_busy_wait(driver);
|
||||||
|
|
||||||
|
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_LUT,
|
||||||
|
ssd16xx_lut_default,
|
||||||
|
sizeof(ssd16xx_lut_default));
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ssd16xx_clear_and_write_buffer(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssd16xx_init(struct device *dev)
|
||||||
|
{
|
||||||
|
struct ssd16xx_data *driver = dev->driver_data;
|
||||||
|
|
||||||
|
LOG_DBG("");
|
||||||
|
|
||||||
|
driver->spi_dev = device_get_binding(DT_INST_0_SOLOMON_SSD16XXFB_BUS_NAME);
|
||||||
|
if (driver->spi_dev == NULL) {
|
||||||
|
LOG_ERR("Could not get SPI device for SSD16XX");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
driver->spi_config.frequency = DT_INST_0_SOLOMON_SSD16XXFB_SPI_MAX_FREQUENCY;
|
||||||
|
driver->spi_config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8);
|
||||||
|
driver->spi_config.slave = DT_INST_0_SOLOMON_SSD16XXFB_BASE_ADDRESS;
|
||||||
|
driver->spi_config.cs = NULL;
|
||||||
|
|
||||||
|
driver->reset = device_get_binding(DT_INST_0_SOLOMON_SSD16XXFB_RESET_GPIOS_CONTROLLER);
|
||||||
|
if (driver->reset == NULL) {
|
||||||
|
LOG_ERR("Could not get GPIO port for SSD16XX reset");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_configure(driver->reset, DT_INST_0_SOLOMON_SSD16XXFB_RESET_GPIOS_PIN,
|
||||||
|
GPIO_DIR_OUT);
|
||||||
|
|
||||||
|
driver->dc = device_get_binding(DT_INST_0_SOLOMON_SSD16XXFB_DC_GPIOS_CONTROLLER);
|
||||||
|
if (driver->dc == NULL) {
|
||||||
|
LOG_ERR("Could not get GPIO port for SSD16XX DC signal");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_configure(driver->dc, DT_INST_0_SOLOMON_SSD16XXFB_DC_GPIOS_PIN,
|
||||||
|
GPIO_DIR_OUT);
|
||||||
|
|
||||||
|
driver->busy = device_get_binding(DT_INST_0_SOLOMON_SSD16XXFB_BUSY_GPIOS_CONTROLLER);
|
||||||
|
if (driver->busy == NULL) {
|
||||||
|
LOG_ERR("Could not get GPIO port for SSD16XX busy signal");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_configure(driver->busy, DT_INST_0_SOLOMON_SSD16XXFB_BUSY_GPIOS_PIN,
|
||||||
|
GPIO_DIR_IN);
|
||||||
|
|
||||||
|
#if defined(DT_INST_0_SOLOMON_SSD16XXFB_CS_GPIOS_CONTROLLER)
|
||||||
|
driver->cs_ctrl.gpio_dev = device_get_binding(
|
||||||
|
DT_INST_0_SOLOMON_SSD16XXFB_CS_GPIOS_CONTROLLER);
|
||||||
|
if (!driver->cs_ctrl.gpio_dev) {
|
||||||
|
LOG_ERR("Unable to get SPI GPIO CS device");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
driver->cs_ctrl.gpio_pin = DT_INST_0_SOLOMON_SSD16XXFB_CS_GPIOS_PIN;
|
||||||
|
driver->cs_ctrl.delay = 0U;
|
||||||
|
driver->spi_config.cs = &driver->cs_ctrl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ssd16xx_controller_init(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ssd16xx_data ssd16xx_driver;
|
||||||
|
|
||||||
|
static struct display_driver_api ssd16xx_driver_api = {
|
||||||
|
.blanking_on = ssd16xx_resume,
|
||||||
|
.blanking_off = ssd16xx_suspend,
|
||||||
|
.write = ssd16xx_write,
|
||||||
|
.read = ssd16xx_read,
|
||||||
|
.get_framebuffer = ssd16xx_get_framebuffer,
|
||||||
|
.set_brightness = ssd16xx_set_brightness,
|
||||||
|
.set_contrast = ssd16xx_set_contrast,
|
||||||
|
.get_capabilities = ssd16xx_get_capabilities,
|
||||||
|
.set_pixel_format = ssd16xx_set_pixel_format,
|
||||||
|
.set_orientation = ssd16xx_set_orientation,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DEVICE_AND_API_INIT(ssd16xx, DT_INST_0_SOLOMON_SSD16XXFB_LABEL, ssd16xx_init,
|
||||||
|
&ssd16xx_driver, NULL,
|
||||||
|
POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY,
|
||||||
|
&ssd16xx_driver_api);
|
77
drivers/display/ssd16xx_regs.h
Normal file
77
drivers/display/ssd16xx_regs.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/* ssd16xx_regs.h - Registers definition for SSD16XX compatible controller */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 PHYTEC Messtechnik GmbH
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SSD16XX_REGS_H__
|
||||||
|
#define __SSD16XX_REGS_H__
|
||||||
|
|
||||||
|
#define SSD16XX_CMD_GDO_CTRL 0x01
|
||||||
|
#define SSD16XX_CMD_GDV_CTRL 0x03
|
||||||
|
#define SSD16XX_CMD_SDV_CTRL 0x04
|
||||||
|
#define SSD16XX_CMD_SOFTSTART 0x0c
|
||||||
|
#define SSD16XX_CMD_GSCAN_START 0x0f
|
||||||
|
#define SSD16XX_CMD_SLEEP_MODE 0x10
|
||||||
|
#define SSD16XX_CMD_ENTRY_MODE 0x11
|
||||||
|
#define SSD16XX_CMD_SW_RESET 0x12
|
||||||
|
#define SSD16XX_CMD_TSENS_CTRL 0x1a
|
||||||
|
#define SSD16XX_CMD_MASTER_ACTIVATION 0x20
|
||||||
|
#define SSD16XX_CMD_UPDATE_CTRL1 0x21
|
||||||
|
#define SSD16XX_CMD_UPDATE_CTRL2 0x22
|
||||||
|
#define SSD16XX_CMD_WRITE_RAM 0x24
|
||||||
|
#define SSD16XX_CMD_VCOM_SENSE 0x28
|
||||||
|
#define SSD16XX_CMD_VCOM_SENSE_DURATON 0x29
|
||||||
|
#define SSD16XX_CMD_PRGM_VCOM_OTP 0x2a
|
||||||
|
#define SSD16XX_CMD_VCOM_VOLTAGE 0x2c
|
||||||
|
#define SSD16XX_CMD_PRGM_WS_OTP 0x30
|
||||||
|
#define SSD16XX_CMD_UPDATE_LUT 0x32
|
||||||
|
#define SSD16XX_CMD_PRGM_OTP_SELECTION 0x36
|
||||||
|
#define SSD16XX_CMD_OTP_SELECTION_CTRL 0x37
|
||||||
|
#define SSD16XX_CMD_DUMMY_LINE 0x3a
|
||||||
|
#define SSD16XX_CMD_GATE_LINE_WIDTH 0x3b
|
||||||
|
#define SSD16XX_CMD_BWF_CTRL 0x3c
|
||||||
|
#define SSD16XX_CMD_RAM_XPOS_CTRL 0x44
|
||||||
|
#define SSD16XX_CMD_RAM_YPOS_CTRL 0x45
|
||||||
|
#define SSD16XX_CMD_RAM_XPOS_CNTR 0x4e
|
||||||
|
#define SSD16XX_CMD_RAM_YPOS_CNTR 0x4f
|
||||||
|
|
||||||
|
/* Data entry sequence modes */
|
||||||
|
#define SSD16XX_DATA_ENTRY_MASK 0x07
|
||||||
|
#define SSD16XX_DATA_ENTRY_XDYDX 0x00
|
||||||
|
#define SSD16XX_DATA_ENTRY_XIYDX 0x01
|
||||||
|
#define SSD16XX_DATA_ENTRY_XDYIX 0x02
|
||||||
|
#define SSD16XX_DATA_ENTRY_XIYIX 0x03
|
||||||
|
#define SSD16XX_DATA_ENTRY_XDYDY 0x04
|
||||||
|
#define SSD16XX_DATA_ENTRY_XIYDY 0x05
|
||||||
|
#define SSD16XX_DATA_ENTRY_XDYIY 0x06
|
||||||
|
#define SSD16XX_DATA_ENTRY_XIYIY 0x07
|
||||||
|
|
||||||
|
/* Options for display update */
|
||||||
|
#define SSD16XX_CTRL1_INITIAL_UPDATE_LL 0x00
|
||||||
|
#define SSD16XX_CTRL1_INITIAL_UPDATE_LH 0x01
|
||||||
|
#define SSD16XX_CTRL1_INITIAL_UPDATE_HL 0x02
|
||||||
|
#define SSD16XX_CTRL1_INITIAL_UPDATE_HH 0x03
|
||||||
|
|
||||||
|
/* Options for display update sequence */
|
||||||
|
#define SSD16XX_CTRL2_ENABLE_CLK 0x80
|
||||||
|
#define SSD16XX_CTRL2_ENABLE_ANALOG 0x40
|
||||||
|
#define SSD16XX_CTRL2_TO_INITIAL 0x08
|
||||||
|
#define SSD16XX_CTRL2_TO_PATTERN 0x04
|
||||||
|
#define SSD16XX_CTRL2_DISABLE_ANALOG 0x02
|
||||||
|
#define SSD16XX_CTRL2_DISABLE_CLK 0x01
|
||||||
|
|
||||||
|
#define SSD16XX_SLEEP_MODE_DSM 0x01
|
||||||
|
#define SSD16XX_SLEEP_MODE_PON 0x00
|
||||||
|
|
||||||
|
/* Default values */
|
||||||
|
#define SSD16XX_VAL_DUMMY_LINE 0x1a
|
||||||
|
#define SSD16XX_VAL_GATE_LWIDTH 0x08
|
||||||
|
|
||||||
|
/* time constants in ms */
|
||||||
|
#define SSD16XX_RESET_DELAY 1
|
||||||
|
#define SSD16XX_BUSY_DELAY 1
|
||||||
|
|
||||||
|
#endif /* __SSD16XX_REGS_H__ */
|
|
@ -4,18 +4,18 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
||||||
title: SSD1673 250x150 EPD Display Controller
|
title: SSD16XX 250x150 EPD Display Controller
|
||||||
version: 0.1
|
version: 0.1
|
||||||
|
|
||||||
description: >
|
description: >
|
||||||
This is a representation of the SSD1673 250x150 EPD Display Controller
|
This is a representation of the SSD16XX 250x150 EPD Display Controller
|
||||||
|
|
||||||
inherits:
|
inherits:
|
||||||
!include spi-device.yaml
|
!include spi-device.yaml
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
constraint: "solomon,ssd1673fb"
|
constraint: "solomon,ssd16xxfb"
|
||||||
|
|
||||||
height:
|
height:
|
||||||
type: int
|
type: int
|
||||||
|
|
|
@ -61,7 +61,7 @@ CONFIG_SPI_ASYNC=y
|
||||||
|
|
||||||
CONFIG_HEAP_MEM_POOL_SIZE=16384
|
CONFIG_HEAP_MEM_POOL_SIZE=16384
|
||||||
CONFIG_DISPLAY=y
|
CONFIG_DISPLAY=y
|
||||||
CONFIG_SSD1673=y
|
CONFIG_SSD16XX=y
|
||||||
|
|
||||||
CONFIG_CHARACTER_FRAMEBUFFER=y
|
CONFIG_CHARACTER_FRAMEBUFFER=y
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ static struct device_info dev_info[] = {
|
||||||
{ NULL, DT_INST_0_TI_HDC1010_LABEL },
|
{ NULL, DT_INST_0_TI_HDC1010_LABEL },
|
||||||
{ NULL, DT_INST_0_NXP_MMA8652FC_LABEL },
|
{ NULL, DT_INST_0_NXP_MMA8652FC_LABEL },
|
||||||
{ NULL, DT_INST_0_AVAGO_APDS9960_LABEL },
|
{ NULL, DT_INST_0_AVAGO_APDS9960_LABEL },
|
||||||
{ NULL, DT_INST_0_SOLOMON_SSD1673FB_LABEL },
|
{ NULL, DT_INST_0_SOLOMON_SSD16XXFB_LABEL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void configure_gpios(void)
|
static void configure_gpios(void)
|
||||||
|
|
|
@ -588,9 +588,9 @@ void board_refresh_display(void)
|
||||||
|
|
||||||
int board_init(void)
|
int board_init(void)
|
||||||
{
|
{
|
||||||
epd_dev = device_get_binding(DT_INST_0_SOLOMON_SSD1673FB_LABEL);
|
epd_dev = device_get_binding(DT_INST_0_SOLOMON_SSD16XXFB_LABEL);
|
||||||
if (epd_dev == NULL) {
|
if (epd_dev == NULL) {
|
||||||
printk("SSD1673 device not found\n");
|
printk("SSD16XX device not found\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_SSD1673=y
|
CONFIG_SSD16XX=y
|
||||||
|
|
|
@ -7,5 +7,5 @@ sample:
|
||||||
tests:
|
tests:
|
||||||
sample.display.cfb.ssd1306:
|
sample.display.cfb.ssd1306:
|
||||||
platform_whitelist: frdm_k64f
|
platform_whitelist: frdm_k64f
|
||||||
sample.display.cfb.ssd1673:
|
sample.display.cfb.ssd16xx:
|
||||||
platform_whitelist: reel_board
|
platform_whitelist: reel_board
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
#include <display/cfb.h>
|
#include <display/cfb.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined(CONFIG_SSD1673)
|
#if defined(CONFIG_SSD16XX)
|
||||||
#define DISPLAY_DRIVER "SSD1673"
|
#define DISPLAY_DRIVER "SSD16XX"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_SSD1306)
|
#if defined(CONFIG_SSD1306)
|
||||||
|
|
|
@ -25,11 +25,11 @@ directory:
|
||||||
Generic config file, normally you should use this.
|
Generic config file, normally you should use this.
|
||||||
|
|
||||||
- :file:`boards/reel_board.conf`
|
- :file:`boards/reel_board.conf`
|
||||||
This overlay config enables support for SSD1673 display controller
|
This overlay config enables support for SSD16XX display controller
|
||||||
on the reel_board.
|
on the reel_board.
|
||||||
|
|
||||||
|
|
||||||
Example building for the reel_board with SSD1673 display support:
|
Example building for the reel_board with SSD16XX display support:
|
||||||
|
|
||||||
.. zephyr-app-commands::
|
.. zephyr-app-commands::
|
||||||
:zephyr-app: samples/display/cfb_custom_font
|
:zephyr-app: samples/display/cfb_custom_font
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_SSD1673=y
|
CONFIG_SSD16XX=y
|
||||||
|
|
|
@ -5,5 +5,5 @@ sample:
|
||||||
description: Custom character framebuffer font example
|
description: Custom character framebuffer font example
|
||||||
name: cfb custom font sample
|
name: cfb custom font sample
|
||||||
tests:
|
tests:
|
||||||
sample.display.cfb_custom_font.ssd1673:
|
sample.display.cfb_custom_font.ssd16xx:
|
||||||
platform_whitelist: reel_board
|
platform_whitelist: reel_board
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
#include "cfb_font_dice.h"
|
#include "cfb_font_dice.h"
|
||||||
|
|
||||||
#if defined(CONFIG_SSD1673)
|
#if defined(CONFIG_SSD16XX)
|
||||||
#define DISPLAY_DRIVER "SSD1673"
|
#define DISPLAY_DRIVER "SSD16XX"
|
||||||
#else
|
#else
|
||||||
#error Unsupported board
|
#error Unsupported board
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -46,7 +46,7 @@ Command example (reel_board):
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
uart:~$ cfb init
|
uart:~$ cfb init
|
||||||
Framebuffer initialized: SSD1673
|
Framebuffer initialized: SSD16XX
|
||||||
Display Cleared
|
Display Cleared
|
||||||
|
|
||||||
**get_device**: prints the display device name.
|
**get_device**: prints the display device name.
|
||||||
|
@ -56,7 +56,7 @@ Command example (reel_board):
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
uart:~$ cfb get_device
|
uart:~$ cfb get_device
|
||||||
Framebuffer Device: SSD1673
|
Framebuffer Device: SSD16XX
|
||||||
|
|
||||||
**get_param**: get the display parameters where height, width and ppt
|
**get_param**: get the display parameters where height, width and ppt
|
||||||
(pixel per tile) are in pixels and the number of rows and columns. The row
|
(pixel per tile) are in pixels and the number of rows and columns. The row
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_SSD1673=y
|
CONFIG_SSD16XX=y
|
||||||
|
|
|
@ -7,5 +7,5 @@ sample:
|
||||||
tests:
|
tests:
|
||||||
sample.display.cfb_shell.ssd1306:
|
sample.display.cfb_shell.ssd1306:
|
||||||
platform_whitelist: frdm_k64f
|
platform_whitelist: frdm_k64f
|
||||||
sample.display.cfb_shell.ssd1673:
|
sample.display.cfb_shell.ssd16xx:
|
||||||
platform_whitelist: reel_board
|
platform_whitelist: reel_board
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_SSD1673=y
|
CONFIG_SSD16XX=y
|
||||||
|
|
||||||
CONFIG_LVGL_COLOR_DEPTH_1=y
|
CONFIG_LVGL_COLOR_DEPTH_1=y
|
||||||
CONFIG_LVGL_BITS_PER_PIXEL=1
|
CONFIG_LVGL_BITS_PER_PIXEL=1
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
&spi3 {
|
&spi3 {
|
||||||
ssd1673fb@0 {
|
ssd16xxfb@0 {
|
||||||
label = "DISPLAY";
|
label = "DISPLAY";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,7 @@ config CHARACTER_FRAMEBUFFER_SHELL
|
||||||
if CHARACTER_FRAMEBUFFER_SHELL
|
if CHARACTER_FRAMEBUFFER_SHELL
|
||||||
config CHARACTER_FRAMEBUFFER_SHELL_DRIVER_NAME
|
config CHARACTER_FRAMEBUFFER_SHELL_DRIVER_NAME
|
||||||
string
|
string
|
||||||
default "SSD1673" if SSD1673
|
default "SSD16XX" if SSD16XX
|
||||||
default "SSD1306" if SSD1306
|
default "SSD1306" if SSD1306
|
||||||
help
|
help
|
||||||
Character Framebuffer Display Driver Name
|
Character Framebuffer Display Driver Name
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue