oled: make async/sync mode configurable
authorCyprien Laplace <cyprien@cypou.net>
Wed, 21 Jun 2017 00:11:45 +0000 (20:11 -0400)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 16:03:05 +0000 (17:03 +0100)
A new "async" parameter in the display structure let the user choose
between asynchronous or synchronous screen updates. This affects both
fullscreen and tiled updates.

Also only re-send the full window when needed. WARNING: this only
tracks driver updates of it...

extdrv/ssd130x_oled_driver.c
include/extdrv/ssd130x_oled_driver.h

index d7c1806..772d251 100644 (file)
@@ -265,6 +265,8 @@ int ssd130x_display_on(struct oled_display* conf)
        int ret = 0;
        uint8_t val = 0;
 
+       conf->fullscreen = 0;
+
        /* Display OFF */
        ret = ssd130x_display_power(conf, SSD130x_DISP_OFF);  /* 0xAE */
        if (ret != 0) {
@@ -319,6 +321,7 @@ int ssd130x_display_on(struct oled_display* conf)
 
 int ssd130x_send_data(struct oled_display* conf, uint8_t* start, uint16_t len)
 {
+       int (*write)(uint8_t, const void *, size_t, const void*);
        int ret = 0;
 
        /* Check that start and satrt + len are within buffer */
@@ -332,8 +335,9 @@ int ssd130x_send_data(struct oled_display* conf, uint8_t* start, uint16_t len)
        *(start - 1) = SSD130x_DATA_ONLY;
 
        /* Send data on I2C bus */
+       write = conf->async ? i2c_write_async : i2c_write;
        do {
-               ret = i2c_write(conf->bus_num, (start - 2), (2 + len), NULL);
+               ret = write(conf->bus_num, (start - 2), (2 + len), NULL);
        } while (ret == -EAGAIN);
 
        /* Restore gddram data */
@@ -349,15 +353,19 @@ int ssd130x_send_data(struct oled_display* conf, uint8_t* start, uint16_t len)
 /* Update what is really displayed */
 int ssd130x_display_full_screen(struct oled_display* conf)
 {
+       int (*write)(uint8_t, const void *, size_t, const void*);
        int ret = 0;
 
-       ret = ssd130x_set_column_address(conf, 0, 127);
-       if (ret != 0) {
-               return ret;
-       }
-       ret = ssd130x_set_page_address(conf, 0, 7);
-       if (ret != 0) {
-               return ret;
+       if (!conf->fullscreen) {
+               ret = ssd130x_set_column_address(conf, 0, 127);
+               if (ret != 0) {
+                       return ret;
+               }
+               ret = ssd130x_set_page_address(conf, 0, 7);
+               if (ret != 0) {
+                       return ret;
+               }
+               conf->fullscreen = 1;
        }
 
        /* Setup I2C transfer */
@@ -365,8 +373,9 @@ int ssd130x_display_full_screen(struct oled_display* conf)
        *(conf->gddram + 3) = SSD130x_DATA_ONLY;
 
        /* Send data on I2C bus */
+       write = conf->async ? i2c_write_async : i2c_write;
        do {
-               ret = i2c_write_async(conf->bus_num, conf->gddram + 2, 2 + GDDRAM_SIZE, NULL);
+               ret = write(conf->bus_num, conf->gddram + 2, 2 + GDDRAM_SIZE, NULL);
        } while (ret == -EAGAIN);
 
        return ret;
@@ -381,6 +390,8 @@ int ssd130x_update_tile(struct oled_display* conf, uint8_t x0, uint8_t y0)
        uint8_t* addr = conf->gddram + 4 + (y0 * 128) + x0 * 8;
        int ret = 0;
 
+       conf->fullscreen = 0;
+
        ret = ssd130x_set_column_address(conf, (x0 * 8), (((x0 + 1) * 8) - 1));
        if (ret != 0) {
                return ret;
index d3802a3..83a972b 100644 (file)
@@ -40,7 +40,10 @@ struct oled_display {
        uint8_t  read_dir;
        uint8_t  display_offset_dir;
        uint8_t  display_offset;
-  uint8_t* gddram;
+       uint8_t* gddram;
+       uint8_t  async;
+       /* internal */
+       uint8_t  fullscreen;
 };
 
 #define SSD130x_NB_LINES   64