Commit cbec4753 authored by Greter Raffael's avatar Greter Raffael Committed by Alberto Escolar
Browse files

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: default avatarGreter Raffael <rgreter@baumer.com>
parent 19610233
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -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");

	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));
+2 −0
Original line number Diff line number Diff line
@@ -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