Fix backlight breathing on C6 (#6102)
* Fix backlight breathing on C6 * Account for ATmega32A's single TIMSK register (MT40) * Document hardware PWM on D4 for ATmega32A * Add C6 and D4 to BACKLIGHT_PIN description
This commit is contained in:
parent
c6850bad74
commit
6bdcbfb25a
3 changed files with 38 additions and 27 deletions
|
@ -76,7 +76,7 @@ This is a C header file that is one of the first things included, and will persi
|
||||||
* `#define B7_AUDIO`
|
* `#define B7_AUDIO`
|
||||||
* enables audio on pin B7 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO)
|
* enables audio on pin B7 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO)
|
||||||
* `#define BACKLIGHT_PIN B7`
|
* `#define BACKLIGHT_PIN B7`
|
||||||
* pin of the backlight - B5, B6, B7 use PWM, others use softPWM
|
* pin of the backlight - `B5`, `B6`, `B7` and `C6` (and `D4` on ATmega32A) use hardware PWM, others use software implementation
|
||||||
* `#define BACKLIGHT_LEVELS 3`
|
* `#define BACKLIGHT_LEVELS 3`
|
||||||
* number of levels your backlight will have (maximum 15 excluding off)
|
* number of levels your backlight will have (maximum 15 excluding off)
|
||||||
* `#define BACKLIGHT_BREATHING`
|
* `#define BACKLIGHT_BREATHING`
|
||||||
|
|
|
@ -35,11 +35,12 @@ Hardware PWM is only supported on certain pins of the MCU, so if the backlightin
|
||||||
Hardware PWM is supported according to the following table:
|
Hardware PWM is supported according to the following table:
|
||||||
|
|
||||||
| Backlight Pin | Hardware timer |
|
| Backlight Pin | Hardware timer |
|
||||||
|---------------|----------------|
|
|---------------|-------------------------|
|
||||||
|`B5` | Timer 1 |
|
|`B5` | Timer 1 |
|
||||||
|`B6` | Timer 1 |
|
|`B6` | Timer 1 |
|
||||||
|`B7` | Timer 1 |
|
|`B7` | Timer 1 |
|
||||||
|`C6` | Timer 3 |
|
|`C6` | Timer 3 |
|
||||||
|
|`D4` | Timer 1 (ATmega32A only)|
|
||||||
| other | Software PWM |
|
| other | Software PWM |
|
||||||
|
|
||||||
The [audio feature](feature_audio.md) also uses hardware timers. Please refer to the following table to know what hardware timer the software PWM will use depending on the audio configuration:
|
The [audio feature](feature_audio.md) also uses hardware timers. Please refer to the following table to know what hardware timer the software PWM will use depending on the audio configuration:
|
||||||
|
|
|
@ -1027,35 +1027,49 @@ void matrix_scan_quantum() {
|
||||||
# define TCCRxB TCCR1B
|
# define TCCRxB TCCR1B
|
||||||
# define COMxx1 COM1C1
|
# define COMxx1 COM1C1
|
||||||
# define OCRxx OCR1C
|
# define OCRxx OCR1C
|
||||||
|
# define TIMERx_OVF_vect TIMER1_OVF_vect
|
||||||
|
# define TOIEx TOIE1
|
||||||
# define ICRx ICR1
|
# define ICRx ICR1
|
||||||
|
# define TIMSKx TIMSK1
|
||||||
#elif BACKLIGHT_PIN == B6
|
#elif BACKLIGHT_PIN == B6
|
||||||
# define HARDWARE_PWM
|
# define HARDWARE_PWM
|
||||||
# define TCCRxA TCCR1A
|
# define TCCRxA TCCR1A
|
||||||
# define TCCRxB TCCR1B
|
# define TCCRxB TCCR1B
|
||||||
# define COMxx1 COM1B1
|
# define COMxx1 COM1B1
|
||||||
# define OCRxx OCR1B
|
# define OCRxx OCR1B
|
||||||
|
# define TIMERx_OVF_vect TIMER1_OVF_vect
|
||||||
|
# define TOIEx TOIE1
|
||||||
# define ICRx ICR1
|
# define ICRx ICR1
|
||||||
|
# define TIMSKx TIMSK1
|
||||||
#elif BACKLIGHT_PIN == B5
|
#elif BACKLIGHT_PIN == B5
|
||||||
# define HARDWARE_PWM
|
# define HARDWARE_PWM
|
||||||
# define TCCRxA TCCR1A
|
# define TCCRxA TCCR1A
|
||||||
# define TCCRxB TCCR1B
|
# define TCCRxB TCCR1B
|
||||||
# define COMxx1 COM1A1
|
# define COMxx1 COM1A1
|
||||||
# define OCRxx OCR1A
|
# define OCRxx OCR1A
|
||||||
|
# define TIMERx_OVF_vect TIMER1_OVF_vect
|
||||||
|
# define TOIEx TOIE1
|
||||||
# define ICRx ICR1
|
# define ICRx ICR1
|
||||||
|
# define TIMSKx TIMSK1
|
||||||
#elif BACKLIGHT_PIN == C6
|
#elif BACKLIGHT_PIN == C6
|
||||||
# define HARDWARE_PWM
|
# define HARDWARE_PWM
|
||||||
# define TCCRxA TCCR3A
|
# define TCCRxA TCCR3A
|
||||||
# define TCCRxB TCCR3B
|
# define TCCRxB TCCR3B
|
||||||
# define COMxx1 COM1A1
|
# define COMxx1 COM3A1
|
||||||
# define OCRxx OCR3A
|
# define OCRxx OCR3A
|
||||||
|
# define TIMERx_OVF_vect TIMER3_OVF_vect
|
||||||
|
# define TOIEx TOIE3
|
||||||
# define ICRx ICR3
|
# define ICRx ICR3
|
||||||
|
# define TIMSKx TIMSK3
|
||||||
#elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4
|
#elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4
|
||||||
# define TCCRxA TCCR1A
|
# define TCCRxA TCCR1A
|
||||||
# define TCCRxB TCCR1B
|
# define TCCRxB TCCR1B
|
||||||
# define COMxx1 COM1B1
|
# define COMxx1 COM1B1
|
||||||
# define OCRxx OCR1B
|
# define OCRxx OCR1B
|
||||||
|
# define TIMERx_OVF_vect TIMER1_OVF_vect
|
||||||
|
# define TOIEx TOIE1
|
||||||
# define ICRx ICR1
|
# define ICRx ICR1
|
||||||
# define TIMSK1 TIMSK
|
# define TIMSKx TIMSK1
|
||||||
#else
|
#else
|
||||||
# if !defined(BACKLIGHT_CUSTOM_DRIVER)
|
# if !defined(BACKLIGHT_CUSTOM_DRIVER)
|
||||||
# if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO)
|
# if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO)
|
||||||
|
@ -1066,15 +1080,15 @@ void matrix_scan_quantum() {
|
||||||
# define TCCRxA TCCR1A
|
# define TCCRxA TCCR1A
|
||||||
# define TCCRxB TCCR1B
|
# define TCCRxB TCCR1B
|
||||||
# define OCRxx OCR1A
|
# define OCRxx OCR1A
|
||||||
# define OCRxAH OCR1AH
|
|
||||||
# define OCRxAL OCR1AL
|
|
||||||
# define TIMERx_COMPA_vect TIMER1_COMPA_vect
|
# define TIMERx_COMPA_vect TIMER1_COMPA_vect
|
||||||
# define TIMERx_OVF_vect TIMER1_OVF_vect
|
# define TIMERx_OVF_vect TIMER1_OVF_vect
|
||||||
# define OCIExA OCIE1A
|
# define OCIExA OCIE1A
|
||||||
# define TOIEx TOIE1
|
# define TOIEx TOIE1
|
||||||
# define ICRx ICR1
|
# define ICRx ICR1
|
||||||
# ifndef TIMSK
|
# if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register
|
||||||
# define TIMSK TIMSK1
|
# define TIMSKx TIMSK
|
||||||
|
# else
|
||||||
|
# define TIMSKx TIMSK1
|
||||||
# endif
|
# endif
|
||||||
# elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO)
|
# elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO)
|
||||||
#pragma message "Using hardware timer 3 with software PWM"
|
#pragma message "Using hardware timer 3 with software PWM"
|
||||||
|
@ -1084,16 +1098,12 @@ void matrix_scan_quantum() {
|
||||||
# define TCCRxA TCCR3A
|
# define TCCRxA TCCR3A
|
||||||
# define TCCRxB TCCR3B
|
# define TCCRxB TCCR3B
|
||||||
# define OCRxx OCR3A
|
# define OCRxx OCR3A
|
||||||
# define OCRxAH OCR3AH
|
|
||||||
# define OCRxAL OCR3AL
|
|
||||||
# define TIMERx_COMPA_vect TIMER3_COMPA_vect
|
# define TIMERx_COMPA_vect TIMER3_COMPA_vect
|
||||||
# define TIMERx_OVF_vect TIMER3_OVF_vect
|
# define TIMERx_OVF_vect TIMER3_OVF_vect
|
||||||
# define OCIExA OCIE3A
|
# define OCIExA OCIE3A
|
||||||
# define TOIEx TOIE3
|
# define TOIEx TOIE3
|
||||||
# define ICRx ICR1
|
# define ICRx ICR1
|
||||||
# ifndef TIMSK
|
# define TIMSKx TIMSK3
|
||||||
# define TIMSK TIMSK3
|
|
||||||
# endif
|
|
||||||
# else
|
# else
|
||||||
#pragma message "Audio in use - using pure software PWM"
|
#pragma message "Audio in use - using pure software PWM"
|
||||||
#define NO_HARDWARE_PWM
|
#define NO_HARDWARE_PWM
|
||||||
|
@ -1274,8 +1284,8 @@ void backlight_set(uint8_t level) {
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
#ifdef BACKLIGHT_PWM_TIMER
|
#ifdef BACKLIGHT_PWM_TIMER
|
||||||
if (OCRxx) {
|
if (OCRxx) {
|
||||||
TIMSK &= ~(_BV(OCIExA));
|
TIMSKx &= ~(_BV(OCIExA));
|
||||||
TIMSK &= ~(_BV(TOIEx));
|
TIMSKx &= ~(_BV(TOIEx));
|
||||||
FOR_EACH_LED(
|
FOR_EACH_LED(
|
||||||
backlight_off(backlight_pin);
|
backlight_off(backlight_pin);
|
||||||
)
|
)
|
||||||
|
@ -1287,8 +1297,8 @@ void backlight_set(uint8_t level) {
|
||||||
} else {
|
} else {
|
||||||
#ifdef BACKLIGHT_PWM_TIMER
|
#ifdef BACKLIGHT_PWM_TIMER
|
||||||
if (!OCRxx) {
|
if (!OCRxx) {
|
||||||
TIMSK |= _BV(OCIExA);
|
TIMSKx |= _BV(OCIExA);
|
||||||
TIMSK |= _BV(TOIEx);
|
TIMSKx |= _BV(TOIEx);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Turn on PWM control of backlight pin
|
// Turn on PWM control of backlight pin
|
||||||
|
@ -1325,11 +1335,11 @@ bool is_breathing(void) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
bool is_breathing(void) {
|
bool is_breathing(void) {
|
||||||
return !!(TIMSK1 & _BV(TOIE1));
|
return !!(TIMSKx & _BV(TOIEx));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define breathing_interrupt_enable() do {TIMSK1 |= _BV(TOIE1);} while (0)
|
#define breathing_interrupt_enable() do {TIMSKx |= _BV(TOIEx);} while (0)
|
||||||
#define breathing_interrupt_disable() do {TIMSK1 &= ~_BV(TOIE1);} while (0)
|
#define breathing_interrupt_disable() do {TIMSKx &= ~_BV(TOIEx);} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define breathing_min() do {breathing_counter = 0;} while (0)
|
#define breathing_min() do {breathing_counter = 0;} while (0)
|
||||||
|
@ -1411,7 +1421,7 @@ void breathing_task(void)
|
||||||
/* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
|
/* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
|
||||||
* about 244 times per second.
|
* about 244 times per second.
|
||||||
*/
|
*/
|
||||||
ISR(TIMER1_OVF_vect)
|
ISR(TIMERx_OVF_vect)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
|
uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
|
||||||
|
|
Loading…
Reference in a new issue