Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for SSD1322 OLED display driver #68608

Closed
wants to merge 1 commit into from

Conversation

hlukasz
Copy link
Contributor

@hlukasz hlukasz commented Feb 6, 2024

Initial support for SSD1322 OLED display driver. Only 1 bit color mode is supported. It it inspired by existing driver for SSD1306. Tested on 3.2 inch 256x64 module (https://www.buydisplay.com/white-3-2-inch-arduino-raspberry-pi-oled-display-module-256x64-spi)

@zephyrbot zephyrbot added area: Devicetree Binding PR modifies or adds a Device Tree binding area: Display labels Feb 6, 2024
@hlukasz hlukasz force-pushed the ssd1322_driver branch 3 times, most recently from 67f53dc to 1153b68 Compare February 6, 2024 12:39
uint16_t column_offset;
};

static inline int ssd1322_write_bus(const struct device *dev, uint8_t *buf, size_t len, bool cmd)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This display looks like it could use the new MIPI DBI API. Shouldn't be too hard to transition (mostly just need to update this function and the display_write implementation)

Can you investigate if this is possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is possible. Thank you for pointing this out, I didn't notice that there is a dedicated interface for that. I have switched to MIPI-DBI in current version.

drivers/display/ssd1322.c Show resolved Hide resolved
return 0;
}

static int ssd1322_read(const struct device *dev, const uint16_t x,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These stub functions can be dropped, see 0096a98

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (gpio_pin_set_dt(&config->reset, 1) < 0) {
return -1;
}
k_sleep(K_MSEC(10));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datasheet claims the delays needed here are 100us each, any reason for the long waits?

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason, that values was copied from some sample driver I have found. Now they are reduced to values from the datasheet.

{
const struct ssd1322_config *config = dev->config;

if (gpio_pin_set_dt(&config->reset, 1) < 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't return an arbitrary value here. Propigate the return value from the GPIO API, like so:

ret = gpio_pin_set_dt;
if (ret < 0) {
   return ret;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Changed also in few other places.

uint8_t cmd, data[2];

cmd = SSD1322_DISPLAY_OFF;
ret |= ssd1322_write_bus(dev, &cmd, sizeof(cmd), true);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the idea here, but I think we should be checking ret after each call, and returning if there is an error. This implementation will be more challenging to debug, since you won't know where something failed without stepping through with a debugger and watching the value of ret

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

const struct ssd1322_config *config = dev->config;
struct display_buffer_descriptor mipi_desc;

mipi_desc.buf_size = len;
Copy link
Collaborator

@danieldegrasse danieldegrasse Feb 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should propagate the height and width for the display buffer descriptor here as well- some controllers depend on these values being set to determine how much data to send.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the 1 bit -> 4bit conversion and sending data in chunks I cannot propagate width and height that I am receiving from upper layer. I hope that current solution will be acceptable :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be ok. Any MIPI controller that relies on the height and width will likely not work with this solution, but truthfully given that we are also lying to the controller about the true format of the pixel data (IE that each pixel is a nibble, not a bit), controllers of this style probably won't work either way.

size_t buf_len;
int ret;

if (desc->pitch < desc->width) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a check to verify the buf_size field in the display_buffer_descriptor is sufficient for the provided height and width- this will provide more robust defense against reading out of bounds in the buffer the application provides

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please look few lines below:

buf_len = MIN(desc->buf_size, desc->height * desc->width / 8);

I think that this should protect us from out of bounds access to the buffer, what do you think? Reading is limited either to buf_size, or to height and width.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that will be fine- sorry for missing that check.

properties:
column_offset:
type: int
description: First visible column number, default 0.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a default value, should we add default key here so that the user does not have to specify column_offset = <0>?

Also:

  • Please add a justification for the default. Can be as simple as "reset setting for the controller" if this is the case
  • property names should be styled like "column-offset"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have rethought that and providing a default value here maybe is not the best option. I guess that this value is different for each display model, so there is not a default one. I have change this property to be required.

@hlukasz hlukasz force-pushed the ssd1322_driver branch 2 times, most recently from 3ec74db to d745d02 Compare March 27, 2024 20:39
@hlukasz hlukasz requested a review from danieldegrasse March 27, 2024 21:02
Initial support for SSD1322 OLED display driver. Only 1 bit color mode is
supported.

Signed-off-by: Lukasz Hawrylko <lukasz@hawrylko.pl>
size_t buf_len;
int ret;

if (desc->pitch < desc->width) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that will be fine- sorry for missing that check.

Copy link

github-actions bot commented Jun 1, 2024

This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.

@danieldegrasse
Copy link
Collaborator

@jfischer-no could you provide feedback on this PR to move it forwards?

@kartben
Copy link
Collaborator

kartben commented Aug 10, 2024

ping @jfischer-no

Comment on lines +10 to +28
#define SSD1322_SET_COLUMN_ADDR 0x15
#define SSD1322_ENABLE_RAM_WRITE 0x5C
#define SSD1322_SET_ROW_ADDR 0x75
#define SSD1322_SET_REMAP 0xA0
#define SSD1322_BLANKING_ON 0xA4
#define SSD1322_BLANKING_OFF 0xA6
#define SSD1322_EXIT_PARTIAL 0xA9
#define SSD1322_DISPLAY_OFF 0xAE
#define SSD1322_DISPLAY_ON 0xAF
#define SSD1322_SET_PHASE_LENGTH 0xB1
#define SSD1322_SET_CLOCK_DIV 0xB3
#define SSD1322_SET_GPIO 0xB5
#define SSD1322_SET_SECOND_PRECHARGE 0xB6
#define SSD1322_DEFAULT_GREYSCALE 0xB9
#define SSD1322_SET_PRECHARGE 0xBB
#define SSD1322_SET_VCOMH 0xBE
#define SSD1322_SET_CONTRAST 0xC1
#define SSD1322_SET_MUX_RATIO 0xCA
#define SSD1322_COMMAND_LOCK 0xFD
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

19 lines could be moved to ssd1322.c


if (desc->pitch < desc->width) {
LOG_ERR("Pitch is smaller than width");
return -1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

		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);

uint8_t cmd_data[2];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable definition should be at the top of a block.

uint8_t cmd_data[2];

cmd_data[0] = config->column_offset + (x >> 2);
cmd_data[1] = config->column_offset + (((x + desc->width) >> 2) - 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmd_data[1] = config->column_offset + ((x + desc->width) >> 2) - 1;

}

cmd_data[0] = y;
cmd_data[1] = (y + desc->height - 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acute overparenthesesis.

cmd_data[1] = y + desc->height - 1;

return ret;
}

uint8_t *buff_ptr = (uint8_t *)buf;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buf is a buffer pointer, maybe data_ptr is better. You do not need explicit conversion here. Variable definition should be at the top of a block.

Comment on lines +127 to +132
}
ret = ssd1322_write_data(dev, pixel_buff, sizeof(pixel_buff));
if (ret < 0) {
return ret;
}
buff_ptr++;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

		}

		ret = ssd1322_write_data(dev, pixel_buff, sizeof(pixel_buff));
		if (ret < 0) {
			return ret;
		}

		buff_ptr++;

}

int ret = ssd1322_init_device(dev);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove this empty line.

Copy link

This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.

@github-actions github-actions bot added the Stale label Oct 16, 2024
@github-actions github-actions bot closed this Oct 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Devicetree Binding PR modifies or adds a Device Tree binding area: Display Stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants