diff --git a/quantum/backlight/backlight.c b/quantum/backlight/backlight.c index 4aa74667d9ca..4a0eac64c664 100644 --- a/quantum/backlight/backlight.c +++ b/quantum/backlight/backlight.c @@ -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 * @@ -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; } @@ -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) {} diff --git a/quantum/backlight/backlight.h b/quantum/backlight/backlight.h index 08acf942ffb5..07a4880e9f4a 100644 --- a/quantum/backlight/backlight.h +++ b/quantum/backlight/backlight.h @@ -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 @@ -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); diff --git a/quantum/backlight/backlight_arm.c b/quantum/backlight/backlight_arm.c index 397a1ac1a8ab..a6d38a1a02e8 100644 --- a/quantum/backlight/backlight_arm.c +++ b/quantum/backlight/backlight_arm.c @@ -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)] */ diff --git a/quantum/backlight/backlight_avr.c b/quantum/backlight/backlight_avr.c index ce6611fb5aca..40291d3821ee 100644 --- a/quantum/backlight/backlight_avr.c +++ b/quantum/backlight/backlight_avr.c @@ -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 @@ -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 @@ -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 @@ -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(); } } @@ -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) { @@ -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)] */ @@ -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. diff --git a/quantum/backlight/backlight_soft.c b/quantum/backlight/backlight_soft.c index 096b41d91075..8552384a4284 100644 --- a/quantum/backlight/backlight_soft.c +++ b/quantum/backlight/backlight_soft.c @@ -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 @@ -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, @@ -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)]; }