aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/feature_oled_driver.md41
-rw-r--r--drivers/oled/oled_driver.c8
-rw-r--r--drivers/oled/oled_driver.h9
3 files changed, 58 insertions, 0 deletions
diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md
index 5f3095198..d106d3d13 100644
--- a/docs/feature_oled_driver.md
+++ b/docs/feature_oled_driver.md
@@ -72,6 +72,43 @@ static void render_logo(void) {
72} 72}
73``` 73```
74 74
75## Buffer Read Example
76For some purposes, you may need to read the current state of the OLED display
77buffer. The `oled_read_raw` function can be used to safely read bytes from the
78buffer.
79
80In this example, calling `fade_display` in the `oled_task_user` function will
81slowly fade away whatever is on the screen by turning random pixels black over
82time.
83```c
84//Setup some mask which can be or'd with bytes to turn off pixels
85const uint8_t single_bit_masks[8] = {127, 191, 223, 239, 247, 251, 253, 254};
86
87static void fade_display(void) {
88 //Define the reader structure
89 oled_buffer_reader_t reader;
90 uint8_t buff_char;
91 if (random() % 30 == 0) {
92 srand(timer_read());
93 // Fetch a pointer for the buffer byte at index 0. The return structure
94 // will have the pointer and the number of bytes remaining from this
95 // index position if we want to perform a sequential read by
96 // incrementing the buffer pointer
97 reader = oled_read_raw(0);
98 //Loop over the remaining buffer and erase pixels as we go
99 for (uint16_t i = 0; i < reader.remaining_element_count; i++) {
100 //Get the actual byte in the buffer by dereferencing the pointer
101 buff_char = *reader.current_element;
102 if (buff_char != 0) {
103 oled_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i);
104 }
105 //increment the pointer to fetch a new byte during the next loop
106 reader.current_element++;
107 }
108 }
109}
110```
111
75## Other Examples 112## Other Examples
76 113
77In 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: 114In 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:
@@ -238,6 +275,10 @@ void oled_write_P(const char *data, bool invert);
238// Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM 275// Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM
239void oled_write_ln_P(const char *data, bool invert); 276void oled_write_ln_P(const char *data, bool invert);
240 277
278// Returns a pointer to the requested start index in the buffer plus remaining
279// buffer length as struct
280oled_buffer_reader_t oled_read_raw(uint16_t start_index);
281
241// Writes a string to the buffer at current cursor position 282// Writes a string to the buffer at current cursor position
242void oled_write_raw(const char *data, uint16_t size); 283void oled_write_raw(const char *data, uint16_t size);
243 284
diff --git a/drivers/oled/oled_driver.c b/drivers/oled/oled_driver.c
index f1990567f..bbf010a09 100644
--- a/drivers/oled/oled_driver.c
+++ b/drivers/oled/oled_driver.c
@@ -444,6 +444,14 @@ void oled_pan(bool left) {
444 oled_dirty = ~((OLED_BLOCK_TYPE)0); 444 oled_dirty = ~((OLED_BLOCK_TYPE)0);
445} 445}
446 446
447oled_buffer_reader_t oled_read_raw(uint16_t start_index) {
448 if (start_index > OLED_MATRIX_SIZE) start_index = OLED_MATRIX_SIZE;
449 oled_buffer_reader_t ret_reader;
450 ret_reader.current_element = &oled_buffer[start_index];
451 ret_reader.remaining_element_count = OLED_MATRIX_SIZE - start_index;
452 return ret_reader;
453}
454
447void oled_write_raw_byte(const char data, uint16_t index) { 455void oled_write_raw_byte(const char data, uint16_t index) {
448 if (index > OLED_MATRIX_SIZE) index = OLED_MATRIX_SIZE; 456 if (index > OLED_MATRIX_SIZE) index = OLED_MATRIX_SIZE;
449 if (oled_buffer[index] == data) return; 457 if (oled_buffer[index] == data) return;
diff --git a/drivers/oled/oled_driver.h b/drivers/oled/oled_driver.h
index 5c21c0cc8..7ec00d66a 100644
--- a/drivers/oled/oled_driver.h
+++ b/drivers/oled/oled_driver.h
@@ -154,6 +154,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
154# define OLED_I2C_TIMEOUT 100 154# define OLED_I2C_TIMEOUT 100
155#endif 155#endif
156 156
157typedef struct __attribute__((__packed__)) {
158 uint8_t *current_element;
159 uint16_t remaining_element_count;
160} oled_buffer_reader_t;
161
157// OLED Rotation enum values are flags 162// OLED Rotation enum values are flags
158typedef enum { 163typedef enum {
159 OLED_ROTATION_0 = 0, 164 OLED_ROTATION_0 = 0,
@@ -207,6 +212,10 @@ void oled_write_ln(const char *data, bool invert);
207// Pans the buffer to the right (or left by passing true) by moving contents of the buffer 212// Pans the buffer to the right (or left by passing true) by moving contents of the buffer
208void oled_pan(bool left); 213void oled_pan(bool left);
209 214
215// Returns a pointer to the requested start index in the buffer plus remaining
216// buffer length as struct
217oled_buffer_reader_t oled_read_raw(uint16_t start_index);
218
210void oled_write_raw(const char *data, uint16_t size); 219void oled_write_raw(const char *data, uint16_t size);
211void oled_write_raw_byte(const char data, uint16_t index); 220void oled_write_raw_byte(const char data, uint16_t index);
212 221