From 02a2653a6d7402e6aaf1539309058cd05b83f59c Mon Sep 17 00:00:00 2001 From: brickbots Date: Sat, 28 Mar 2020 18:17:47 -0700 Subject: [PATCH 01/10] Adding extern and declaration --- drivers/oled/oled_driver.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/oled/oled_driver.h b/drivers/oled/oled_driver.h index 3e5a5bcabe8c..4632d91689ec 100644 --- a/drivers/oled/oled_driver.h +++ b/drivers/oled/oled_driver.h @@ -150,6 +150,9 @@ along with this program. If not, see . # endif #endif +// Moved here to enable sharing with other source files +extern uint8_t oled_buffer[OLED_MATRIX_SIZE]; + // OLED Rotation enum values are flags typedef enum { OLED_ROTATION_0 = 0, From a020be88a5b5c78838e900de790ad86790086270 Mon Sep 17 00:00:00 2001 From: brickbots Date: Fri, 24 Apr 2020 19:37:14 -0700 Subject: [PATCH 02/10] Change to mediated buffer read --- docs/feature_oled_driver.md | 3 +++ drivers/oled/oled_driver.c | 9 --------- drivers/oled/oled_driver.h | 6 +++--- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md index 772ce57bdd29..e626b67f65e2 100644 --- a/docs/feature_oled_driver.md +++ b/docs/feature_oled_driver.md @@ -238,6 +238,9 @@ void oled_write_P(const char *data, bool invert); // Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM void oled_write_ln_P(const char *data, bool invert); +// Returns a single byte of the oled buffer at index +char oled_read_raw_byte(uint16_t index); + // Writes a string to the buffer at current cursor position void oled_write_raw(const char *data, uint16_t size); diff --git a/drivers/oled/oled_driver.c b/drivers/oled/oled_driver.c index ce5c23cc40a6..cb30be96b51d 100644 --- a/drivers/oled/oled_driver.c +++ b/drivers/oled/oled_driver.c @@ -453,15 +453,6 @@ void oled_write_raw_byte(const char data, uint16_t index) { oled_dirty |= (1 << (index / OLED_BLOCK_SIZE)); } -void oled_write_raw(const char *data, uint16_t size) { - if (size > OLED_MATRIX_SIZE) size = OLED_MATRIX_SIZE; - for (uint16_t i = 0; i < size; i++) { - if (oled_buffer[i] == data[i]) continue; - oled_buffer[i] = data[i]; - oled_dirty |= (1 << (i / OLED_BLOCK_SIZE)); - } -} - #if defined(__AVR__) void oled_write_P(const char *data, bool invert) { uint8_t c = pgm_read_byte(data); diff --git a/drivers/oled/oled_driver.h b/drivers/oled/oled_driver.h index 4632d91689ec..053a62ce919d 100644 --- a/drivers/oled/oled_driver.h +++ b/drivers/oled/oled_driver.h @@ -150,9 +150,6 @@ along with this program. If not, see . # endif #endif -// Moved here to enable sharing with other source files -extern uint8_t oled_buffer[OLED_MATRIX_SIZE]; - // OLED Rotation enum values are flags typedef enum { OLED_ROTATION_0 = 0, @@ -206,6 +203,9 @@ void oled_write_ln(const char *data, bool invert); // Pans the buffer to the right (or left by passing true) by moving contents of the buffer void oled_pan(bool left); +// Returns a single byte of the oled buffer at index +char oled_read_raw_byte(uint16_t index); + void oled_write_raw(const char *data, uint16_t size); void oled_write_raw_byte(const char data, uint16_t index); From b954b50fc9a700f742ed073e71b546e5d39d866a Mon Sep 17 00:00:00 2001 From: brickbots Date: Fri, 24 Apr 2020 19:48:22 -0700 Subject: [PATCH 03/10] Adding raw byte read --- drivers/oled/oled_driver.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/oled/oled_driver.c b/drivers/oled/oled_driver.c index cb30be96b51d..67c670c241a8 100644 --- a/drivers/oled/oled_driver.c +++ b/drivers/oled/oled_driver.c @@ -446,6 +446,11 @@ void oled_pan(bool left) { oled_dirty = ~((OLED_BLOCK_TYPE)0); } +char oled_read_raw_byte(uint16_t index) { + if (index > OLED_MATRIX_SIZE) index = OLED_MATRIX_SIZE; + return oled_buffer[index]; +} + void oled_write_raw_byte(const char data, uint16_t index) { if (index > OLED_MATRIX_SIZE) index = OLED_MATRIX_SIZE; if (oled_buffer[index] == data) return; From 9848f1097982b9df8901ae368e1262ed8cd21164 Mon Sep 17 00:00:00 2001 From: brickbots Date: Fri, 24 Apr 2020 19:50:45 -0700 Subject: [PATCH 04/10] Restore write raw... D'Oh --- drivers/oled/oled_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/oled/oled_driver.c b/drivers/oled/oled_driver.c index 67c670c241a8..6c61d6ddadc3 100644 --- a/drivers/oled/oled_driver.c +++ b/drivers/oled/oled_driver.c @@ -458,6 +458,15 @@ void oled_write_raw_byte(const char data, uint16_t index) { oled_dirty |= (1 << (index / OLED_BLOCK_SIZE)); } +void oled_write_raw(const char *data, uint16_t size) { + if (size > OLED_MATRIX_SIZE) size = OLED_MATRIX_SIZE; + for (uint16_t i = 0; i < size; i++) { + if (oled_buffer[i] == data[i]) continue; + oled_buffer[i] = data[i]; + oled_dirty |= (1 << (i / OLED_BLOCK_SIZE)); + } +} + #if defined(__AVR__) void oled_write_P(const char *data, bool invert) { uint8_t c = pgm_read_byte(data); From cc30467cbbf053377e52a77f1dca87dbc5c95e08 Mon Sep 17 00:00:00 2001 From: brickbots Date: Wed, 29 Apr 2020 19:24:18 -0700 Subject: [PATCH 05/10] Working struct return --- docs/feature_oled_driver.md | 5 +++-- drivers/oled/oled_driver.c | 9 ++++++--- drivers/oled/oled_driver.h | 12 ++++++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md index e626b67f65e2..e29f356173b2 100644 --- a/docs/feature_oled_driver.md +++ b/docs/feature_oled_driver.md @@ -238,8 +238,9 @@ void oled_write_P(const char *data, bool invert); // Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM void oled_write_ln_P(const char *data, bool invert); -// Returns a single byte of the oled buffer at index -char oled_read_raw_byte(uint16_t index); +// Returns a pointer to the requested start index in the buffer plus remaining +// buffer length as struct +oled_buffer_reader_t oled_read_raw(uint16_t start_index); // Writes a string to the buffer at current cursor position void oled_write_raw(const char *data, uint16_t size); diff --git a/drivers/oled/oled_driver.c b/drivers/oled/oled_driver.c index 6c61d6ddadc3..4910d20e66df 100644 --- a/drivers/oled/oled_driver.c +++ b/drivers/oled/oled_driver.c @@ -446,9 +446,12 @@ void oled_pan(bool left) { oled_dirty = ~((OLED_BLOCK_TYPE)0); } -char oled_read_raw_byte(uint16_t index) { - if (index > OLED_MATRIX_SIZE) index = OLED_MATRIX_SIZE; - return oled_buffer[index]; +oled_buffer_reader_t oled_read_raw(uint16_t start_index) { + if (start_index > OLED_MATRIX_SIZE) start_index = OLED_MATRIX_SIZE; + oled_buffer_reader_t ret_reader; + ret_reader.current_element = &oled_buffer[start_index]; + ret_reader.remaining_element_count = OLED_MATRIX_SIZE - start_index; + return ret_reader; } void oled_write_raw_byte(const char data, uint16_t index) { diff --git a/drivers/oled/oled_driver.h b/drivers/oled/oled_driver.h index 053a62ce919d..21bf26869f2d 100644 --- a/drivers/oled/oled_driver.h +++ b/drivers/oled/oled_driver.h @@ -150,6 +150,13 @@ along with this program. If not, see . # endif #endif + +typedef struct _oled_buffer_reader_t { + uint8_t *current_element; + uint16_t remaining_element_count; +} oled_buffer_reader_t; + + // OLED Rotation enum values are flags typedef enum { OLED_ROTATION_0 = 0, @@ -203,8 +210,9 @@ void oled_write_ln(const char *data, bool invert); // Pans the buffer to the right (or left by passing true) by moving contents of the buffer void oled_pan(bool left); -// Returns a single byte of the oled buffer at index -char oled_read_raw_byte(uint16_t index); +// Returns a pointer to the requested start index in the buffer plus remaining +// buffer length as struct +oled_buffer_reader_t oled_read_raw(uint16_t start_index); void oled_write_raw(const char *data, uint16_t size); void oled_write_raw_byte(const char data, uint16_t index); From ecf9bcfe15ab1547bdef1fe49607c6f845d87c23 Mon Sep 17 00:00:00 2001 From: brickbots Date: Wed, 29 Apr 2020 19:48:46 -0700 Subject: [PATCH 06/10] Pack that struct --- drivers/oled/oled_driver.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/oled/oled_driver.h b/drivers/oled/oled_driver.h index 21bf26869f2d..57681e16e252 100644 --- a/drivers/oled/oled_driver.h +++ b/drivers/oled/oled_driver.h @@ -150,13 +150,17 @@ along with this program. If not, see . # endif #endif +#if defined(__GNUC__) +# define PACKED __attribute__((__packed__)) +#else +# define PACKED +#endif -typedef struct _oled_buffer_reader_t { +typedef struct PACKED { uint8_t *current_element; uint16_t remaining_element_count; } oled_buffer_reader_t; - // OLED Rotation enum values are flags typedef enum { OLED_ROTATION_0 = 0, From d4a1e3898827a698b2066419135e17aebde99881 Mon Sep 17 00:00:00 2001 From: brickbots Date: Fri, 3 Jul 2020 18:24:02 -0700 Subject: [PATCH 07/10] Remove conditional packing and add example to docs --- docs/feature_oled_driver.md | 37 +++++++++++++++++++++++++++++++++++++ drivers/oled/oled_driver.h | 8 +------- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md index e29f356173b2..68cfaa22b696 100644 --- a/docs/feature_oled_driver.md +++ b/docs/feature_oled_driver.md @@ -72,6 +72,43 @@ static void render_logo(void) { } ``` +## Buffer Read Example +For some purposes, you may need to read the current state of the OLED display +buffer. The `oled_read_raw` function can be used to safely read bytes from the +buffer. + +In this example, calling `fade_display` in the `oled_task_user` function will +slowly fade away whatever is on the screen by turning random pixels black over +time. +```c +//Setup some mask which can be or'd with bytes to turn off pixels +const uint8_t single_bit_masks[8] = {127, 191, 223, 239, 247, 251, 253, 254}; + +static void fade_display(void) { + //Define the reader structure + oled_buffer_reader_t reader; + uint8_t buff_char; + if(random() % 30==0) { + srand(timer_read()); + // Fetch a pointer for the buffer byte at index 0. The return structure + // will have the pointer and the number of bytes remaining from this + // index position if we want to perform a sequential read by + // incrementing the buffer pointer + reader = oled_read_raw(0); + //Loop over the remaining buffer and erase pixels as we go + for (uint16_t i = 0; i < reader.remaining_element_count; i++) { + //Get the actual byte in the buffer by dereferencing the pointer + buff_char = *reader.current_element; + if (buff_char != 0) { + oled_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i); + } + //increment the pointer to fetch a new byte during the next loop + reader.current_element++; + } + } +} +``` + ## Other Examples In split keyboards, it is very common to have two OLED displays that each render different content and are oriented or flipped differently. You can do this by switching which content to render by using the return value from `is_keyboard_master()` or `is_keyboard_left()` found in `split_util.h`, e.g: diff --git a/drivers/oled/oled_driver.h b/drivers/oled/oled_driver.h index 57681e16e252..5df81bffab34 100644 --- a/drivers/oled/oled_driver.h +++ b/drivers/oled/oled_driver.h @@ -150,13 +150,7 @@ along with this program. If not, see . # endif #endif -#if defined(__GNUC__) -# define PACKED __attribute__((__packed__)) -#else -# define PACKED -#endif - -typedef struct PACKED { +typedef struct __attribute__((__packed__)) { uint8_t *current_element; uint16_t remaining_element_count; } oled_buffer_reader_t; From b5ad4d506e1b12424e8e3c43d981071a09cda918 Mon Sep 17 00:00:00 2001 From: brickbots Date: Tue, 28 Jul 2020 09:13:35 -0700 Subject: [PATCH 08/10] Cleanup tab/spaces --- docs/feature_oled_driver.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md index 68cfaa22b696..48b33b78dcd5 100644 --- a/docs/feature_oled_driver.md +++ b/docs/feature_oled_driver.md @@ -89,21 +89,21 @@ static void fade_display(void) { oled_buffer_reader_t reader; uint8_t buff_char; if(random() % 30==0) { - srand(timer_read()); - // Fetch a pointer for the buffer byte at index 0. The return structure - // will have the pointer and the number of bytes remaining from this - // index position if we want to perform a sequential read by - // incrementing the buffer pointer - reader = oled_read_raw(0); - //Loop over the remaining buffer and erase pixels as we go + srand(timer_read()); + // Fetch a pointer for the buffer byte at index 0. The return structure + // will have the pointer and the number of bytes remaining from this + // index position if we want to perform a sequential read by + // incrementing the buffer pointer + reader = oled_read_raw(0); + //Loop over the remaining buffer and erase pixels as we go for (uint16_t i = 0; i < reader.remaining_element_count; i++) { - //Get the actual byte in the buffer by dereferencing the pointer + //Get the actual byte in the buffer by dereferencing the pointer buff_char = *reader.current_element; - if (buff_char != 0) { + if (buff_char != 0) { oled_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i); - } - //increment the pointer to fetch a new byte during the next loop - reader.current_element++; + } + //increment the pointer to fetch a new byte during the next loop + reader.current_element++; } } } From 9534dcca31491da1da78f97f840672d1850a60e7 Mon Sep 17 00:00:00 2001 From: Richard Date: Tue, 28 Jul 2020 12:57:58 -0700 Subject: [PATCH 09/10] Update docs/feature_oled_driver.md Prettify formatting Co-authored-by: Ryan --- docs/feature_oled_driver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md index 48b33b78dcd5..e34c291322b8 100644 --- a/docs/feature_oled_driver.md +++ b/docs/feature_oled_driver.md @@ -88,7 +88,7 @@ static void fade_display(void) { //Define the reader structure oled_buffer_reader_t reader; uint8_t buff_char; - if(random() % 30==0) { + if (random() % 30 == 0) { srand(timer_read()); // Fetch a pointer for the buffer byte at index 0. The return structure // will have the pointer and the number of bytes remaining from this From 8c261f3c1c3839a9c4d32155df32da8d1dc6266c Mon Sep 17 00:00:00 2001 From: Richard Date: Tue, 28 Jul 2020 12:58:16 -0700 Subject: [PATCH 10/10] Update drivers/oled/oled_driver.h Prettify formatting Co-authored-by: Ryan --- drivers/oled/oled_driver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/oled/oled_driver.h b/drivers/oled/oled_driver.h index 5df81bffab34..028c6d717b17 100644 --- a/drivers/oled/oled_driver.h +++ b/drivers/oled/oled_driver.h @@ -151,8 +151,8 @@ along with this program. If not, see . #endif typedef struct __attribute__((__packed__)) { - uint8_t *current_element; - uint16_t remaining_element_count; + uint8_t *current_element; + uint16_t remaining_element_count; } oled_buffer_reader_t; // OLED Rotation enum values are flags