drivers: display: ssd1306: Invert colors at runtime

This allows to invert the display at runtime using the function
`ssd1306_set_pixel_format`. The current format is stored in the data
struct.

Also adjusted `ssd1306_get_capabilities` to return both supported
formats and the current one.

From the ssd1306 doc: 'In normal display a RAM data of 1 indicates an
"ON" pixel while in inverse display a RAM data of 0 indicates an "ON"
pixel.' Thus `PIXEL_FORMAT_MONO01 == SSD1306_SET_NORMAL_DISPLAY`.

Signed-off-by: Greter Raffael <rgreter@baumer.com>
This commit is contained in:
Greter Raffael 2024-02-02 13:33:06 +00:00 committed by Alberto Escolar
parent 19610233e2
commit cbec4753e1
2 changed files with 33 additions and 5 deletions

View file

@ -62,6 +62,7 @@ struct ssd1306_config {
struct ssd1306_data {
uint8_t contrast;
uint8_t scan_mode;
enum display_pixel_format pf;
};
#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, i2c) || \
@ -332,27 +333,50 @@ static void ssd1306_get_capabilities(const struct device *dev,
struct display_capabilities *caps)
{
const struct ssd1306_config *config = dev->config;
struct ssd1306_data *data = dev->data;
memset(caps, 0, sizeof(struct display_capabilities));
caps->x_resolution = config->width;
caps->y_resolution = config->height;
caps->supported_pixel_formats = PIXEL_FORMAT_MONO10;
caps->current_pixel_format = PIXEL_FORMAT_MONO10;
caps->supported_pixel_formats = PIXEL_FORMAT_MONO10 | PIXEL_FORMAT_MONO01;
caps->current_pixel_format = data->pf;
caps->screen_info = SCREEN_INFO_MONO_VTILED;
}
static int ssd1306_set_pixel_format(const struct device *dev,
const enum display_pixel_format pf)
{
if (pf == PIXEL_FORMAT_MONO10) {
struct ssd1306_data *data = dev->data;
uint8_t cmd;
int ret;
if (pf == data->pf) {
return 0;
}
LOG_ERR("Unsupported");
return -ENOTSUP;
if (pf == PIXEL_FORMAT_MONO10) {
cmd = SSD1306_SET_REVERSE_DISPLAY;
} else if (pf == PIXEL_FORMAT_MONO01) {
cmd = SSD1306_SET_NORMAL_DISPLAY;
} else {
LOG_WRN("Unsupported pixel format");
return -ENOTSUP;
}
ret = ssd1306_write_bus(dev, &cmd, 1, true);
if (ret) {
return ret;
}
data->pf = pf;
return 0;
}
static int ssd1306_init_device(const struct device *dev)
{
const struct ssd1306_config *config = dev->config;
struct ssd1306_data *data = dev->data;
uint8_t cmd_buf[] = {
SSD1306_SET_ENTIRE_DISPLAY_OFF,
@ -360,6 +384,8 @@ static int ssd1306_init_device(const struct device *dev)
: SSD1306_SET_NORMAL_DISPLAY),
};
data->pf = config->color_inversion ? PIXEL_FORMAT_MONO10 : PIXEL_FORMAT_MONO01;
/* Reset if pin connected */
if (config->reset.port) {
k_sleep(K_MSEC(SSD1306_RESET_DELAY));

View file

@ -28,7 +28,9 @@
#define SSD1306_SET_ENTIRE_DISPLAY_OFF 0xa4
#define SSD1306_SET_ENTIRE_DISPLAY_ON 0xa5
/* RAM data of 1 indicates an "ON" pixel */
#define SSD1306_SET_NORMAL_DISPLAY 0xa6
/* RAM data of 0 indicates an "ON" pixel */
#define SSD1306_SET_REVERSE_DISPLAY 0xa7
#define SSD1306_DISPLAY_OFF 0xae