Bläddra i källkod

Fix oled_render to render all dirty blocks. (#18887)

Richard Nash 2 år sedan
förälder
incheckning
4c1d8a0eb3
1 ändrade filer med 44 tillägg och 46 borttagningar
  1. 44 46
      drivers/oled/ssd1306_sh1106.c

+ 44 - 46
drivers/oled/ssd1306_sh1106.c

@@ -291,65 +291,63 @@ static void rotate_90(const uint8_t *src, uint8_t *dest) {
 }
 
 void oled_render(void) {
-    if (!oled_initialized) {
-        return;
-    }
-
     // Do we have work to do?
     oled_dirty &= OLED_ALL_BLOCKS_MASK;
-    if (!oled_dirty || oled_scrolling) {
+    if (!oled_dirty || !oled_initialized || oled_scrolling) {
         return;
     }
 
-    // Find first dirty block
-    uint8_t update_start = 0;
-    while (!(oled_dirty & ((OLED_BLOCK_TYPE)1 << update_start))) {
-        ++update_start;
-    }
-
-    // Set column & page position
-    static uint8_t display_start[] = {I2C_CMD, COLUMN_ADDR, 0, OLED_DISPLAY_WIDTH - 1, PAGE_ADDR, 0, OLED_DISPLAY_HEIGHT / 8 - 1};
-    if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
-        calc_bounds(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
-    } else {
-        calc_bounds_90(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
-    }
-
-    // Send column & page position
-    if (I2C_TRANSMIT(display_start) != I2C_STATUS_SUCCESS) {
-        print("oled_render offset command failed\n");
-        return;
-    }
+    // Turn on display if it is off
+    oled_on();
 
-    if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
-        // Send render data chunk as is
-        if (I2C_WRITE_REG(I2C_DATA, &oled_buffer[OLED_BLOCK_SIZE * update_start], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) {
-            print("oled_render data failed\n");
-            return;
+    uint8_t update_start = 0;
+    while (oled_dirty) { // render all dirty blocks
+        // Find next dirty block
+        while (!(oled_dirty & ((OLED_BLOCK_TYPE)1 << update_start))) {
+            ++update_start;
         }
-    } else {
-        // Rotate the render chunks
-        const static uint8_t source_map[] = OLED_SOURCE_MAP;
-        const static uint8_t target_map[] = OLED_TARGET_MAP;
-
-        static uint8_t temp_buffer[OLED_BLOCK_SIZE];
-        memset(temp_buffer, 0, sizeof(temp_buffer));
-        for (uint8_t i = 0; i < sizeof(source_map); ++i) {
-            rotate_90(&oled_buffer[OLED_BLOCK_SIZE * update_start + source_map[i]], &temp_buffer[target_map[i]]);
+
+        // Set column & page position
+        static uint8_t display_start[] = {I2C_CMD, COLUMN_ADDR, 0, OLED_DISPLAY_WIDTH - 1, PAGE_ADDR, 0, OLED_DISPLAY_HEIGHT / 8 - 1};
+        if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
+            calc_bounds(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
+        } else {
+            calc_bounds_90(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
         }
 
-        // Send render data chunk after rotating
-        if (I2C_WRITE_REG(I2C_DATA, &temp_buffer[0], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) {
-            print("oled_render90 data failed\n");
+        // Send column & page position
+        if (I2C_TRANSMIT(display_start) != I2C_STATUS_SUCCESS) {
+            print("oled_render offset command failed\n");
             return;
         }
-    }
 
-    // Turn on display if it is off
-    oled_on();
+        if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
+            // Send render data chunk as is
+            if (I2C_WRITE_REG(I2C_DATA, &oled_buffer[OLED_BLOCK_SIZE * update_start], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) {
+                print("oled_render data failed\n");
+                return;
+            }
+        } else {
+            // Rotate the render chunks
+            const static uint8_t source_map[] = OLED_SOURCE_MAP;
+            const static uint8_t target_map[] = OLED_TARGET_MAP;
+
+            static uint8_t temp_buffer[OLED_BLOCK_SIZE];
+            memset(temp_buffer, 0, sizeof(temp_buffer));
+            for (uint8_t i = 0; i < sizeof(source_map); ++i) {
+                rotate_90(&oled_buffer[OLED_BLOCK_SIZE * update_start + source_map[i]], &temp_buffer[target_map[i]]);
+            }
 
-    // Clear dirty flag
-    oled_dirty &= ~((OLED_BLOCK_TYPE)1 << update_start);
+            // Send render data chunk after rotating
+            if (I2C_WRITE_REG(I2C_DATA, &temp_buffer[0], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) {
+                print("oled_render90 data failed\n");
+                return;
+            }
+        }
+
+        // Clear dirty flag of just rendered block
+        oled_dirty &= ~((OLED_BLOCK_TYPE)1 << update_start);
+    }
 }
 
 void oled_set_cursor(uint8_t col, uint8_t line) {