Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor more backlight to a common location #8292

Merged
merged 3 commits into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion quantum/backlight/backlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,62 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "quantum.h"
#include "backlight.h"
#include "eeconfig.h"
#include "debug.h"

backlight_config_t backlight_config;

#ifdef BACKLIGHT_BREATHING
// TODO: migrate to backlight_config_t
static uint8_t breathing_period = BREATHING_PERIOD;
#endif

#ifndef BACKLIGHT_CUSTOM_DRIVER
# if defined(BACKLIGHT_PINS)
static const pin_t backlight_pins[] = BACKLIGHT_PINS;
# ifndef BACKLIGHT_LED_COUNT
# define BACKLIGHT_LED_COUNT (sizeof(backlight_pins) / sizeof(pin_t))
# endif

# define FOR_EACH_LED(x) \
for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) { \
pin_t backlight_pin = backlight_pins[i]; \
{ x } \
}
# else
// we support only one backlight pin
static const pin_t backlight_pin = BACKLIGHT_PIN;
# define FOR_EACH_LED(x) x
# endif

static inline void backlight_on(pin_t backlight_pin) {
# if BACKLIGHT_ON_STATE == 0
writePinLow(backlight_pin);
# else
writePinHigh(backlight_pin);
# endif
}

static inline void backlight_off(pin_t backlight_pin) {
# if BACKLIGHT_ON_STATE == 0
writePinHigh(backlight_pin);
# else
writePinLow(backlight_pin);
# endif
}

void backlight_pins_init(void) {
// Setup backlight pin as output and output to off state.
FOR_EACH_LED(setPinOutput(backlight_pin); backlight_off(backlight_pin);)
}

void backlight_pins_on(void) { FOR_EACH_LED(backlight_on(backlight_pin);) }

void backlight_pins_off(void) { FOR_EACH_LED(backlight_off(backlight_pin);) }

#endif

/** \brief Backlight initialization
*
Expand Down Expand Up @@ -205,7 +253,6 @@ void backlight_disable_breathing(void) {
* FIXME: needs doc
*/
bool is_backlight_breathing(void) { return backlight_config.breathing; }
#endif

// following are marked as weak purely for backwards compatibility
__attribute__((weak)) void breathing_period_set(uint8_t value) { breathing_period = value ? value : 1; }
Expand All @@ -218,6 +265,15 @@ __attribute__((weak)) void breathing_period_inc(void) { breathing_period_set(bre

__attribute__((weak)) void breathing_period_dec(void) { breathing_period_set(breathing_period - 1); }

__attribute__((weak)) void breathing_toggle(void) {
if (is_breathing())
breathing_disable();
else
breathing_enable();
}

#endif

// defaults for backlight api
__attribute__((weak)) void backlight_init_ports(void) {}

Expand Down
8 changes: 8 additions & 0 deletions quantum/backlight/backlight.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# error "Maximum value of BACKLIGHT_LEVELS is 31"
#endif

#ifndef BACKLIGHT_ON_STATE
# define BACKLIGHT_ON_STATE 1
#endif

#ifndef BREATHING_PERIOD
# define BREATHING_PERIOD 6
#endif
Expand All @@ -40,6 +44,10 @@ typedef union {
};
} backlight_config_t;

void backlight_pins_init(void);
void backlight_pins_on(void);
void backlight_pins_off(void);

void backlight_init(void);
void backlight_toggle(void);
void backlight_enable(void);
Expand Down
7 changes: 0 additions & 7 deletions quantum/backlight/backlight_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,6 @@ void breathing_self_disable(void) {
breathing_halt = BREATHING_HALT_ON;
}

void breathing_toggle(void) {
if (is_breathing())
breathing_disable();
else
breathing_enable();
}

/* To generate breathing curve in python:
* from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
*/
Expand Down
63 changes: 5 additions & 58 deletions quantum/backlight/backlight_avr.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,49 +164,7 @@ error("Please set 'BACKLIGHT_DRIVER = custom' within rules.mk")
error("Please set 'BACKLIGHT_DRIVER = software' within rules.mk")
#endif

#ifndef BACKLIGHT_ON_STATE
# define BACKLIGHT_ON_STATE 1
#endif

void backlight_on(pin_t backlight_pin) {
#if BACKLIGHT_ON_STATE == 1
writePinHigh(backlight_pin);
#else
writePinLow(backlight_pin);
#endif
}

void backlight_off(pin_t backlight_pin) {
#if BACKLIGHT_ON_STATE == 1
writePinLow(backlight_pin);
#else
writePinHigh(backlight_pin);
#endif
}

#ifdef BACKLIGHT_PWM_TIMER // pwm through software

// we support multiple backlight pins
# ifndef BACKLIGHT_LED_COUNT
# define BACKLIGHT_LED_COUNT 1
# endif

# if BACKLIGHT_LED_COUNT == 1
# define BACKLIGHT_PIN_INIT \
{ BACKLIGHT_PIN }
# else
# define BACKLIGHT_PIN_INIT BACKLIGHT_PINS
# endif

# define FOR_EACH_LED(x) \
for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) { \
pin_t backlight_pin = backlight_pins[i]; \
{ x } \
}

static const pin_t backlight_pins[BACKLIGHT_LED_COUNT] = BACKLIGHT_PIN_INIT;

