diff options
author | fauxpark <fauxpark@gmail.com> | 2019-08-09 06:12:12 +1000 |
---|---|---|
committer | Drashna Jaelre <drashna@live.com> | 2019-08-08 13:12:12 -0700 |
commit | 4d72aa428fb8dc72634bded428f78ffba2284fdc (patch) | |
tree | 4ff5ead1218accfb7650e79ec60697fb0ac22a2a /quantum/quantum.c | |
parent | 57540af102d034396c9f41a5a6e69ead8b10ba99 (diff) | |
download | qmk_firmware-4d72aa428fb8dc72634bded428f78ffba2284fdc.tar.gz qmk_firmware-4d72aa428fb8dc72634bded428f78ffba2284fdc.zip |
Improve backlight PWM pin support (#6202)
* Improve backlight PWM pin support
* I accidentally an equals sign
* Another typo
* Order by pin number
* Throw an error if backlight pin is C4 or C5 on 16/32U4
* Use else for clarity
* Minor alignment adjustments
Diffstat (limited to 'quantum/quantum.c')
-rw-r--r-- | quantum/quantum.c | 239 |
1 files changed, 141 insertions, 98 deletions
diff --git a/quantum/quantum.c b/quantum/quantum.c index d98c601d9..77cbbb2e7 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
@@ -1034,104 +1034,147 @@ void matrix_scan_quantum() { | |||
1034 | } | 1034 | } |
1035 | #if defined(BACKLIGHT_ENABLE) && (defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)) | 1035 | #if defined(BACKLIGHT_ENABLE) && (defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)) |
1036 | 1036 | ||
1037 | // The logic is a bit complex, we support 3 setups: | 1037 | // This logic is a bit complex, we support 3 setups: |
1038 | // 1. hardware PWM when backlight is wired to a PWM pin | 1038 | // |
1039 | // depending on this pin, we use a different output compare unit | 1039 | // 1. Hardware PWM when backlight is wired to a PWM pin. |
1040 | // 2. software PWM with hardware timers, but the used timer depends | 1040 | // Depending on this pin, we use a different output compare unit. |
1041 | // on the audio setup (audio wins other backlight) | 1041 | // 2. Software PWM with hardware timers, but the used timer |
1042 | // 3. full software PWM | 1042 | // depends on the Audio setup (Audio wins over Backlight). |
1043 | 1043 | // 3. Full software PWM, driven by the matrix scan, if both timers are used by Audio. | |
1044 | #if BACKLIGHT_PIN == B7 | 1044 | |
1045 | # define HARDWARE_PWM | 1045 | #if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) \ |
1046 | # define TCCRxA TCCR1A | 1046 | || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) \ |
1047 | # define TCCRxB TCCR1B | 1047 | || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) \ |
1048 | # define COMxx1 COM1C1 | 1048 | && (BACKLIGHT_PIN == B5 || BACKLIGHT_PIN == B6 || BACKLIGHT_PIN == B7) |
1049 | # define OCRxx OCR1C | 1049 | #define HARDWARE_PWM |
1050 | # define TIMERx_OVF_vect TIMER1_OVF_vect | 1050 | #define ICRx ICR1 |
1051 | # define TOIEx TOIE1 | 1051 | #define TCCRxA TCCR1A |
1052 | # define ICRx ICR1 | 1052 | #define TCCRxB TCCR1B |
1053 | # define TIMSKx TIMSK1 | 1053 | #define TIMERx_OVF_vect TIMER1_OVF_vect |
1054 | #elif BACKLIGHT_PIN == B6 | 1054 | #define TIMSKx TIMSK1 |
1055 | # define HARDWARE_PWM | 1055 | #define TOIEx TOIE1 |
1056 | # define TCCRxA TCCR1A | 1056 | |
1057 | # define TCCRxB TCCR1B | 1057 | #if BACKLIGHT_PIN == B5 |
1058 | # define COMxx1 COM1B1 | 1058 | #define COMxx1 COM1A1 |
1059 | # define OCRxx OCR1B | 1059 | #define OCRxx OCR1A |
1060 | # define TIMERx_OVF_vect TIMER1_OVF_vect | 1060 | #elif BACKLIGHT_PIN == B6 |
1061 | # define TOIEx TOIE1 | 1061 | #define COMxx1 COM1B1 |
1062 | # define ICRx ICR1 | 1062 | #define OCRxx OCR1B |
1063 | # define TIMSKx TIMSK1 | 1063 | #elif BACKLIGHT_PIN == B7 |
1064 | #elif BACKLIGHT_PIN == B5 | 1064 | #define COMxx1 COM1C1 |
1065 | # define HARDWARE_PWM | 1065 | #define OCRxx OCR1C |
1066 | # define TCCRxA TCCR1A | 1066 | #endif |
1067 | # define TCCRxB TCCR1B | 1067 | #elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) \ |
1068 | # define COMxx1 COM1A1 | 1068 | || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) \ |
1069 | # define OCRxx OCR1A | 1069 | || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) \ |
1070 | # define TIMERx_OVF_vect TIMER1_OVF_vect | 1070 | && (BACKLIGHT_PIN == C4 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6) |
1071 | # define TOIEx TOIE1 | 1071 | #define HARDWARE_PWM |
1072 | # define ICRx ICR1 | 1072 | #define ICRx ICR3 |
1073 | # define TIMSKx TIMSK1 | 1073 | #define TCCRxA TCCR3A |
1074 | #elif BACKLIGHT_PIN == C6 | 1074 | #define TCCRxB TCCR3B |
1075 | # define HARDWARE_PWM | 1075 | #define TIMERx_OVF_vect TIMER3_OVF_vect |
1076 | # define TCCRxA TCCR3A | 1076 | #define TIMSKx TIMSK3 |
1077 | # define TCCRxB TCCR3B | 1077 | #define TOIEx TOIE3 |
1078 | # define COMxx1 COM3A1 | 1078 | |
1079 | # define OCRxx OCR3A | 1079 | #if BACKLIGHT_PIN == C4 |
1080 | # define TIMERx_OVF_vect TIMER3_OVF_vect | 1080 | #if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) |
1081 | # define TOIEx TOIE3 | 1081 | #error This MCU has no C4 pin! |
1082 | # define ICRx ICR3 | 1082 | #else |
1083 | # define TIMSKx TIMSK3 | 1083 | #define COMxx1 COM3C1 |
1084 | #elif defined(__AVR_ATmega32A__) && BACKLIGHT_PIN == D4 | 1084 | #define OCRxx OCR3C |
1085 | # define TCCRxA TCCR1A | 1085 | #endif |
1086 | # define TCCRxB TCCR1B | 1086 | #elif BACKLIGHT_PIN == C5 |
1087 | # define COMxx1 COM1B1 | 1087 | #if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) |
1088 | # define OCRxx OCR1B | 1088 | #error This MCU has no C5 pin! |
1089 | # define TIMERx_OVF_vect TIMER1_OVF_vect | 1089 | #else |
1090 | # define TOIEx TOIE1 | 1090 | #define COMxx1 COM3B1 |
1091 | # define ICRx ICR1 | 1091 | #define OCRxx OCR3B |
1092 | # define TIMSKx TIMSK1 | 1092 | #endif |
1093 | #elif BACKLIGHT_PIN == C6 | ||
1094 | #define COMxx1 COM3A1 | ||
1095 | #define OCRxx OCR3A | ||
1096 | #endif | ||
1097 | #elif (defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__)) \ | ||
1098 | && (BACKLIGHT_PIN == B7 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6) | ||
1099 | #define HARDWARE_PWM | ||
1100 | #define ICRx ICR1 | ||
1101 | #define TCCRxA TCCR1A | ||
1102 | #define TCCRxB TCCR1B | ||
1103 | #define TIMERx_OVF_vect TIMER1_OVF_vect | ||
1104 | #define TIMSKx TIMSK1 | ||
1105 | #define TOIEx TOIE1 | ||
1106 | |||
1107 | #if BACKLIGHT_PIN == B7 | ||
1108 | #define COMxx1 COM1C1 | ||
1109 | #define OCRxx OCR1C | ||
1110 | #elif BACKLIGHT_PIN == C5 | ||
1111 | #define COMxx1 COM1B1 | ||
1112 | #define OCRxx OCR1B | ||
1113 | #elif BACKLIGHT_PIN == C6 | ||
1114 | #define COMxx1 COM1A1 | ||
1115 | #define OCRxx OCR1A | ||
1116 | #endif | ||
1117 | #elif defined(__AVR_ATmega32A__) \ | ||
1118 | && (BACKLIGHT_PIN == D4 || BACKLIGHT_PIN == D5) | ||
1119 | #define HARDWARE_PWM | ||
1120 | #define ICRx ICR1 | ||
1121 | #define TCCRxA TCCR1A | ||
1122 | #define TCCRxB TCCR1B | ||
1123 | #define TIMERx_OVF_vect TIMER1_OVF_vect | ||
1124 | #define TIMSKx TIMSK | ||
1125 | #define TOIEx TOIE1 | ||
1126 | |||
1127 | #if BACKLIGHT_PIN == D4 | ||
1128 | #define COMxx1 COM1B1 | ||
1129 | #define OCRxx OCR1B | ||
1130 | #elif BACKLIGHT_PIN == D5 | ||
1131 | #define COMxx1 COM1A1 | ||
1132 | #define OCRxx OCR1A | ||
1133 | #endif | ||
1093 | #else | 1134 | #else |
1094 | # if !defined(BACKLIGHT_CUSTOM_DRIVER) | 1135 | #if !defined(BACKLIGHT_CUSTOM_DRIVER) |
1095 | # if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO) | 1136 | #if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO) |
1096 | // timer 1 is not used by audio , backlight can use it | 1137 | // Timer 1 is not in use by Audio feature, Backlight can use it |
1097 | #pragma message "Using hardware timer 1 with software PWM" | 1138 | #pragma message "Using hardware timer 1 with software PWM" |
1098 | # define HARDWARE_PWM | 1139 | #define HARDWARE_PWM |
1099 | # define BACKLIGHT_PWM_TIMER | 1140 | #define BACKLIGHT_PWM_TIMER |
1100 | # define TCCRxA TCCR1A | 1141 | #define ICRx ICR1 |
1101 | # define TCCRxB TCCR1B | 1142 | #define TCCRxA TCCR1A |
1102 | # define OCRxx OCR1A | 1143 | #define TCCRxB TCCR1B |
1103 | # define TIMERx_COMPA_vect TIMER1_COMPA_vect | 1144 | #define TIMERx_COMPA_vect TIMER1_COMPA_vect |
1104 | # define TIMERx_OVF_vect TIMER1_OVF_vect | 1145 | #define TIMERx_OVF_vect TIMER1_OVF_vect |
1105 | # define OCIExA OCIE1A | 1146 | #if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register |
1106 | # define TOIEx TOIE1 | 1147 | #define TIMSKx TIMSK |
1107 | # define ICRx ICR1 | 1148 | #else |
1108 | # if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register | 1149 | #define TIMSKx TIMSK1 |
1109 | # define TIMSKx TIMSK | 1150 | #endif |
1110 | # else | 1151 | #define TOIEx TOIE1 |
1111 | # define TIMSKx TIMSK1 | 1152 | |
1112 | # endif | 1153 | #define OCIExA OCIE1A |
1113 | # elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO) | 1154 | #define OCRxx OCR1A |
1114 | #pragma message "Using hardware timer 3 with software PWM" | 1155 | #elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO) |
1115 | // timer 3 is not used by audio, backlight can use it | 1156 | #pragma message "Using hardware timer 3 with software PWM" |
1116 | # define HARDWARE_PWM | 1157 | // Timer 3 is not in use by Audio feature, Backlight can use it |
1117 | # define BACKLIGHT_PWM_TIMER | 1158 | #define HARDWARE_PWM |
1118 | # define TCCRxA TCCR3A | 1159 | #define BACKLIGHT_PWM_TIMER |
1119 | # define TCCRxB TCCR3B | 1160 | #define ICRx ICR1 |
1120 | # define OCRxx OCR3A | 1161 | #define TCCRxA TCCR3A |
1121 | # define TIMERx_COMPA_vect TIMER3_COMPA_vect | 1162 | #define TCCRxB TCCR3B |
1122 | # define TIMERx_OVF_vect TIMER3_OVF_vect | 1163 | #define TIMERx_COMPA_vect TIMER3_COMPA_vect |
1123 | # define OCIExA OCIE3A | 1164 | #define TIMERx_OVF_vect TIMER3_OVF_vect |
1124 | # define TOIEx TOIE3 | 1165 | #define TIMSKx TIMSK3 |
1125 | # define ICRx ICR1 | 1166 | #define TOIEx TOIE3 |
1126 | # define TIMSKx TIMSK3 | 1167 | |
1127 | # else | 1168 | #define OCIExA OCIE3A |
1128 | #pragma message "Audio in use - using pure software PWM" | 1169 | #define OCRxx OCR3A |
1129 | #define NO_HARDWARE_PWM | 1170 | #else |
1130 | # endif | 1171 | #pragma message "Audio in use - using pure software PWM" |
1131 | # else | 1172 | #define NO_HARDWARE_PWM |
1132 | #pragma message "Custom driver defined - using pure software PWM" | 1173 | #endif |
1133 | #define NO_HARDWARE_PWM | 1174 | #else |
1134 | # endif | 1175 | #pragma message "Custom driver defined - using pure software PWM" |
1176 | #define NO_HARDWARE_PWM | ||
1177 | #endif | ||
1135 | #endif | 1178 | #endif |
1136 | 1179 | ||
1137 | #ifndef BACKLIGHT_ON_STATE | 1180 | #ifndef BACKLIGHT_ON_STATE |
@@ -1300,7 +1343,7 @@ static uint16_t cie_lightness(uint16_t v) { | |||
1300 | 1343 | ||
1301 | // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val. | 1344 | // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val. |
1302 | static inline void set_pwm(uint16_t val) { | 1345 | static inline void set_pwm(uint16_t val) { |
1303 | OCRxx = val; | 1346 | OCRxx = val; |
1304 | } | 1347 | } |
1305 | 1348 | ||
1306 | #ifndef BACKLIGHT_CUSTOM_DRIVER | 1349 | #ifndef BACKLIGHT_CUSTOM_DRIVER |