Configuring SSD1306 shield with 64x32 pixel display.

I recently bought this display that is 64x32 pixels and uses the SSD1306 driver. When running the LVGL Basic Sample with the Zephyr ssd1306_128x64 shield, the display works, but shows only the bottom center of what would show up on the 128x64 display. Zephyr does not have a ssd1306_64x32 shield unfortunately, so I have tried changing the width and height in the devicetree like from 128->64 and from 64 ->32 like this:
nrf52dk_nrf52832.overlay:
/ {
	chosen {
		zephyr,display = &ssd1306_ssd1306_128x64;
	};
};

&arduino_i2c {
	status = "okay";

	ssd1306_ssd1306_128x64: ssd1306@3c {
		compatible = "solomon,ssd1306fb";
		reg = 0x3c;
		width = 64;
		height = 32;
		segment-offset = 0;
		page-offset = 0;
		display-offset = 0;
		multiplex-ratio = 63;
		segment-remap;
		com-invdir;
		prechargep = <x22;
	};
};
but this results in the display freezing on whatever was showing before the flash. Any ideas on what I could modify to use a 64x32 display?
Parents
  • I have found a temporary solution. In zephyr/drivers/display/ssd1306.c, change these lines:

    static int ssd1306_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)
    {
    	uint8_t cmd_buf[] = {
    		SSD1306_SET_MEM_ADDRESSING_MODE,
    		SSD1306_ADDRESSING_MODE,
    		SSD1306_SET_COLUMN_ADDRESS,
    		x,
    		(x + desc->width - 1),
    		SSD1306_SET_PAGE_ADDRESS,
    		y/8,
    		((y + desc->height)/8 - 1)
    	};

    to this:

    static int ssd1306_write_default(const struct device *dev, const uint16_t y,
    				 const struct display_buffer_descriptor *desc, const void *buf,
    				 const size_t buf_len)
    {
    	uint8_t cmd_buf[] = {
    		SSD1306_SET_MEM_ADDRESSING_MODE,
    		SSD1306_ADDRESSING_MODE,
    		SSD1306_SET_COLUMN_ADDRESS,
    		SSD1306_SET_LOWER_COL_ADDRESS,
    		SSD1306_SET_HIGHER_COL_ADDRESS,
    		SSD1306_SET_PAGE_ADDRESS,
    		y/8,
    		((y + desc->height)/8 - 1)
    	};

    Where

    SSD1306_SET_LOWER_COL_ADDRESS = 0x20
    SSD1306_SET_HIGHER_COL_ADDRESS = 0x5f

    Also, the multiplex ratio in the device tree configuration should be set to height-1, so 31.

    I am not sure where I am supposed to be able to set the "x" value in the ssd1306_write_default() function. This would allow me to configure the display without needing to modify the zephyr source files.

Reply
  • I have found a temporary solution. In zephyr/drivers/display/ssd1306.c, change these lines:

    static int ssd1306_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)
    {
    	uint8_t cmd_buf[] = {
    		SSD1306_SET_MEM_ADDRESSING_MODE,
    		SSD1306_ADDRESSING_MODE,
    		SSD1306_SET_COLUMN_ADDRESS,
    		x,
    		(x + desc->width - 1),
    		SSD1306_SET_PAGE_ADDRESS,
    		y/8,
    		((y + desc->height)/8 - 1)
    	};

    to this:

    static int ssd1306_write_default(const struct device *dev, const uint16_t y,
    				 const struct display_buffer_descriptor *desc, const void *buf,
    				 const size_t buf_len)
    {
    	uint8_t cmd_buf[] = {
    		SSD1306_SET_MEM_ADDRESSING_MODE,
    		SSD1306_ADDRESSING_MODE,
    		SSD1306_SET_COLUMN_ADDRESS,
    		SSD1306_SET_LOWER_COL_ADDRESS,
    		SSD1306_SET_HIGHER_COL_ADDRESS,
    		SSD1306_SET_PAGE_ADDRESS,
    		y/8,
    		((y + desc->height)/8 - 1)
    	};

    Where

    SSD1306_SET_LOWER_COL_ADDRESS = 0x20
    SSD1306_SET_HIGHER_COL_ADDRESS = 0x5f

    Also, the multiplex ratio in the device tree configuration should be set to height-1, so 31.

    I am not sure where I am supposed to be able to set the "x" value in the ssd1306_write_default() function. This would allow me to configure the display without needing to modify the zephyr source files.

Children
Related