mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-11-04 07:12:33 +01:00 
			
		
		
		
	Fix oled_render to render all dirty blocks. (#18887)
This commit is contained in:
		
							parent
							
								
									81bf60a636
								
							
						
					
					
						commit
						4c1d8a0eb3
					
				@ -291,65 +291,63 @@ static void rotate_90(const uint8_t *src, uint8_t *dest) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void oled_render(void) {
 | 
					void oled_render(void) {
 | 
				
			||||||
    if (!oled_initialized) {
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Do we have work to do?
 | 
					    // Do we have work to do?
 | 
				
			||||||
    oled_dirty &= OLED_ALL_BLOCKS_MASK;
 | 
					    oled_dirty &= OLED_ALL_BLOCKS_MASK;
 | 
				
			||||||
    if (!oled_dirty || oled_scrolling) {
 | 
					    if (!oled_dirty || !oled_initialized || oled_scrolling) {
 | 
				
			||||||
        return;
 | 
					        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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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]]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 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;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Turn on display if it is off
 | 
					    // Turn on display if it is off
 | 
				
			||||||
    oled_on();
 | 
					    oled_on();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Clear dirty flag
 | 
					    uint8_t update_start = 0;
 | 
				
			||||||
    oled_dirty &= ~((OLED_BLOCK_TYPE)1 << update_start);
 | 
					    while (oled_dirty) { // render all dirty blocks
 | 
				
			||||||
 | 
					        // Find next dirty block
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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]]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 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) {
 | 
					void oled_set_cursor(uint8_t col, uint8_t line) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user