~ruther/qmk_firmware

957070a6b5886719557b6880afa7e3716548c18a — XScorpion2 6 years ago f22c5c1
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
M docs/feature_oled_driver.md => docs/feature_oled_driver.md +13 -11
@@ 96,17 96,19 @@ void oled_task_user(void) {

 ## Basic Configuration

| Define                 | Default           | Description                                                                                                                |
|------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------|
| `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_START`      | `0`               | The starting 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_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_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. |
| Define                     | Default           | Description                                                                                                                |
|----------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------|
| `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_START`          | `0`               | The starting 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_HEIGHT`         | `8`               | The font height (untested)                                                                                                 |
| `OLED_TIMEOUT`             | `60000`           | Turns off the OLED screen after 60000ms of keyboard inactivity. Helps reduce OLED Burn-in. Set to 0 to disable.            |
| `OLED_SCROLL_TIMEOUT`      | `0`               | Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable.                      |
| `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


M drivers/oled/oled_driver.c => drivers/oled/oled_driver.c +34 -6
@@ 114,8 114,11 @@ bool             oled_active = false;
bool             oled_scrolling = false;
uint8_t          oled_rotation = 0;
uint8_t          oled_rotation_width = 0;
#if !defined(OLED_DISABLE_TIMEOUT)
  uint16_t         oled_last_activity;
#if OLED_TIMEOUT > 0
  uint32_t         oled_timeout;
#endif
#if OLED_SCROLL_TIMEOUT > 0
  uint32_t         oled_scroll_timeout;
#endif

// Internal variables to reduce math instructions


@@ 209,6 212,13 @@ bool oled_init(uint8_t rotation) {
    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_initialized = true;
  oled_active = true;


@@ 457,8 467,8 @@ void oled_write_ln_P(const char *data, bool invert) {
#endif // defined(__AVR__)

bool oled_on(void) {
#if !defined(OLED_DISABLE_TIMEOUT)
  oled_last_activity = timer_read();
#if OLED_TIMEOUT > 0
  oled_timeout = timer_read32() + OLED_TIMEOUT;
#endif

  static const uint8_t PROGMEM display_on[] = { I2C_CMD, DISPLAY_ON };


@@ 522,6 532,7 @@ bool oled_scroll_off(void) {
      return oled_scrolling;
    }
    oled_scrolling = false;
    oled_dirty = -1;
  }
  return !oled_scrolling;
}


@@ 549,15 560,32 @@ void oled_task(void) {

  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
  oled_render();

  // Display timeout check
#if !defined(OLED_DISABLE_TIMEOUT)
  if (oled_active && timer_elapsed(oled_last_activity) > OLED_TIMEOUT) {
#if OLED_TIMEOUT > 0
  if (oled_active && timer_expired32(timer_read32(), oled_timeout)) {
    oled_off();
  }
#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))

M drivers/oled/oled_driver.h => drivers/oled/oled_driver.h +8 -0
@@ 138,6 138,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  #define OLED_FONT_HEIGHT 8
#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
typedef enum {
    OLED_ROTATION_0   = 0,

M tmk_core/common/timer.h => tmk_core/common/timer.h +11 -0
@@ 19,6 19,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define TIMER_H 1

#include <stdint.h>
#include <stdbool.h>

#if defined(__AVR__)
#include "avr/timer_avr.h"


@@ 46,6 47,16 @@ uint32_t timer_read32(void);
uint16_t timer_elapsed(uint16_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
}
#endif

M tmk_core/protocol/usb_hid/override_wiring.c => tmk_core/protocol/usb_hid/override_wiring.c +3 -4
@@ 4,14 4,13 @@
#define __DELAY_BACKWARD_COMPATIBLE__
#include <util/delay.h>
#include "common/timer.h"
#include "Arduino.h"


unsigned long millis()
unsigned long millis(void)
{
    return timer_read32();
}
unsigned long micros()
unsigned long micros(void)
{
    return timer_read32() * 1000UL;
}


@@ 23,7 22,7 @@ void delayMicroseconds(unsigned int us)
{
    _delay_us(us);
}
void init()
void init(void)
{
    timer_init();
}

M users/xulkal/custom_tap_dance.c => users/xulkal/custom_tap_dance.c +0 -1
@@ 1,6 1,5 @@
#include "custom_tap_dance.h"
#include "custom_keycodes.h"
#include "timer_utils.h"

#ifdef TAP_DANCE_ENABLE


M users/xulkal/layouts.h => users/xulkal/layouts.h +1 -1
@@ 18,7 18,7 @@
#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_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_R2_________________           KC_Y,    KC_U,      KC_I,     KC_O,     KC_P,     KC_BSLS

M users/xulkal/process_records.c => users/xulkal/process_records.c +1 -2
@@ 1,6 1,5 @@
#include "process_records.h"
#include "custom_keycodes.h"
#include "timer_utils.h"

#ifdef RGB_ENABLE
#include "custom_rgb.h"


@@ 34,7 33,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record)
            {
                if (record->event.pressed)
                    reset_timer = timer_read() + 500;
                else if (timer_expired(reset_timer))
                else if (timer_expired(timer_read(), reset_timer))
                    reset_keyboard();
            }
            return false;

M users/xulkal/rules.mk => users/xulkal/rules.mk +1 -2
@@ 1,7 1,6 @@
SRC += xulkal.c \
    process_records.c \
    custom_tap_dance.c \
    timer_utils.c
    custom_tap_dance.c

# Some usual defaults
MOUSEKEY_ENABLE         = no    # Mouse keys (+4700)

D users/xulkal/timer_utils.c => users/xulkal/timer_utils.c +0 -12
@@ 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;
}


D users/xulkal/timer_utils.h => users/xulkal/timer_utils.h +0 -6
@@ 1,6 0,0 @@
#pragma once
#include "timer.h"
#include <stdbool.h>

bool timer_expired(uint16_t last);
bool timer_expired32(uint32_t last);

M users/xulkal/xulkal.h => users/xulkal/xulkal.h +0 -1
@@ 2,6 2,5 @@

#include "process_records.h"
#include "layouts.h"
#include "timer_utils.h"
#include "custom_keycodes.h"
#include "custom_tap_dance.h"