aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfauxpark <fauxpark@gmail.com>2019-06-18 12:37:17 +1000
committerDrashna Jaelre <drashna@live.com>2019-06-17 19:37:17 -0700
commit6bdcbfb25ae068d9f5351af0f7c6a03385020661 (patch)
treec5c3e95ba361d1dc90600ecddff5550c07206965
parentc6850bad74ccec3cec0af1c74eb20b139d0ca481 (diff)
downloadqmk_firmware-6bdcbfb25ae068d9f5351af0f7c6a03385020661.tar.gz
qmk_firmware-6bdcbfb25ae068d9f5351af0f7c6a03385020661.zip
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
-rw-r--r--docs/config_options.md2
-rw-r--r--docs/feature_backlight.md15
-rw-r--r--quantum/quantum.c48
3 files changed, 38 insertions, 27 deletions
diff --git a/docs/config_options.md b/docs/config_options.md
index f4035809a..55d25d4c8 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -76,7 +76,7 @@ This is a C header file that is one of the first things included, and will persi
76* `#define B7_AUDIO` 76* `#define B7_AUDIO`
77 * 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) 77 * 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)
78* `#define BACKLIGHT_PIN B7` 78* `#define BACKLIGHT_PIN B7`
79 * pin of the backlight - B5, B6, B7 use PWM, others use softPWM 79 * pin of the backlight - `B5`, `B6`, `B7` and `C6` (and `D4` on ATmega32A) use hardware PWM, others use software implementation
80* `#define BACKLIGHT_LEVELS 3` 80* `#define BACKLIGHT_LEVELS 3`
81 * number of levels your backlight will have (maximum 15 excluding off) 81 * number of levels your backlight will have (maximum 15 excluding off)
82* `#define BACKLIGHT_BREATHING` 82* `#define BACKLIGHT_BREATHING`
diff --git a/docs/feature_backlight.md b/docs/feature_backlight.md
index 048d75390..5a21a6790 100644
--- a/docs/feature_backlight.md
+++ b/docs/feature_backlight.md
@@ -34,13 +34,14 @@ Hardware PWM is only supported on certain pins of the MCU, so if the backlightin
34 34
35Hardware PWM is supported according to the following table: 35Hardware PWM is supported according to the following table:
36 36
37| Backlight Pin | Hardware timer | 37| Backlight Pin | Hardware timer |
38|---------------|----------------| 38|---------------|-------------------------|
39|`B5` | Timer 1 | 39|`B5` | Timer 1 |
40|`B6` | Timer 1 | 40|`B6` | Timer 1 |
41|`B7` | Timer 1 | 41|`B7` | Timer 1 |
42|`C6` | Timer 3 | 42|`C6` | Timer 3 |
43| other | Software PWM | 43|`D4` | Timer 1 (ATmega32A only)|
44| other | Software PWM |
44 45
45The [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: 46The [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:
46 47
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 23263b700..36b7942d5 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -1027,35 +1027,49 @@ void matrix_scan_quantum() {
1027# define TCCRxB TCCR1B 1027# define TCCRxB TCCR1B
1028# define COMxx1 COM1C1 1028# define COMxx1 COM1C1
1029# define OCRxx OCR1C 1029# define OCRxx OCR1C
1030# define TIMERx_OVF_vect TIMER1_OVF_vect
1031# define TOIEx TOIE1
1030# define ICRx ICR1 1032# define ICRx ICR1
1033# define TIMSKx TIMSK1
1031#elif BACKLIGHT_PIN == B6 1034#elif BACKLIGHT_PIN == B6
1032# define HARDWARE_PWM 1035# define HARDWARE_PWM
1033# define TCCRxA TCCR1A 1036# define TCCRxA TCCR1A
1034# define TCCRxB TCCR1B 1037# define TCCRxB TCCR1B
1035# define COMxx1 COM1B1 1038# define COMxx1 COM1B1
1036# define OCRxx OCR1B 1039# define OCRxx OCR1B
1040# define TIMERx_OVF_vect TIMER1_OVF_vect
1041# define TOIEx TOIE1
1037# define ICRx ICR1 1042# define ICRx ICR1
1043# define TIMSKx TIMSK1
1038#elif BACKLIGHT_PIN == B5 1044#elif BACKLIGHT_PIN == B5
1039# define HARDWARE_PWM 1045# define HARDWARE_PWM
1040# define TCCRxA TCCR1A 1046# define TCCRxA TCCR1A
1041# define TCCRxB TCCR1B 1047# define TCCRxB TCCR1B
1042# define COMxx1 COM1A1 1048# define COMxx1 COM1A1
1043# define OCRxx OCR1A 1049# define OCRxx OCR1A
1050# define TIMERx_OVF_vect TIMER1_OVF_vect
1051# define TOIEx TOIE1
1044# define ICRx ICR1 1052# define ICRx ICR1
1053# define TIMSKx TIMSK1
1045#elif BACKLIGHT_PIN == C6 1054#elif BACKLIGHT_PIN == C6
1046# define HARDWARE_PWM 1055# define HARDWARE_PWM
1047# define TCCRxA TCCR3A 1056# define TCCRxA TCCR3A
1048# define TCCRxB TCCR3B 1057# define TCCRxB TCCR3B
1049# define COMxx1 COM1A1 1058# define COMxx1 COM3A1
1050# define OCRxx OCR3A 1059# define OCRxx OCR3A
1060# define TIMERx_OVF_vect TIMER3_OVF_vect
1061# define TOIEx TOIE3
1051# define ICRx ICR3 1062# define ICRx ICR3
1063# define TIMSKx TIMSK3
1052#elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4 1064#elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4
1053# define TCCRxA TCCR1A 1065# define TCCRxA TCCR1A
1054# define TCCRxB TCCR1B 1066# define TCCRxB TCCR1B
1055# define COMxx1 COM1B1 1067# define COMxx1 COM1B1
1056# define OCRxx OCR1B 1068# define OCRxx OCR1B
1069# define TIMERx_OVF_vect TIMER1_OVF_vect
1070# define TOIEx TOIE1
1057# define ICRx ICR1 1071# define ICRx ICR1
1058# define TIMSK1 TIMSK 1072# define TIMSKx TIMSK1
1059#else 1073#else
1060# if !defined(BACKLIGHT_CUSTOM_DRIVER) 1074# if !defined(BACKLIGHT_CUSTOM_DRIVER)
1061# if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO) 1075# if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO)
@@ -1066,15 +1080,15 @@ void matrix_scan_quantum() {
1066# define TCCRxA TCCR1A 1080# define TCCRxA TCCR1A
1067# define TCCRxB TCCR1B 1081# define TCCRxB TCCR1B
1068# define OCRxx OCR1A 1082# define OCRxx OCR1A
1069# define OCRxAH OCR1AH
1070# define OCRxAL OCR1AL
1071# define TIMERx_COMPA_vect TIMER1_COMPA_vect 1083# define TIMERx_COMPA_vect TIMER1_COMPA_vect
1072# define TIMERx_OVF_vect TIMER1_OVF_vect 1084# define TIMERx_OVF_vect TIMER1_OVF_vect
1073# define OCIExA OCIE1A 1085# define OCIExA OCIE1A
1074# define TOIEx TOIE1 1086# define TOIEx TOIE1
1075# define ICRx ICR1 1087# define ICRx ICR1
1076# ifndef TIMSK 1088# if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register
1077# define TIMSK TIMSK1 1089# define TIMSKx TIMSK
1090# else
1091# define TIMSKx TIMSK1
1078# endif 1092# endif
1079# elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO) 1093# elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO)
1080#pragma message "Using hardware timer 3 with software PWM" 1094#pragma message "Using hardware timer 3 with software PWM"
@@ -1084,16 +1098,12 @@ void matrix_scan_quantum() {
1084# define TCCRxA TCCR3A 1098# define TCCRxA TCCR3A
1085# define TCCRxB TCCR3B 1099# define TCCRxB TCCR3B
1086# define OCRxx OCR3A 1100# define OCRxx OCR3A
1087# define OCRxAH OCR3AH
1088# define OCRxAL OCR3AL
1089# define TIMERx_COMPA_vect TIMER3_COMPA_vect 1101# define TIMERx_COMPA_vect TIMER3_COMPA_vect
1090# define TIMERx_OVF_vect TIMER3_OVF_vect 1102# define TIMERx_OVF_vect TIMER3_OVF_vect
1091# define OCIExA OCIE3A 1103# define OCIExA OCIE3A
1092# define TOIEx TOIE3 1104# define TOIEx TOIE3
1093# define ICRx ICR1 1105# define ICRx ICR1
1094# ifndef TIMSK 1106# define TIMSKx TIMSK3
1095# define TIMSK TIMSK3
1096# endif
1097# else 1107# else
1098#pragma message "Audio in use - using pure software PWM" 1108#pragma message "Audio in use - using pure software PWM"
1099#define NO_HARDWARE_PWM 1109#define NO_HARDWARE_PWM
@@ -1274,8 +1284,8 @@ void backlight_set(uint8_t level) {
1274 if (level == 0) { 1284 if (level == 0) {
1275 #ifdef BACKLIGHT_PWM_TIMER 1285 #ifdef BACKLIGHT_PWM_TIMER
1276 if (OCRxx) { 1286 if (OCRxx) {
1277 TIMSK &= ~(_BV(OCIExA)); 1287 TIMSKx &= ~(_BV(OCIExA));
1278 TIMSK &= ~(_BV(TOIEx)); 1288 TIMSKx &= ~(_BV(TOIEx));
1279 FOR_EACH_LED( 1289 FOR_EACH_LED(
1280 backlight_off(backlight_pin); 1290 backlight_off(backlight_pin);
1281 ) 1291 )
@@ -1287,8 +1297,8 @@ void backlight_set(uint8_t level) {
1287 } else { 1297 } else {
1288 #ifdef BACKLIGHT_PWM_TIMER 1298 #ifdef BACKLIGHT_PWM_TIMER
1289 if (!OCRxx) { 1299 if (!OCRxx) {
1290 TIMSK |= _BV(OCIExA); 1300 TIMSKx |= _BV(OCIExA);
1291 TIMSK |= _BV(TOIEx); 1301 TIMSKx |= _BV(TOIEx);
1292 } 1302 }
1293 #else 1303 #else
1294 // Turn on PWM control of backlight pin 1304 // Turn on PWM control of backlight pin
@@ -1325,11 +1335,11 @@ bool is_breathing(void) {
1325#else 1335#else
1326 1336
1327bool is_breathing(void) { 1337bool is_breathing(void) {
1328 return !!(TIMSK1 & _BV(TOIE1)); 1338 return !!(TIMSKx & _BV(TOIEx));
1329} 1339}
1330 1340
1331#define breathing_interrupt_enable() do {TIMSK1 |= _BV(TOIE1);} while (0) 1341#define breathing_interrupt_enable() do {TIMSKx |= _BV(TOIEx);} while (0)
1332#define breathing_interrupt_disable() do {TIMSK1 &= ~_BV(TOIE1);} while (0) 1342#define breathing_interrupt_disable() do {TIMSKx &= ~_BV(TOIEx);} while (0)
1333#endif 1343#endif
1334 1344
1335#define breathing_min() do {breathing_counter = 0;} while (0) 1345#define breathing_min() do {breathing_counter = 0;} while (0)
@@ -1411,7 +1421,7 @@ void breathing_task(void)
1411/* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run 1421/* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
1412 * about 244 times per second. 1422 * about 244 times per second.
1413 */ 1423 */
1414ISR(TIMER1_OVF_vect) 1424ISR(TIMERx_OVF_vect)
1415#endif 1425#endif
1416{ 1426{
1417 uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS; 1427 uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;