@@ -53,47 +53,36 @@ static void syncTCC(Tcc* TCCx) {
53
53
while (TCCx -> SYNCBUSY .reg & TCC_SYNCBUSY_MASK );
54
54
}
55
55
56
- void analogReadResolution ( int res )
56
+ void analogReadResolution (int res )
57
57
{
58
- _readResolution = res ;
59
- if (res > 10 )
60
- {
58
+ _readResolution = res ;
59
+ if (res > 10 ) {
61
60
ADC -> CTRLB .bit .RESSEL = ADC_CTRLB_RESSEL_12BIT_Val ;
62
61
_ADCResolution = 12 ;
63
- }
64
- else if (res > 8 )
65
- {
62
+ } else if (res > 8 ) {
66
63
ADC -> CTRLB .bit .RESSEL = ADC_CTRLB_RESSEL_10BIT_Val ;
67
64
_ADCResolution = 10 ;
68
- }
69
- else
70
- {
65
+ } else {
71
66
ADC -> CTRLB .bit .RESSEL = ADC_CTRLB_RESSEL_8BIT_Val ;
72
67
_ADCResolution = 8 ;
73
68
}
74
69
syncADC ();
75
70
}
76
71
77
- void analogWriteResolution ( int res )
72
+ void analogWriteResolution (int res )
78
73
{
79
- _writeResolution = res ;
74
+ _writeResolution = res ;
80
75
}
81
76
82
- static inline uint32_t mapResolution ( uint32_t value , uint32_t from , uint32_t to )
77
+ static inline uint32_t mapResolution (uint32_t value , uint32_t from , uint32_t to )
83
78
{
84
- if ( from == to )
85
- {
86
- return value ;
79
+ if (from == to ) {
80
+ return value ;
87
81
}
88
-
89
- if ( from > to )
90
- {
91
- return value >> (from - to ) ;
92
- }
93
- else
94
- {
95
- return value << (to - from ) ;
82
+ if (from > to ) {
83
+ return value >> (from - to );
96
84
}
85
+ return value << (to - from );
97
86
}
98
87
99
88
/*
@@ -102,10 +91,10 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to
102
91
*
103
92
* Warning : On Arduino Zero board the input/output voltage for SAMD21G18 is 3.3 volts maximum
104
93
*/
105
- void analogReference ( eAnalogReference ulMode )
94
+ void analogReference (eAnalogReference mode )
106
95
{
107
96
syncADC ();
108
- switch ( ulMode )
97
+ switch (mode )
109
98
{
110
99
case AR_INTERNAL :
111
100
case AR_INTERNAL2V23 :
@@ -136,27 +125,25 @@ void analogReference( eAnalogReference ulMode )
136
125
}
137
126
}
138
127
139
- uint32_t analogRead ( uint32_t ulPin )
128
+ uint32_t analogRead (uint32_t pin )
140
129
{
141
130
uint32_t valueRead = 0 ;
142
131
143
- if ( ulPin < A0 )
144
- {
145
- ulPin += A0 ;
132
+ if (pin < A0 ) {
133
+ pin += A0 ;
146
134
}
147
135
148
- pinPeripheral (ulPin , PIO_ANALOG );
136
+ pinPeripheral (pin , PIO_ANALOG );
149
137
150
- if (ulPin == A0 ) // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
151
- {
138
+ if (pin == A0 ) { // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
152
139
syncDAC ();
153
140
DAC -> CTRLA .bit .ENABLE = 0x00 ; // Disable DAC
154
141
//DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off.
155
142
syncDAC ();
156
143
}
157
144
158
145
syncADC ();
159
- ADC -> INPUTCTRL .bit .MUXPOS = g_APinDescription [ulPin ].ulADCChannelNumber ; // Selection for the positive ADC input
146
+ ADC -> INPUTCTRL .bit .MUXPOS = g_APinDescription [pin ].ulADCChannelNumber ; // Selection for the positive ADC input
160
147
161
148
// Control A
162
149
/*
@@ -185,7 +172,7 @@ uint32_t analogRead( uint32_t ulPin )
185
172
ADC -> SWTRIG .bit .START = 1 ;
186
173
187
174
// Store the value
188
- while ( ADC -> INTFLAG .bit .RESRDY == 0 ); // Waiting for conversion to complete
175
+ while (ADC -> INTFLAG .bit .RESRDY == 0 ); // Waiting for conversion to complete
189
176
valueRead = ADC -> RESULT .reg ;
190
177
191
178
syncADC ();
@@ -200,143 +187,134 @@ uint32_t analogRead( uint32_t ulPin )
200
187
// hardware support. These are defined in the appropriate
201
188
// pins_*.c file. For the rest of the pins, we default
202
189
// to digital output.
203
- void analogWrite ( uint32_t ulPin , uint32_t ulValue )
190
+ void analogWrite (uint32_t pin , uint32_t value )
204
191
{
205
- uint32_t attr = g_APinDescription [ulPin ].ulPinAttribute ;
192
+ PinDescription pinDesc = g_APinDescription [pin ];
193
+ uint32_t attr = pinDesc .ulPinAttribute ;
206
194
207
- if ( (attr & PIN_ATTR_ANALOG ) == PIN_ATTR_ANALOG )
195
+ if ((attr & PIN_ATTR_ANALOG ) == PIN_ATTR_ANALOG )
208
196
{
209
- if ( ulPin != PIN_A0 ) // Only 1 DAC on A0 (PA02)
210
- {
197
+ // DAC handling code
198
+
199
+ if (pin != PIN_A0 ) { // Only 1 DAC on A0 (PA02)
211
200
return ;
212
201
}
213
202
214
- ulValue = mapResolution (ulValue , _writeResolution , 10 );
203
+ value = mapResolution (value , _writeResolution , 10 );
215
204
216
205
syncDAC ();
217
- DAC -> DATA .reg = ulValue & 0x3FF ; // DAC on 10 bits.
206
+ DAC -> DATA .reg = value & 0x3FF ; // DAC on 10 bits.
218
207
syncDAC ();
219
208
DAC -> CTRLA .bit .ENABLE = 0x01 ; // Enable DAC
220
209
syncDAC ();
221
- return ;
210
+ return ;
222
211
}
223
212
224
- if ( (attr & PIN_ATTR_PWM ) == PIN_ATTR_PWM )
213
+ if ((attr & PIN_ATTR_PWM ) == PIN_ATTR_PWM )
225
214
{
226
- if (attr & PIN_ATTR_TIMER ) {
227
- #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603 )
228
- // Compatibility for cores based on SAMD core <=1.6.2
229
- if (g_APinDescription [ulPin ].ulPinType == PIO_TIMER_ALT ) {
230
- pinPeripheral (ulPin , PIO_TIMER_ALT );
231
- } else
232
- #endif
233
- {
234
- pinPeripheral (ulPin , PIO_TIMER );
215
+ value = mapResolution (value , _writeResolution , 8 );
216
+
217
+ uint32_t tcNum = GetTCNumber (pinDesc .ulPWMChannel );
218
+ uint8_t tcChannel = GetTCChannelNumber (pinDesc .ulPWMChannel );
219
+ static bool tcEnabled [TCC_INST_NUM + TC_INST_NUM ];
220
+
221
+ if (!tcEnabled [tcNum ]) {
222
+ tcEnabled [tcNum ] = true;
223
+
224
+ if (attr & PIN_ATTR_TIMER ) {
225
+ #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603 )
226
+ // Compatibility for cores based on SAMD core <=1.6.2
227
+ if (pinDesc .ulPinType == PIO_TIMER_ALT ) {
228
+ pinPeripheral (pin , PIO_TIMER_ALT );
229
+ } else
230
+ #endif
231
+ {
232
+ pinPeripheral (pin , PIO_TIMER );
233
+ }
234
+ } else {
235
+ // We suppose that attr has PIN_ATTR_TIMER_ALT bit set...
236
+ pinPeripheral (pin , PIO_TIMER_ALT );
235
237
}
236
- } else {
237
- // We suppose that attr has PIN_ATTR_TIMER_ALT bit set...
238
- pinPeripheral (ulPin , PIO_TIMER_ALT );
239
- }
240
238
241
- Tc * TCx = 0 ;
242
- Tcc * TCCx = 0 ;
243
- uint8_t Channelx = GetTCChannelNumber ( g_APinDescription [ulPin ].ulPWMChannel ) ;
244
- if ( GetTCNumber ( g_APinDescription [ulPin ].ulPWMChannel ) >= TCC_INST_NUM )
245
- {
246
- TCx = (Tc * ) GetTC ( g_APinDescription [ulPin ].ulPWMChannel ) ;
247
- }
248
- else
249
- {
250
- TCCx = (Tcc * ) GetTC ( g_APinDescription [ulPin ].ulPWMChannel ) ;
251
- }
252
-
253
- // Enable clocks according to TCCx instance to use
254
- switch ( GetTCNumber ( g_APinDescription [ulPin ].ulPWMChannel ) )
255
- {
256
- case 0 : // TCC0
257
- case 1 : // TCC1
258
- // Enable GCLK for TCC0 and TCC1 (timer counter input clock)
259
- GCLK -> CLKCTRL .reg = (uint16_t ) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID ( GCM_TCC0_TCC1 )) ;
260
- break ;
261
-
262
- case 2 : // TCC2
263
- case 3 : // TC3
264
- // Enable GCLK for TCC2 and TC3 (timer counter input clock)
265
- GCLK -> CLKCTRL .reg = (uint16_t ) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID ( GCM_TCC2_TC3 )) ;
266
- break ;
267
-
268
- case 4 : // TC4
269
- case 5 : // TC5
270
- // Enable GCLK for TC4 and TC5 (timer counter input clock)
271
- GCLK -> CLKCTRL .reg = (uint16_t ) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID ( GCM_TC4_TC5 ));
272
- break ;
273
-
274
- case 6 : // TC6 (not available on Zero)
275
- case 7 : // TC7 (not available on Zero)
276
- // Enable GCLK for TC6 and TC7 (timer counter input clock)
277
- GCLK -> CLKCTRL .reg = (uint16_t ) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID ( GCM_TC6_TC7 ));
278
- break ;
279
- }
280
-
281
- while ( GCLK -> STATUS .bit .SYNCBUSY == 1 ) ;
282
-
283
- ulValue = mapResolution (ulValue , _writeResolution , 8 );
284
-
285
- // Set PORT
286
- if ( TCx )
287
- {
288
- // -- Configure TC
289
-
290
- // Disable TCx
291
- TCx -> COUNT8 .CTRLA .reg &= ~TC_CTRLA_ENABLE ;
292
- syncTC_8 (TCx );
293
- // Set Timer counter Mode to 8 bits
294
- TCx -> COUNT8 .CTRLA .reg |= TC_CTRLA_MODE_COUNT8 ;
295
- // Set TCx as normal PWM
296
- TCx -> COUNT8 .CTRLA .reg |= TC_CTRLA_WAVEGEN_NPWM ;
297
- // Set TCx in waveform mode Normal PWM
298
- TCx -> COUNT8 .CC [Channelx ].reg = (uint8_t ) ulValue ;
299
- syncTC_8 (TCx );
300
- // Set PER to maximum counter value (resolution : 0xFF)
301
- TCx -> COUNT8 .PER .reg = 0xFF ;
302
- syncTC_8 (TCx );
303
- // Enable TCx
304
- TCx -> COUNT8 .CTRLA .reg |= TC_CTRLA_ENABLE ;
305
- syncTC_8 (TCx );
306
- }
307
- else
308
- {
309
- // -- Configure TCC
310
- // Disable TCCx
311
- TCCx -> CTRLA .reg &= ~TCC_CTRLA_ENABLE ;
312
- syncTCC (TCCx );
313
- // Set TCx as normal PWM
314
- TCCx -> WAVE .reg |= TCC_WAVE_WAVEGEN_NPWM ;
315
- syncTCC (TCCx );
316
- // Set TCx in waveform mode Normal PWM
317
- TCCx -> CC [Channelx ].reg = (uint32_t )ulValue ;
318
- syncTCC (TCCx );
319
- // Set PER to maximum counter value (resolution : 0xFF)
320
- TCCx -> PER .reg = 0xFF ;
321
- syncTCC (TCCx );
322
- // Enable TCCx
323
- TCCx -> CTRLA .reg |= TCC_CTRLA_ENABLE ;
324
- syncTCC (TCCx );
239
+ uint16_t GCLK_CLKCTRL_IDs [] = {
240
+ GCLK_CLKCTRL_ID (GCM_TCC0_TCC1 ), // TCC0
241
+ GCLK_CLKCTRL_ID (GCM_TCC0_TCC1 ), // TCC1
242
+ GCLK_CLKCTRL_ID (GCM_TCC2_TC3 ), // TCC2
243
+ GCLK_CLKCTRL_ID (GCM_TCC2_TC3 ), // TC3
244
+ GCLK_CLKCTRL_ID (GCM_TC4_TC5 ), // TC4
245
+ GCLK_CLKCTRL_ID (GCM_TC4_TC5 ), // TC5
246
+ GCLK_CLKCTRL_ID (GCM_TC6_TC7 ), // TC6
247
+ GCLK_CLKCTRL_ID (GCM_TC6_TC7 ), // TC7
248
+ };
249
+ GCLK -> CLKCTRL .reg = (uint16_t ) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_IDs [tcNum ]);
250
+ while (GCLK -> STATUS .bit .SYNCBUSY == 1 );
251
+
252
+ // Set PORT
253
+ if (tcNum >= TCC_INST_NUM ) {
254
+ // -- Configure TC
255
+ Tc * TCx = (Tc * ) GetTC (pinDesc .ulPWMChannel );
256
+ // Disable TCx
257
+ TCx -> COUNT8 .CTRLA .bit .ENABLE = 0 ;
258
+ syncTC_8 (TCx );
259
+ // Set Timer counter Mode to 8 bits, normal PWM, prescaler 1/256
260
+ TCx -> COUNT8 .CTRLA .reg |= TC_CTRLA_MODE_COUNT8 | TC_CTRLA_WAVEGEN_NPWM | TC_CTRLA_PRESCALER_DIV256 ;
261
+ syncTC_8 (TCx );
262
+ // Set the initial value
263
+ TCx -> COUNT8 .CC [tcChannel ].reg = (uint8_t ) value ;
264
+ syncTC_8 (TCx );
265
+ // Set PER to maximum counter value (resolution : 0xFF)
266
+ TCx -> COUNT8 .PER .reg = 0xFF ;
267
+ syncTC_8 (TCx );
268
+ // Enable TCx
269
+ TCx -> COUNT8 .CTRLA .bit .ENABLE = 1 ;
270
+ syncTC_8 (TCx );
271
+ } else {
272
+ // -- Configure TCC
273
+ Tcc * TCCx = (Tcc * ) GetTC (pinDesc .ulPWMChannel );
274
+ // Disable TCCx
275
+ TCCx -> CTRLA .bit .ENABLE = 0 ;
276
+ syncTCC (TCCx );
277
+ // Set prescaler to 1/256
278
+ TCCx -> CTRLA .reg |= TCC_CTRLA_PRESCALER_DIV256 ;
279
+ syncTCC (TCCx );
280
+ // Set TCx as normal PWM
281
+ TCCx -> WAVE .reg |= TCC_WAVE_WAVEGEN_NPWM ;
282
+ syncTCC (TCCx );
283
+ // Set the initial value
284
+ TCCx -> CC [tcChannel ].reg = (uint32_t ) value ;
285
+ syncTCC (TCCx );
286
+ // Set PER to maximum counter value (resolution : 0xFF)
287
+ TCCx -> PER .reg = 0xFF ;
288
+ syncTCC (TCCx );
289
+ // Enable TCCx
290
+ TCCx -> CTRLA .bit .ENABLE = 1 ;
291
+ syncTCC (TCCx );
292
+ }
293
+ } else {
294
+ if (tcNum >= TCC_INST_NUM ) {
295
+ Tc * TCx = (Tc * ) GetTC (pinDesc .ulPWMChannel );
296
+ TCx -> COUNT8 .CC [tcChannel ].reg = (uint8_t ) value ;
297
+ syncTC_8 (TCx );
298
+ } else {
299
+ Tcc * TCCx = (Tcc * ) GetTC (pinDesc .ulPWMChannel );
300
+ TCCx -> CTRLBSET .bit .LUPD = 1 ;
301
+ syncTCC (TCCx );
302
+ TCCx -> CCB [tcChannel ].reg = (uint32_t ) value ;
303
+ syncTCC (TCCx );
304
+ TCCx -> CTRLBCLR .bit .LUPD = 1 ;
305
+ syncTCC (TCCx );
306
+ }
325
307
}
326
-
327
- return ;
308
+ return ;
328
309
}
329
310
330
311
// -- Defaults to digital write
331
- pinMode ( ulPin , OUTPUT ) ;
332
- ulValue = mapResolution (ulValue , _writeResolution , 8 );
333
- if ( ulValue < 128 )
334
- {
335
- digitalWrite ( ulPin , LOW ) ;
336
- }
337
- else
338
- {
339
- digitalWrite ( ulPin , HIGH ) ;
312
+ pinMode (pin , OUTPUT );
313
+ value = mapResolution (value , _writeResolution , 8 );
314
+ if (value < 128 ) {
315
+ digitalWrite (pin , LOW );
316
+ } else {
317
+ digitalWrite (pin , HIGH );
340
318
}
341
319
}
342
320
0 commit comments