mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 05:12:33 +01:00 
			
		
		
		
	Added OLED Display autoscroll during periods of OLED data inactivity (#6546)
* Added OLED Display autoscroll during periods of OLED data inactivity. * Fixing compile errors * Feedback from review
This commit is contained in:
		
							parent
							
								
									f22c5c17b6
								
							
						
					
					
						commit
						957070a6b5
					
				| @ -96,17 +96,19 @@ void oled_task_user(void) { | |||||||
| 
 | 
 | ||||||
|  ## Basic Configuration |  ## Basic Configuration | ||||||
| 
 | 
 | ||||||
| | Define                 | Default           | Description                                                                                                                | | | Define                     | Default           | Description                                                                                                                | | ||||||
| |------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------| | |----------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------| | ||||||
| | `OLED_DISPLAY_ADDRESS` | `0x3C`            | The i2c address of the OLED Display                                                                                        | | | `OLED_DISPLAY_ADDRESS`     | `0x3C`            | The i2c address of the OLED Display                                                                                        | | ||||||
| | `OLED_FONT_H`          | `"glcdfont.c"`    | The font code file to use for custom fonts                                                                                 | | | `OLED_FONT_H`              | `"glcdfont.c"`    | The font code file to use for custom fonts                                                                                 | | ||||||
| | `OLED_FONT_START`      | `0`               | The starting characer index for custom fonts                                                                               | | | `OLED_FONT_START`          | `0`               | The starting characer index for custom fonts                                                                               | | ||||||
| | `OLED_FONT_END`        | `224`             | The ending characer index for custom fonts                                                                                 | | | `OLED_FONT_END`            | `224`             | The ending characer index for custom fonts                                                                                 | | ||||||
| | `OLED_FONT_WIDTH`      | `6`               | The font width                                                                                                             | | | `OLED_FONT_WIDTH`          | `6`               | The font width                                                                                                             | | ||||||
| | `OLED_FONT_HEIGHT`     | `8`               | The font height (untested)                                                                                                 | | | `OLED_FONT_HEIGHT`         | `8`               | The font height (untested)                                                                                                 | | ||||||
| | `OLED_DISABLE_TIMEOUT` | *Not defined*     | Disables the built in OLED timeout feature. Useful when implementing custom timeout rules.                                 | | | `OLED_TIMEOUT`             | `60000`           | Turns off the OLED screen after 60000ms of keyboard inactivity. Helps reduce OLED Burn-in. Set to 0 to disable.            | | ||||||
| | `OLED_IC`              | `OLED_IC_SSD1306` | Set to `OLED_IC_SH1106` if you're using the SH1106 OLED controller.                                                        | | | `OLED_SCROLL_TIMEOUT`      | `0`               | Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable.                      | | ||||||
| | `OLED_COLUMN_OFFSET`   | `0`               | (SH1106 only.) Shift output to the right this many pixels.<br />Useful for 128x64 displays centered on a 132x64 SH1106 IC. | | | `OLED_SCROLL_TIMEOUT_RIGHT`| *Not defined*     | Scroll timeout direction is right when defined, left when undefined.                                                       | | ||||||
|  | | `OLED_IC`                  | `OLED_IC_SSD1306` | Set to `OLED_IC_SH1106` if you're using the SH1106 OLED controller.                                                        | | ||||||
|  | | `OLED_COLUMN_OFFSET`       | `0`               | (SH1106 only.) Shift output to the right this many pixels.<br />Useful for 128x64 displays centered on a 132x64 SH1106 IC. | | ||||||
| 
 | 
 | ||||||
|  ## 128x64 & Custom sized OLED Displays |  ## 128x64 & Custom sized OLED Displays | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -114,8 +114,11 @@ bool             oled_active = false; | |||||||
| bool             oled_scrolling = false; | bool             oled_scrolling = false; | ||||||
| uint8_t          oled_rotation = 0; | uint8_t          oled_rotation = 0; | ||||||
| uint8_t          oled_rotation_width = 0; | uint8_t          oled_rotation_width = 0; | ||||||
| #if !defined(OLED_DISABLE_TIMEOUT) | #if OLED_TIMEOUT > 0 | ||||||
|   uint16_t         oled_last_activity; |   uint32_t         oled_timeout; | ||||||
|  | #endif | ||||||
|  | #if OLED_SCROLL_TIMEOUT > 0 | ||||||
|  |   uint32_t         oled_scroll_timeout; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| // Internal variables to reduce math instructions
 | // Internal variables to reduce math instructions
 | ||||||
| @ -209,6 +212,13 @@ bool oled_init(uint8_t rotation) { | |||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | #if OLED_TIMEOUT > 0 | ||||||
|  |   oled_timeout = timer_read32() + OLED_TIMEOUT; | ||||||
|  | #endif | ||||||
|  | #if OLED_SCROLL_TIMEOUT > 0 | ||||||
|  |   oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|   oled_clear(); |   oled_clear(); | ||||||
|   oled_initialized = true; |   oled_initialized = true; | ||||||
|   oled_active = true; |   oled_active = true; | ||||||
| @ -457,8 +467,8 @@ void oled_write_ln_P(const char *data, bool invert) { | |||||||
| #endif // defined(__AVR__)
 | #endif // defined(__AVR__)
 | ||||||
| 
 | 
 | ||||||
| bool oled_on(void) { | bool oled_on(void) { | ||||||
| #if !defined(OLED_DISABLE_TIMEOUT) | #if OLED_TIMEOUT > 0 | ||||||
|   oled_last_activity = timer_read(); |   oled_timeout = timer_read32() + OLED_TIMEOUT; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|   static const uint8_t PROGMEM display_on[] = { I2C_CMD, DISPLAY_ON }; |   static const uint8_t PROGMEM display_on[] = { I2C_CMD, DISPLAY_ON }; | ||||||
| @ -522,6 +532,7 @@ bool oled_scroll_off(void) { | |||||||
|       return oled_scrolling; |       return oled_scrolling; | ||||||
|     } |     } | ||||||
|     oled_scrolling = false; |     oled_scrolling = false; | ||||||
|  |     oled_dirty = -1; | ||||||
|   } |   } | ||||||
|   return !oled_scrolling; |   return !oled_scrolling; | ||||||
| } | } | ||||||
| @ -549,15 +560,32 @@ void oled_task(void) { | |||||||
| 
 | 
 | ||||||
|   oled_task_user(); |   oled_task_user(); | ||||||
| 
 | 
 | ||||||
|  | #if OLED_SCROLL_TIMEOUT > 0 | ||||||
|  |   if (oled_dirty && oled_scrolling) { | ||||||
|  |     oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT; | ||||||
|  |     oled_scroll_off(); | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|   // Smart render system, no need to check for dirty
 |   // Smart render system, no need to check for dirty
 | ||||||
|   oled_render(); |   oled_render(); | ||||||
| 
 | 
 | ||||||
|   // Display timeout check
 |   // Display timeout check
 | ||||||
| #if !defined(OLED_DISABLE_TIMEOUT) | #if OLED_TIMEOUT > 0 | ||||||
|   if (oled_active && timer_elapsed(oled_last_activity) > OLED_TIMEOUT) { |   if (oled_active && timer_expired32(timer_read32(), oled_timeout)) { | ||||||
|     oled_off(); |     oled_off(); | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|  | 
 | ||||||
|  | #if OLED_SCROLL_TIMEOUT > 0 | ||||||
|  |   if (!oled_scrolling && timer_expired32(timer_read32(), oled_scroll_timeout)) { | ||||||
|  | #ifdef OLED_SCROLL_TIMEOUT_RIGHT | ||||||
|  |     oled_scroll_right(); | ||||||
|  | #else | ||||||
|  |     oled_scroll_left(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| __attribute__((weak)) | __attribute__((weak)) | ||||||
|  | |||||||
| @ -138,6 +138,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
|   #define OLED_FONT_HEIGHT 8 |   #define OLED_FONT_HEIGHT 8 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if !defined(OLED_TIMEOUT) | ||||||
|  |   #if defined(OLED_DISABLE_TIMEOUT) | ||||||
|  |     #define OLED_TIMEOUT 0 | ||||||
|  |   #else | ||||||
|  |     #define OLED_TIMEOUT 60000 | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| // OLED Rotation enum values are flags
 | // OLED Rotation enum values are flags
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     OLED_ROTATION_0   = 0, |     OLED_ROTATION_0   = 0, | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| #define TIMER_H 1 | #define TIMER_H 1 | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
| 
 | 
 | ||||||
| #if defined(__AVR__) | #if defined(__AVR__) | ||||||
| #include "avr/timer_avr.h" | #include "avr/timer_avr.h" | ||||||
| @ -46,6 +47,16 @@ uint32_t timer_read32(void); | |||||||
| uint16_t timer_elapsed(uint16_t last); | uint16_t timer_elapsed(uint16_t last); | ||||||
| uint32_t timer_elapsed32(uint32_t last); | uint32_t timer_elapsed32(uint32_t last); | ||||||
| 
 | 
 | ||||||
|  | // Utility functions to check if a future time has expired & autmatically handle time wrapping if checked / reset frequently (half of max value)
 | ||||||
|  | inline bool timer_expired(uint16_t current, uint16_t last) | ||||||
|  | { | ||||||
|  |     return current - last < 0x8000; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | inline bool timer_expired32(uint32_t current, uint32_t future) { | ||||||
|  |     return current - future < 0x80000000; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -4,14 +4,13 @@ | |||||||
| #define __DELAY_BACKWARD_COMPATIBLE__ | #define __DELAY_BACKWARD_COMPATIBLE__ | ||||||
| #include <util/delay.h> | #include <util/delay.h> | ||||||
| #include "common/timer.h" | #include "common/timer.h" | ||||||
| #include "Arduino.h" |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| unsigned long millis() | unsigned long millis(void) | ||||||
| { | { | ||||||
|     return timer_read32(); |     return timer_read32(); | ||||||
| } | } | ||||||
| unsigned long micros() | unsigned long micros(void) | ||||||
| { | { | ||||||
|     return timer_read32() * 1000UL; |     return timer_read32() * 1000UL; | ||||||
| } | } | ||||||
| @ -23,7 +22,7 @@ void delayMicroseconds(unsigned int us) | |||||||
| { | { | ||||||
|     _delay_us(us); |     _delay_us(us); | ||||||
| } | } | ||||||
| void init() | void init(void) | ||||||
| { | { | ||||||
|     timer_init(); |     timer_init(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,5 @@ | |||||||
| #include "custom_tap_dance.h" | #include "custom_tap_dance.h" | ||||||
| #include "custom_keycodes.h" | #include "custom_keycodes.h" | ||||||
| #include "timer_utils.h" |  | ||||||
| 
 | 
 | ||||||
| #ifdef TAP_DANCE_ENABLE | #ifdef TAP_DANCE_ENABLE | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ | |||||||
| #define _________________QWERTY_L2_________________ KC_TAB,   KC_Q,     KC_W,     KC_E,     KC_R,     KC_T | #define _________________QWERTY_L2_________________ KC_TAB,   KC_Q,     KC_W,     KC_E,     KC_R,     KC_T | ||||||
| #define _________________QWERTY_L3_________________ RIS_CAPS, KC_A,     KC_S,     KC_D,     KC_F,     KC_G | #define _________________QWERTY_L3_________________ RIS_CAPS, KC_A,     KC_S,     KC_D,     KC_F,     KC_G | ||||||
| #define _________________QWERTY_L4_________________ KC_LSPO,  KC_Z,     KC_X,     KC_C,     KC_V,     KC_B | #define _________________QWERTY_L4_________________ KC_LSPO,  KC_Z,     KC_X,     KC_C,     KC_V,     KC_B | ||||||
| #define _________________QWERTY_L5_________________ KC_LCPO,  KC_LGUI,  LOWER,    RAISE,    KC_LALT,  KC_SPC | #define _________________QWERTY_L5_________________ KC_LCPO,  KC_LGUI,  KC_LALT,  LOWER,    RAISE,  KC_SPC | ||||||
| 
 | 
 | ||||||
| #define _________________QWERTY_R1_________________           KC_6,    KC_7,      KC_8,     KC_9,     KC_0,     TD_BSPC | #define _________________QWERTY_R1_________________           KC_6,    KC_7,      KC_8,     KC_9,     KC_0,     TD_BSPC | ||||||
| #define _________________QWERTY_R2_________________           KC_Y,    KC_U,      KC_I,     KC_O,     KC_P,     KC_BSLS | #define _________________QWERTY_R2_________________           KC_Y,    KC_U,      KC_I,     KC_O,     KC_P,     KC_BSLS | ||||||
|  | |||||||
| @ -1,6 +1,5 @@ | |||||||
| #include "process_records.h" | #include "process_records.h" | ||||||
| #include "custom_keycodes.h" | #include "custom_keycodes.h" | ||||||
| #include "timer_utils.h" |  | ||||||
| 
 | 
 | ||||||
| #ifdef RGB_ENABLE | #ifdef RGB_ENABLE | ||||||
| #include "custom_rgb.h" | #include "custom_rgb.h" | ||||||
| @ -34,7 +33,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) | |||||||
|             { |             { | ||||||
|                 if (record->event.pressed) |                 if (record->event.pressed) | ||||||
|                     reset_timer = timer_read() + 500; |                     reset_timer = timer_read() + 500; | ||||||
|                 else if (timer_expired(reset_timer)) |                 else if (timer_expired(timer_read(), reset_timer)) | ||||||
|                     reset_keyboard(); |                     reset_keyboard(); | ||||||
|             } |             } | ||||||
|             return false; |             return false; | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| SRC += xulkal.c \
 | SRC += xulkal.c \
 | ||||||
|     process_records.c \
 |     process_records.c \
 | ||||||
|     custom_tap_dance.c \
 |     custom_tap_dance.c | ||||||
|     timer_utils.c |  | ||||||
| 
 | 
 | ||||||
| # Some usual defaults
 | # Some usual defaults
 | ||||||
| MOUSEKEY_ENABLE         = no    # Mouse keys (+4700) | MOUSEKEY_ENABLE         = no    # Mouse keys (+4700) | ||||||
|  | |||||||
| @ -1,12 +0,0 @@ | |||||||
| #include "timer_utils.h" |  | ||||||
| 
 |  | ||||||
| bool timer_expired(uint16_t last) |  | ||||||
| { |  | ||||||
|     return timer_read() - last < 0x8000; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool timer_expired32(uint32_t last) |  | ||||||
| { |  | ||||||
|     return timer_read32() - last < 0x80000000; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @ -1,6 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "timer.h" |  | ||||||
| #include <stdbool.h> |  | ||||||
| 
 |  | ||||||
| bool timer_expired(uint16_t last); |  | ||||||
| bool timer_expired32(uint32_t last); |  | ||||||
| @ -2,6 +2,5 @@ | |||||||
| 
 | 
 | ||||||
| #include "process_records.h" | #include "process_records.h" | ||||||
| #include "layouts.h" | #include "layouts.h" | ||||||
| #include "timer_utils.h" |  | ||||||
| #include "custom_keycodes.h" | #include "custom_keycodes.h" | ||||||
| #include "custom_tap_dance.h" | #include "custom_tap_dance.h" | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 XScorpion2
						XScorpion2