#else // full hardware PWM
#ifndef BACKLIGHT_PWM_TIMER // pwm through software

static inline void enable_pwm(void) {
# if BACKLIGHT_ON_STATE == 1
Expand All @@ -224,10 +182,6 @@ static inline void disable_pwm(void) {
# endif
}

// we support only one backlight pin
static const pin_t backlight_pin = BACKLIGHT_PIN;
# define FOR_EACH_LED(x) x

#endif

#ifdef BACKLIGHT_PWM_TIMER
Expand All @@ -246,7 +200,7 @@ static const pin_t backlight_pin = BACKLIGHT_PIN;
// The LED will then be on for OCRxx/0xFFFF time, adjusted every 244Hz.

// Triggered when the counter reaches the OCRx value
ISR(TIMERx_COMPA_vect) { FOR_EACH_LED(backlight_off(backlight_pin);) }
ISR(TIMERx_COMPA_vect) { backlight_pins_off(); }

// Triggered when the counter reaches the TOP value
// this one triggers at F_CPU/65536 =~ 244 Hz
Expand All @@ -265,7 +219,7 @@ ISR(TIMERx_OVF_vect) {
// takes many computation cycles).
// so better not turn them on while the counter TOP is very low.
if (OCRxx > 256) {
FOR_EACH_LED(backlight_on(backlight_pin);)
backlight_pins_on();
}
}

Expand Down Expand Up @@ -305,7 +259,7 @@ void backlight_set(uint8_t level) {
// Turn off PWM control on backlight pin
disable_pwm();
#endif
FOR_EACH_LED(backlight_off(backlight_pin);)
backlight_pins_off();
} else {
#ifdef BACKLIGHT_PWM_TIMER
if (!OCRxx) {
Expand Down Expand Up @@ -397,13 +351,6 @@ void breathing_self_disable(void) {
breathing_halt = BREATHING_HALT_ON;
}

void breathing_toggle(void) {
if (is_breathing())
breathing_disable();
else
breathing_enable();
}

/* To generate breathing curve in python:
* from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
*/
Expand Down Expand Up @@ -438,7 +385,7 @@ ISR(TIMERx_OVF_vect)

void backlight_init_ports(void) {
// Setup backlight pin as output and output to on state.
FOR_EACH_LED(setPinOutput(backlight_pin); backlight_on(backlight_pin);)
backlight_pins_init();

// I could write a wall of text here to explain... but TL;DW
// Go read the ATmega32u4 datasheet.
Expand Down
54 changes: 8 additions & 46 deletions quantum/backlight/backlight_soft.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,7 @@
# error "Backlight breathing is not available for software PWM. Please disable."
#endif

#ifndef BACKLIGHT_ON_STATE
# define BACKLIGHT_ON_STATE 1
#endif

#ifdef BACKLIGHT_PINS
# define BACKLIGHT_PIN_INIT BACKLIGHT_PINS
#else
# define BACKLIGHT_PIN_INIT \
{ BACKLIGHT_PIN }
#endif

static uint16_t s_duty_pattern = 0;
static const pin_t backlight_pins[] = BACKLIGHT_PIN_INIT;
#define BACKLIGHT_LED_COUNT (sizeof(backlight_pins) / sizeof(pin_t))

#define FOR_EACH_LED(x) \
for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) { \
pin_t backlight_pin = backlight_pins[i]; \
{ x } \
}

void backlight_on(pin_t backlight_pin) {
#if BACKLIGHT_ON_STATE == 0
writePinLow(backlight_pin);
#else
writePinHigh(backlight_pin);
#endif
}

void backlight_off(pin_t backlight_pin) {
#if BACKLIGHT_ON_STATE == 0
writePinHigh(backlight_pin);
#else
writePinLow(backlight_pin);
#endif
}

void backlight_init_ports(void) {
// Setup backlight pin as output and output to off state.
FOR_EACH_LED(setPinOutput(backlight_pin); backlight_off(backlight_pin);)
}
static uint16_t s_duty_pattern = 0;

// clang-format off

Expand All @@ -58,7 +18,7 @@ void backlight_init_ports(void) {
* We scale the current backlight level to an index within this array. This allows
* backlight_task to focus on just switching LEDs on/off, and we can predict the duty pattern
*/
static uint16_t backlight_duty_table[] = {
static const uint16_t backlight_duty_table[] = {
0b0000000000000000,
0b1000000000000000,
0b1000000010000000,
Expand All @@ -75,15 +35,17 @@ static uint16_t backlight_duty_table[] = {

static uint8_t scale_backlight(uint8_t v) { return v * (backlight_duty_table_size - 1) / BACKLIGHT_LEVELS; }

void backlight_init_ports(void) { backlight_pins_init(); }

void backlight_set(uint8_t level) { s_duty_pattern = backlight_duty_table[scale_backlight(level)]; }

void backlight_task(void) {
static uint8_t backlight_tick = 0;

if (s_duty_pattern & ((uint16_t)1 << backlight_tick)) {
FOR_EACH_LED(backlight_on(backlight_pin);)
backlight_pins_on();
} else {
FOR_EACH_LED(backlight_off(backlight_pin);)
backlight_pins_off();
}
backlight_tick = (backlight_tick + 1) % 16;
}

void backlight_set(uint8_t level) { s_duty_pattern = backlight_duty_table[scale_backlight(level)]; }