drivers: display: Introduce Sitronix ST7567
Introduces a driver for the Sitronix ST7567 132x65 LCD driver. Signed-off-by: Camille BAUD <mail@massdriver.space>
This commit is contained in:
parent
46829bbe6b
commit
3334a8e9cd
@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_SSD1306 ssd1306.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SSD1327 ssd1327.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SSD16XX ssd16xx.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SSD1322 ssd1322.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ST7567 display_st7567.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ST7789V display_st7789v.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ST7735R display_st7735r.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ST7796S display_st7796s.c)
|
||||
|
||||
@ -30,6 +30,7 @@ source "drivers/display/Kconfig.ssd1306"
|
||||
source "drivers/display/Kconfig.ssd1327"
|
||||
source "drivers/display/Kconfig.ssd16xx"
|
||||
source "drivers/display/Kconfig.ssd1322"
|
||||
source "drivers/display/Kconfig.st7567"
|
||||
source "drivers/display/Kconfig.st7735r"
|
||||
source "drivers/display/Kconfig.st7789v"
|
||||
source "drivers/display/Kconfig.st7796s"
|
||||
|
||||
22
drivers/display/Kconfig.st7567
Normal file
22
drivers/display/Kconfig.st7567
Normal file
@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig ST7567
|
||||
bool "ST7567 display controller"
|
||||
default y
|
||||
depends on DT_HAS_SITRONIX_ST7567_ENABLED
|
||||
select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SITRONIX_ST7567),i2c)
|
||||
select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SITRONIX_ST7567),spi)
|
||||
help
|
||||
Enable driver for ST7567 display controller.
|
||||
|
||||
if ST7567
|
||||
|
||||
config ST7567_DEFAULT_CONTRAST
|
||||
int "ST7567 default contrast"
|
||||
default 8
|
||||
range 0 15
|
||||
help
|
||||
ST7567 default contrast.
|
||||
|
||||
endif # ST7567
|
||||
491
drivers/display/display_st7567.c
Normal file
491
drivers/display/display_st7567.c
Normal file
@ -0,0 +1,491 @@
|
||||
/*
|
||||
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(display_st7567, CONFIG_DISPLAY_LOG_LEVEL);
|
||||
|
||||
#include <string.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/drivers/display.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include "display_st7567_regs.h"
|
||||
|
||||
union st7567_bus {
|
||||
struct i2c_dt_spec i2c;
|
||||
struct spi_dt_spec spi;
|
||||
};
|
||||
|
||||
typedef bool (*st7567_bus_ready_fn)(const struct device *dev);
|
||||
typedef int (*st7567_write_bus_fn)(const struct device *dev, uint8_t *buf, size_t len,
|
||||
bool command);
|
||||
typedef const char *(*st7567_bus_name_fn)(const struct device *dev);
|
||||
|
||||
struct st7567_config {
|
||||
union st7567_bus bus;
|
||||
struct gpio_dt_spec data_cmd;
|
||||
struct gpio_dt_spec reset;
|
||||
st7567_bus_ready_fn bus_ready;
|
||||
st7567_write_bus_fn write_bus;
|
||||
st7567_bus_name_fn bus_name;
|
||||
uint16_t height;
|
||||
uint16_t width;
|
||||
uint8_t column_offset;
|
||||
uint8_t line_offset;
|
||||
uint8_t regulation_ratio;
|
||||
bool com_invdir;
|
||||
bool segment_invdir;
|
||||
bool inversion_on;
|
||||
bool bias;
|
||||
};
|
||||
|
||||
struct st7567_data {
|
||||
enum display_pixel_format pf;
|
||||
};
|
||||
|
||||
#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sitronix_st7567, i2c)
|
||||
|
||||
static bool st7567_bus_ready_i2c(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
|
||||
return i2c_is_ready_dt(&config->bus.i2c);
|
||||
}
|
||||
|
||||
static int st7567_write_bus_i2c(const struct device *dev, uint8_t *buf, size_t len, bool command)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
|
||||
return i2c_burst_write_dt(
|
||||
&config->bus.i2c,
|
||||
command ? ST7567_CONTROL_ALL_BYTES_CMD : ST7567_CONTROL_ALL_BYTES_DATA, buf, len);
|
||||
}
|
||||
|
||||
static const char *st7567_bus_name_i2c(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
|
||||
return config->bus.i2c.bus->name;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sitronix_st7567, spi)
|
||||
|
||||
static bool st7567_bus_ready_spi(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
|
||||
if (gpio_pin_configure_dt(&config->data_cmd, GPIO_OUTPUT_INACTIVE) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return spi_is_ready_dt(&config->bus.spi);
|
||||
}
|
||||
|
||||
static int st7567_write_bus_spi(const struct device *dev, uint8_t *buf, size_t len, bool command)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
int ret;
|
||||
|
||||
gpio_pin_set_dt(&config->data_cmd, command ? 0 : 1);
|
||||
struct spi_buf tx_buf = {.buf = buf, .len = len};
|
||||
|
||||
struct spi_buf_set tx_bufs = {.buffers = &tx_buf, .count = 1};
|
||||
|
||||
ret = spi_write_dt(&config->bus.spi, &tx_bufs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *st7567_bus_name_spi(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
|
||||
return config->bus.spi.bus->name;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline bool st7567_bus_ready(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
|
||||
return config->bus_ready(dev);
|
||||
}
|
||||
|
||||
static inline int st7567_write_bus(const struct device *dev, uint8_t *buf, size_t len, bool command)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
|
||||
return config->write_bus(dev, buf, len, command);
|
||||
}
|
||||
|
||||
static inline int st7567_set_panel_orientation(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
uint8_t cmd_buf[] = {(config->segment_invdir ? ST7567_SET_SEGMENT_MAP_FLIPPED
|
||||
: ST7567_SET_SEGMENT_MAP_NORMAL),
|
||||
(config->com_invdir ? ST7567_SET_COM_OUTPUT_SCAN_FLIPPED
|
||||
: ST7567_SET_COM_OUTPUT_SCAN_NORMAL)};
|
||||
|
||||
return st7567_write_bus(dev, cmd_buf, sizeof(cmd_buf), true);
|
||||
}
|
||||
|
||||
static inline int st7567_set_hardware_config(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
int ret;
|
||||
uint8_t cmd_buf[1];
|
||||
|
||||
cmd_buf[0] = ST7567_SET_BIAS | (config->bias ? 1 : 0);
|
||||
ret = st7567_write_bus(dev, cmd_buf, 1, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmd_buf[0] = ST7567_POWER_CONTROL | ST7567_POWER_CONTROL_VB;
|
||||
ret = st7567_write_bus(dev, cmd_buf, 1, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmd_buf[0] = ST7567_POWER_CONTROL | ST7567_POWER_CONTROL_VB | ST7567_POWER_CONTROL_VR;
|
||||
ret = st7567_write_bus(dev, cmd_buf, 1, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmd_buf[0] = ST7567_POWER_CONTROL | ST7567_POWER_CONTROL_VB | ST7567_POWER_CONTROL_VR |
|
||||
ST7567_POWER_CONTROL_VF;
|
||||
ret = st7567_write_bus(dev, cmd_buf, 1, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmd_buf[0] = ST7567_SET_REGULATION_RATIO | (config->regulation_ratio & 0x7);
|
||||
ret = st7567_write_bus(dev, cmd_buf, 1, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmd_buf[0] = ST7567_LINE_SCROLL | (config->line_offset & 0x3F);
|
||||
ret = st7567_write_bus(dev, cmd_buf, 1, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int st7567_resume(const struct device *dev)
|
||||
{
|
||||
uint8_t cmd_buf[] = {
|
||||
ST7567_DISPLAY_ALL_PIXEL_NORMAL,
|
||||
ST7567_DISPLAY_ON,
|
||||
};
|
||||
|
||||
return st7567_write_bus(dev, cmd_buf, sizeof(cmd_buf), true);
|
||||
}
|
||||
|
||||
static int st7567_suspend(const struct device *dev)
|
||||
{
|
||||
uint8_t cmd_buf[] = {
|
||||
ST7567_DISPLAY_OFF,
|
||||
ST7567_DISPLAY_ALL_PIXEL_ON,
|
||||
};
|
||||
|
||||
return st7567_write_bus(dev, cmd_buf, sizeof(cmd_buf), true);
|
||||
}
|
||||
|
||||
static int st7567_write_default(const struct device *dev, const uint16_t x, const uint16_t y,
|
||||
const struct display_buffer_descriptor *desc, const void *buf,
|
||||
const size_t buf_len)
|
||||
{
|
||||
int ret;
|
||||
uint8_t cmd_buf[3];
|
||||
|
||||
for (int i = 0; i < desc->height / 8; i++) {
|
||||
cmd_buf[0] = ST7567_COLUMN_LSB | (x & 0xF);
|
||||
cmd_buf[1] = ST7567_COLUMN_MSB | ((x >> 4) & 0xF);
|
||||
cmd_buf[2] = ST7567_PAGE | ((y >> 3) + i);
|
||||
ret = st7567_write_bus(dev, cmd_buf, sizeof(cmd_buf), true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = st7567_write_bus(dev, ((uint8_t *)buf + i * desc->pitch), desc->pitch, false);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int st7567_write(const struct device *dev, const uint16_t x, const uint16_t y,
|
||||
const struct display_buffer_descriptor *desc, const void *buf)
|
||||
{
|
||||
size_t buf_len;
|
||||
|
||||
if (desc->pitch < desc->width) {
|
||||
LOG_ERR("Pitch is smaller than width");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf_len = MIN(desc->buf_size, desc->height * desc->width / 8);
|
||||
if (buf == NULL || buf_len == 0U) {
|
||||
LOG_ERR("Display buffer is not available");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (desc->pitch > desc->width) {
|
||||
LOG_ERR("Unsupported mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((y & 0x7) != 0U) {
|
||||
LOG_ERR("Y coordinate must be aligned on page boundary");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", x, y, desc->pitch,
|
||||
desc->width, desc->height, buf_len);
|
||||
|
||||
return st7567_write_default(dev, x, y, desc, buf, buf_len);
|
||||
}
|
||||
|
||||
static int st7567_set_contrast(const struct device *dev, const uint8_t contrast)
|
||||
{
|
||||
uint8_t cmd_buf[] = {
|
||||
ST7567_SET_CONTRAST_CTRL,
|
||||
contrast,
|
||||
};
|
||||
|
||||
return st7567_write_bus(dev, cmd_buf, sizeof(cmd_buf), true);
|
||||
}
|
||||
|
||||
static void st7567_get_capabilities(const struct device *dev, struct display_capabilities *caps)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
struct st7567_data *data = dev->data;
|
||||
|
||||
caps->x_resolution = config->width;
|
||||
caps->y_resolution = config->height;
|
||||
caps->supported_pixel_formats = PIXEL_FORMAT_MONO10 | PIXEL_FORMAT_MONO01;
|
||||
caps->current_pixel_format = data->pf;
|
||||
caps->screen_info = SCREEN_INFO_MONO_VTILED;
|
||||
caps->current_orientation = DISPLAY_ORIENTATION_NORMAL;
|
||||
}
|
||||
|
||||
static int st7567_set_pixel_format(const struct device *dev, const enum display_pixel_format pf)
|
||||
{
|
||||
struct st7567_data *data = dev->data;
|
||||
const struct st7567_config *config = dev->config;
|
||||
uint8_t cmd;
|
||||
int ret;
|
||||
|
||||
if (pf == data->pf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pf == PIXEL_FORMAT_MONO10) {
|
||||
cmd = config->inversion_on ? ST7567_SET_REVERSE_DISPLAY : ST7567_SET_NORMAL_DISPLAY;
|
||||
} else if (pf == PIXEL_FORMAT_MONO01) {
|
||||
cmd = config->inversion_on ? ST7567_SET_NORMAL_DISPLAY : ST7567_SET_REVERSE_DISPLAY;
|
||||
} else {
|
||||
LOG_WRN("Unsupported pixel format");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
ret = st7567_write_bus(dev, &cmd, 1, true);
|
||||
if (ret) {
|
||||
LOG_WRN("Couldn't set inversion");
|
||||
return ret;
|
||||
}
|
||||
|
||||
data->pf = pf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st7567_reset(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
uint8_t cmd_buf[] = {
|
||||
ST7567_DISPLAY_OFF,
|
||||
(config->inversion_on ? ST7567_SET_REVERSE_DISPLAY : ST7567_SET_NORMAL_DISPLAY),
|
||||
};
|
||||
|
||||
/* Reset if pin connected */
|
||||
if (config->reset.port) {
|
||||
k_sleep(K_MSEC(ST7567_RESET_DELAY));
|
||||
gpio_pin_set_dt(&config->reset, 1);
|
||||
k_sleep(K_MSEC(ST7567_RESET_DELAY));
|
||||
gpio_pin_set_dt(&config->reset, 0);
|
||||
k_sleep(K_MSEC(ST7567_RESET_DELAY));
|
||||
}
|
||||
|
||||
return st7567_write_bus(dev, cmd_buf, sizeof(cmd_buf), true);
|
||||
}
|
||||
|
||||
static int st7567_clear(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
int ret;
|
||||
uint8_t buf = 0;
|
||||
|
||||
uint8_t cmd_buf[] = {
|
||||
ST7567_COLUMN_LSB,
|
||||
ST7567_COLUMN_MSB,
|
||||
ST7567_PAGE,
|
||||
};
|
||||
|
||||
for (int y = 0; y < config->height; y += 8) {
|
||||
for (int x = 0; x < config->width; x++) {
|
||||
cmd_buf[0] = ST7567_COLUMN_LSB | (x & 0xF);
|
||||
cmd_buf[1] = ST7567_COLUMN_MSB | ((x >> 4) & 0xF);
|
||||
cmd_buf[2] = ST7567_PAGE | (y >> 3);
|
||||
ret = st7567_write_bus(dev, cmd_buf, sizeof(cmd_buf), true);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Error clearing display");
|
||||
return ret;
|
||||
}
|
||||
ret = st7567_write_bus(dev, (uint8_t *)&buf, 1, false);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Error clearing display");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int st7567_init_device(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
struct st7567_data *data = dev->data;
|
||||
int ret;
|
||||
uint8_t cmd_buf[] = {
|
||||
ST7567_DISPLAY_OFF,
|
||||
(config->inversion_on ? ST7567_SET_REVERSE_DISPLAY : ST7567_SET_NORMAL_DISPLAY),
|
||||
};
|
||||
|
||||
ret = st7567_reset(dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = st7567_suspend(dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = st7567_set_hardware_config(dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = st7567_set_panel_orientation(dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set inversion */
|
||||
ret = st7567_write_bus(dev, cmd_buf, sizeof(cmd_buf), true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
data->pf = config->inversion_on ? PIXEL_FORMAT_MONO10 : PIXEL_FORMAT_MONO01;
|
||||
|
||||
ret = st7567_set_contrast(dev, CONFIG_ST7567_DEFAULT_CONTRAST);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Clear display, RAM is undefined at power up */
|
||||
ret = st7567_clear(dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = st7567_resume(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int st7567_init(const struct device *dev)
|
||||
{
|
||||
const struct st7567_config *config = dev->config;
|
||||
int ret;
|
||||
|
||||
if (!st7567_bus_ready(dev)) {
|
||||
LOG_ERR("Bus device %s not ready!", config->bus_name(dev));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (config->reset.port) {
|
||||
ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_INACTIVE);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Couldn't configure reset pin");
|
||||
return ret;
|
||||
}
|
||||
if (!gpio_is_ready_dt(&config->reset)) {
|
||||
LOG_ERR("Reset GPIO device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (st7567_init_device(dev)) {
|
||||
LOG_ERR("Failed to initialize device!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_API(display, st7567_driver_api) = {
|
||||
.blanking_on = st7567_suspend,
|
||||
.blanking_off = st7567_resume,
|
||||
.write = st7567_write,
|
||||
.set_contrast = st7567_set_contrast,
|
||||
.get_capabilities = st7567_get_capabilities,
|
||||
.set_pixel_format = st7567_set_pixel_format,
|
||||
};
|
||||
|
||||
#define ST7567_CONFIG_SPI(node_id) \
|
||||
.bus = {.spi = SPI_DT_SPEC_GET( \
|
||||
node_id, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 0)}, \
|
||||
.bus_ready = st7567_bus_ready_spi, .write_bus = st7567_write_bus_spi, \
|
||||
.bus_name = st7567_bus_name_spi, .data_cmd = GPIO_DT_SPEC_GET(node_id, data_cmd_gpios),
|
||||
|
||||
#define ST7567_CONFIG_I2C(node_id) \
|
||||
.bus = {.i2c = I2C_DT_SPEC_GET(node_id)}, .bus_ready = st7567_bus_ready_i2c, \
|
||||
.write_bus = st7567_write_bus_i2c, .bus_name = st7567_bus_name_i2c, .data_cmd = {0},
|
||||
|
||||
#define ST7567_DEFINE(node_id) \
|
||||
static struct st7567_data data##node_id; \
|
||||
static const struct st7567_config config##node_id = { \
|
||||
.reset = GPIO_DT_SPEC_GET_OR(node_id, reset_gpios, {0}), \
|
||||
.height = DT_PROP(node_id, height), \
|
||||
.width = DT_PROP(node_id, width), \
|
||||
.column_offset = DT_PROP(node_id, column_offset), \
|
||||
.line_offset = DT_PROP(node_id, line_offset), \
|
||||
.segment_invdir = DT_PROP(node_id, segment_invdir), \
|
||||
.com_invdir = DT_PROP(node_id, com_invdir), \
|
||||
.inversion_on = DT_PROP(node_id, inversion_on), \
|
||||
.bias = DT_PROP(node_id, bias), \
|
||||
.regulation_ratio = DT_PROP(node_id, regulation_ratio), \
|
||||
COND_CODE_1(DT_ON_BUS(node_id, spi), (ST7567_CONFIG_SPI(node_id)), \
|
||||
(ST7567_CONFIG_I2C(node_id))) }; \
|
||||
\
|
||||
DEVICE_DT_DEFINE(node_id, st7567_init, NULL, &data##node_id, &config##node_id, \
|
||||
POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &st7567_driver_api);
|
||||
|
||||
DT_FOREACH_STATUS_OKAY(sitronix_st7567, ST7567_DEFINE)
|
||||
52
drivers/display/display_st7567_regs.h
Normal file
52
drivers/display/display_st7567_regs.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __DISPLAY_ST7567_REGS_H__
|
||||
#define __DISPLAY_ST7567_REGS_H__
|
||||
|
||||
/* All following bytes will contain commands */
|
||||
#define ST7567_CONTROL_ALL_BYTES_CMD 0x00
|
||||
/* All following bytes will contain data */
|
||||
#define ST7567_CONTROL_ALL_BYTES_DATA 0x40
|
||||
/* The next byte will contain a command, then expect another control byte */
|
||||
#define ST7567_CONTROL_CONTINUE_BYTE_CMD 0x80
|
||||
|
||||
#define ST7567_DISPLAY_OFF 0xAE
|
||||
#define ST7567_DISPLAY_ON 0xAF
|
||||
#define ST7567_DISPLAY_ALL_PIXEL_ON 0xA5
|
||||
#define ST7567_DISPLAY_ALL_PIXEL_NORMAL 0xA4
|
||||
#define ST7567_SET_CONTRAST_CTRL 0x81
|
||||
#define ST7567_SET_BIAS 0xA2
|
||||
#define ST7567_SET_REGULATION_RATIO 0x20
|
||||
|
||||
/* Inversion controls */
|
||||
#define ST7567_SET_NORMAL_DISPLAY 0xA6
|
||||
#define ST7567_SET_REVERSE_DISPLAY 0xA7
|
||||
|
||||
/* COM invdir */
|
||||
#define ST7567_SET_COM_OUTPUT_SCAN_FLIPPED 0xC8
|
||||
#define ST7567_SET_COM_OUTPUT_SCAN_NORMAL 0xC0
|
||||
|
||||
/* SEG invdir */
|
||||
#define ST7567_SET_SEGMENT_MAP_FLIPPED 0xA1
|
||||
#define ST7567_SET_SEGMENT_MAP_NORMAL 0xA0
|
||||
|
||||
/* Power Control */
|
||||
#define ST7567_POWER_CONTROL 0x28
|
||||
#define ST7567_POWER_CONTROL_VF 0x1
|
||||
#define ST7567_POWER_CONTROL_VR 0x2
|
||||
#define ST7567_POWER_CONTROL_VB 0x4
|
||||
|
||||
/* Offsets */
|
||||
#define ST7567_COLUMN_MSB 0x10
|
||||
#define ST7567_COLUMN_LSB 0x0
|
||||
#define ST7567_PAGE 0xB0
|
||||
#define ST7567_LINE_SCROLL 0x40
|
||||
|
||||
#define ST7567_RESET_DELAY 1
|
||||
#define ST7567_RESET 0xE2
|
||||
|
||||
#endif /* __DISPLAY_ST7567_REGS_H__ */
|
||||
44
dts/bindings/display/sitronix,st7567-common.yaml
Normal file
44
dts/bindings/display/sitronix,st7567-common.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
# Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
include: display-controller.yaml
|
||||
|
||||
properties:
|
||||
column-offset:
|
||||
type: int
|
||||
required: true
|
||||
description: 8-bits start column address
|
||||
|
||||
line-offset:
|
||||
type: int
|
||||
required: true
|
||||
description: 6-bits start line offset
|
||||
|
||||
regulation-ratio:
|
||||
type: int
|
||||
required: true
|
||||
description: Regulation resistor ratio (3-bits RR2 RR1 RR0)
|
||||
|
||||
segment-invdir:
|
||||
type: boolean
|
||||
description: Scan direction is from last SEG output to first SEG output
|
||||
|
||||
com-invdir:
|
||||
type: boolean
|
||||
description: Scan direction is from last COM output to first COM output
|
||||
|
||||
inversion-on:
|
||||
type: boolean
|
||||
description: Invert display
|
||||
|
||||
bias:
|
||||
type: boolean
|
||||
description: Bias setting (0 for 1/9, or 1 for 1/7)
|
||||
|
||||
reset-gpios:
|
||||
type: phandle-array
|
||||
description: RESET pin.
|
||||
|
||||
The RESET pin of ST7567 is active low.
|
||||
If connected directly, the MCU pin should be configured
|
||||
as active low.
|
||||
8
dts/bindings/display/sitronix,st7567-i2c.yaml
Normal file
8
dts/bindings/display/sitronix,st7567-i2c.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: ST7567 132x65 dot-matrix LCD controller on I2C bus
|
||||
|
||||
compatible: "sitronix,st7567"
|
||||
|
||||
include: ["sitronix,st7567-common.yaml", "i2c-device.yaml"]
|
||||
14
dts/bindings/display/sitronix,st7567-spi.yaml
Normal file
14
dts/bindings/display/sitronix,st7567-spi.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: ST7567 132x65 dot-matrix LCD controller on SPI bus
|
||||
|
||||
compatible: "sitronix,st7567"
|
||||
|
||||
include: ["sitronix,st7567-common.yaml", "spi-device.yaml"]
|
||||
|
||||
properties:
|
||||
data-cmd-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: D/C# pin.
|
||||
Loading…
Reference in New Issue
Block a user