]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Fix backlight breathing on C6 (#6102)
authorfauxpark <fauxpark@gmail.com>
Tue, 18 Jun 2019 02:37:17 +0000 (12:37 +1000)
committerDrashna Jaelre <drashna@live.com>
Tue, 18 Jun 2019 02:37:17 +0000 (19:37 -0700)
* 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

docs/config_options.md
docs/feature_backlight.md
quantum/quantum.c

index f4035809a7870e5e18a9c962e4679a6ff800709f..55d25d4c88dd612f485429966f1014b50c5afb9d 100644 (file)
@@ -76,7 +76,7 @@ This is a C header file that is one of the first things included, and will persi
 * `#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)
 * `#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`
   * number of levels your backlight will have (maximum 15 excluding off)
 * `#define BACKLIGHT_BREATHING`
index 048d75390df6ff7b0992d7ee60bdde925feb42e6..5a21a679017a4f3378a2f3af9c0cee2db324652d 100644 (file)
@@ -34,13 +34,14 @@ Hardware PWM is only supported on certain pins of the MCU, so if the backlightin
 
 Hardware PWM is supported according to the following table:
 
-| Backlight Pin | Hardware timer |
-|---------------|----------------|
-|`B5`           | Timer 1        |
-|`B6`           | Timer 1        |
-|`B7`           | Timer 1        |
-|`C6`           | Timer 3        |
-| other         | Software PWM   |
+| Backlight Pin | Hardware timer          |
+|---------------|-------------------------|
+|`B5`           | Timer 1                 |
+|`B6`           | Timer 1                 |
+|`B7`           | Timer 1                 |
+|`C6`           | Timer 3                 |
+|`D4`           | Timer 1 (ATmega32A only)|
+| 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:
 
index 23263b7007d7f4c4d3f38c3b62a16f98b8061220..36b7942d5d8d73a02f4993711d7a14dbe20ac0e8 100644 (file)
@@ -1027,35 +1027,49 @@ void matrix_scan_quantum() {
 #  define TCCRxB TCCR1B
 #  define COMxx1 COM1C1
 #  define OCRxx  OCR1C
+#  define TIMERx_OVF_vect TIMER1_OVF_vect
+#  define TOIEx  TOIE1
 #  define ICRx   ICR1
+#  define TIMSKx TIMSK1
 #elif BACKLIGHT_PIN == B6
 #  define HARDWARE_PWM
 #  define TCCRxA TCCR1A
 #  define TCCRxB TCCR1B
 #  define COMxx1 COM1B1
 #  define OCRxx  OCR1B
+#  define TIMERx_OVF_vect TIMER1_OVF_vect
+#  define TOIEx  TOIE1
 #  define ICRx   ICR1
+#  define TIMSKx TIMSK1
 #elif BACKLIGHT_PIN == B5
 #  define HARDWARE_PWM
 #  define TCCRxA TCCR1A
 #  define TCCRxB TCCR1B
 #  define COMxx1 COM1A1
 #  define OCRxx  OCR1A
+#  define TIMERx_OVF_vect TIMER1_OVF_vect
+#  define TOIEx  TOIE1
 #  define ICRx   ICR1
+#  define TIMSKx TIMSK1
 #elif BACKLIGHT_PIN == C6
 #  define HARDWARE_PWM
 #  define TCCRxA TCCR3A
 #  define TCCRxB TCCR3B
-#  define COMxx1 COM1A1
+#  define COMxx1 COM3A1
 #  define OCRxx  OCR3A
+#  define TIMERx_OVF_vect TIMER3_OVF_vect
+#  define TOIEx  TOIE3
 #  define ICRx   ICR3
+#  define TIMSKx TIMSK3
 #elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4
 #  define TCCRxA TCCR1A
 #  define TCCRxB TCCR1B
 #  define COMxx1 COM1B1
 #  define OCRxx  OCR1B
+#  define TIMERx_OVF_vect TIMER1_OVF_vect
+#  define TOIEx  TOIE1
 #  define ICRx   ICR1
-#  define TIMSK1 TIMSK
+#  define TIMSKx TIMSK1
 #else
 #  if !defined(BACKLIGHT_CUSTOM_DRIVER)
 #    if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO)
@@ -1066,15 +1080,15 @@ void matrix_scan_quantum() {
 #      define TCCRxA TCCR1A
 #      define TCCRxB TCCR1B
 #      define OCRxx  OCR1A
-#      define OCRxAH OCR1AH
-#      define OCRxAL OCR1AL
 #      define TIMERx_COMPA_vect TIMER1_COMPA_vect
 #      define TIMERx_OVF_vect TIMER1_OVF_vect
 #      define OCIExA OCIE1A
 #      define TOIEx  TOIE1
 #      define ICRx   ICR1
-#      ifndef TIMSK
-#        define TIMSK TIMSK1
+#      if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register
+#        define TIMSKx TIMSK
+#      else
+#        define TIMSKx TIMSK1
 #      endif
 #    elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO)
 #pragma message "Using hardware timer 3 with software PWM"
@@ -1084,16 +1098,12 @@ void matrix_scan_quantum() {
 #      define TCCRxA TCCR3A
 #      define TCCRxB TCCR3B
 #      define OCRxx OCR3A
-#      define OCRxAH OCR3AH
-#      define OCRxAL OCR3AL
 #      define TIMERx_COMPA_vect TIMER3_COMPA_vect
 #      define TIMERx_OVF_vect TIMER3_OVF_vect
 #      define OCIExA OCIE3A
 #      define TOIEx  TOIE3
 #      define ICRx   ICR1
-#      ifndef TIMSK
-#        define TIMSK TIMSK3
-#      endif
+#      define TIMSKx TIMSK3
 #    else
 #pragma message "Audio in use - using pure software PWM"
 #define NO_HARDWARE_PWM
@@ -1274,8 +1284,8 @@ void backlight_set(uint8_t level) {
   if (level == 0) {
     #ifdef BACKLIGHT_PWM_TIMER
       if (OCRxx) {
-        TIMSK &= ~(_BV(OCIExA));
-        TIMSK &= ~(_BV(TOIEx));
+        TIMSKx &= ~(_BV(OCIExA));
+        TIMSKx &= ~(_BV(TOIEx));
         FOR_EACH_LED(
           backlight_off(backlight_pin);
         )
@@ -1287,8 +1297,8 @@ void backlight_set(uint8_t level) {
   } else {
     #ifdef BACKLIGHT_PWM_TIMER
       if (!OCRxx) {
-        TIMSK |= _BV(OCIExA);
-        TIMSK |= _BV(TOIEx);
+        TIMSKx |= _BV(OCIExA);
+        TIMSKx |= _BV(TOIEx);
       }
     #else
     // Turn on PWM control of backlight pin
@@ -1325,11 +1335,11 @@ bool is_breathing(void) {
 #else
 
 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_disable() do {TIMSK1 &= ~_BV(TOIE1);} while (0)
+#define breathing_interrupt_enable() do {TIMSKx |= _BV(TOIEx);} while (0)
+#define breathing_interrupt_disable() do {TIMSKx &= ~_BV(TOIEx);} while (0)
 #endif
 
 #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
  * about 244 times per second.
  */
-ISR(TIMER1_OVF_vect)
+ISR(TIMERx_OVF_vect)
 #endif
 {
   uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;