|
@@ -34,27 +34,27 @@ struct Timer {
|
34
|
34
|
};
|
35
|
35
|
|
36
|
36
|
// Macros for the Timer structure
|
37
|
|
-#define _SET_WGMnQ(TCCRnQ, V) do{ \
|
38
|
|
- *(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
|
39
|
|
- *(TCCRnQ)[1] = (*(TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
|
|
37
|
+#define _SET_WGMnQ(T, V) do{ \
|
|
38
|
+ *(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
|
|
39
|
+ *(T.TCCRnQ)[1] = (*(T.TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
|
40
|
40
|
}while(0)
|
41
|
41
|
|
42
|
42
|
// Set TCCR CS bits
|
43
|
|
-#define _SET_CSn(TCCRnQ, V) (*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0))
|
|
43
|
+#define _SET_CSn(T, V) (*(T.TCCRnQ)[1] = (*(T.TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0))
|
44
|
44
|
|
45
|
45
|
// Set TCCR COM bits
|
46
|
|
-#define _SET_COMnQ(TCCRnQ, Q, V) (*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q))))
|
|
46
|
+#define _SET_COMnQ(T, Q, V) (*(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q))))
|
47
|
47
|
|
48
|
48
|
// Set OCRnQ register
|
49
|
|
-#define _SET_OCRnQ(OCRnQ, Q, V) (*(OCRnQ)[Q] = int(V) & 0xFFFF)
|
|
49
|
+#define _SET_OCRnQ(T, Q, V) (*(T.OCRnQ)[Q] = int(V) & 0xFFFF)
|
50
|
50
|
|
51
|
51
|
// Set ICRn register (one per timer)
|
52
|
|
-#define _SET_ICRn(ICRn, V) (*(ICRn) = int(V) & 0xFFFF)
|
|
52
|
+#define _SET_ICRn(T, V) (*(T.ICRn) = int(V) & 0xFFFF)
|
53
|
53
|
|
54
|
54
|
/**
|
55
|
55
|
* Return a Timer struct describing a pin's timer.
|
56
|
56
|
*/
|
57
|
|
-Timer get_pwm_timer(const pin_t pin) {
|
|
57
|
+const Timer get_pwm_timer(const pin_t pin) {
|
58
|
58
|
|
59
|
59
|
uint8_t q = 0;
|
60
|
60
|
|
|
@@ -108,7 +108,7 @@ Timer get_pwm_timer(const pin_t pin) {
|
108
|
108
|
}
|
109
|
109
|
|
110
|
110
|
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
|
111
|
|
- Timer timer = get_pwm_timer(pin);
|
|
111
|
+ const Timer timer = get_pwm_timer(pin);
|
112
|
112
|
if (timer.isProtected || !timer.isPWM) return; // Don't proceed if protected timer or not recognized
|
113
|
113
|
|
114
|
114
|
const bool is_timer2 = timer.n == 2;
|
|
@@ -166,14 +166,14 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
|
166
|
166
|
}
|
167
|
167
|
}
|
168
|
168
|
|
169
|
|
- _SET_WGMnQ(timer.TCCRnQ, wgm);
|
170
|
|
- _SET_CSn(timer.TCCRnQ, j);
|
|
169
|
+ _SET_WGMnQ(timer, wgm);
|
|
170
|
+ _SET_CSn(timer, j);
|
171
|
171
|
|
172
|
172
|
if (is_timer2) {
|
173
|
|
- TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer.OCRnQ, 0, res)); // Set OCR2A value (TOP) = res
|
|
173
|
+ TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer, 0, res)); // Set OCR2A value (TOP) = res
|
174
|
174
|
}
|
175
|
175
|
else
|
176
|
|
- _SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res
|
|
176
|
+ _SET_ICRn(timer, res); // Set ICRn value (TOP) = res
|
177
|
177
|
}
|
178
|
178
|
|
179
|
179
|
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
|
|
@@ -184,7 +184,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
|
184
|
184
|
else if (v == v_size)
|
185
|
185
|
digitalWrite(pin, !invert);
|
186
|
186
|
else {
|
187
|
|
- Timer timer = get_pwm_timer(pin);
|
|
187
|
+ const Timer timer = get_pwm_timer(pin);
|
188
|
188
|
if (timer.isPWM) {
|
189
|
189
|
if (timer.n == 0) {
|
190
|
190
|
TCCR0A |= _BV(COM0B1); // Only allow a TIMER0B select and OCR0B duty update for pin D4 outputs no frequency changes are permited.
|
|
@@ -192,8 +192,8 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
|
192
|
192
|
}
|
193
|
193
|
else if (!timer.isProtected) {
|
194
|
194
|
const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn;
|
195
|
|
- _SET_COMnQ(timer.TCCRnQ, SUM_TERN(HAS_TCCR2, timer.q, timer.q == 2), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2
|
196
|
|
- _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value
|
|
195
|
+ _SET_COMnQ(timer, SUM_TERN(HAS_TCCR2, timer.q, timer.q == 2), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2
|
|
196
|
+ _SET_OCRnQ(timer, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value
|
197
|
197
|
}
|
198
|
198
|
}
|
199
|
199
|
else
|