@@ -53,47 +53,36 @@ static void syncTCC(Tcc* TCCx) {
5353 while (TCCx -> SYNCBUSY .reg & TCC_SYNCBUSY_MASK );
5454}
5555
56- void analogReadResolution ( int res )
56+ void analogReadResolution (int res )
5757{
58- _readResolution = res ;
59- if (res > 10 )
60- {
58+ _readResolution = res ;
59+ if (res > 10 ) {
6160 ADC -> CTRLB .bit .RESSEL = ADC_CTRLB_RESSEL_12BIT_Val ;
6261 _ADCResolution = 12 ;
63- }
64- else if (res > 8 )
65- {
62+ } else if (res > 8 ) {
6663 ADC -> CTRLB .bit .RESSEL = ADC_CTRLB_RESSEL_10BIT_Val ;
6764 _ADCResolution = 10 ;
68- }
69- else
70- {
65+ } else {
7166 ADC -> CTRLB .bit .RESSEL = ADC_CTRLB_RESSEL_8BIT_Val ;
7267 _ADCResolution = 8 ;
7368 }
7469 syncADC ();
7570}
7671
77- void analogWriteResolution ( int res )
72+ void analogWriteResolution (int res )
7873{
79- _writeResolution = res ;
74+ _writeResolution = res ;
8075}
8176
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 )
8378{
84- if ( from == to )
85- {
86- return value ;
79+ if (from == to ) {
80+ return value ;
8781 }
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 );
9684 }
85+ return value << (to - from );
9786}
9887
9988/*
@@ -102,10 +91,10 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to
10291 *
10392 * Warning : On Arduino Zero board the input/output voltage for SAMD21G18 is 3.3 volts maximum
10493 */
105- void analogReference ( eAnalogReference ulMode )
94+ void analogReference (eAnalogReference mode )
10695{
10796 syncADC ();
108- switch ( ulMode )
97+ switch (mode )
10998 {
11099 case AR_INTERNAL :
111100 case AR_INTERNAL2V23 :
@@ -136,27 +125,25 @@ void analogReference( eAnalogReference ulMode )
136125 }
137126}
138127
139- uint32_t analogRead ( uint32_t ulPin )
128+ uint32_t analogRead (uint32_t pin )
140129{
141130 uint32_t valueRead = 0 ;
142131
143- if ( ulPin < A0 )
144- {
145- ulPin += A0 ;
132+ if (pin < A0 ) {
133+ pin += A0 ;
146134 }
147135
148- pinPeripheral (ulPin , PIO_ANALOG );
136+ pinPeripheral (pin , PIO_ANALOG );
149137
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
152139 syncDAC ();
153140 DAC -> CTRLA .bit .ENABLE = 0x00 ; // Disable DAC
154141 //DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off.
155142 syncDAC ();
156143 }
157144
158145 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
160147
161148 // Control A
162149 /*
@@ -185,7 +172,7 @@ uint32_t analogRead( uint32_t ulPin )
185172 ADC -> SWTRIG .bit .START = 1 ;
186173
187174 // 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
189176 valueRead = ADC -> RESULT .reg ;
190177
191178 syncADC ();
@@ -200,143 +187,134 @@ uint32_t analogRead( uint32_t ulPin )
200187// hardware support. These are defined in the appropriate
201188// pins_*.c file. For the rest of the pins, we default
202189// to digital output.
203- void analogWrite ( uint32_t ulPin , uint32_t ulValue )
190+ void analogWrite (uint32_t pin , uint32_t value )
204191{
205- uint32_t attr = g_APinDescription [ulPin ].ulPinAttribute ;
192+ PinDescription pinDesc = g_APinDescription [pin ];
193+ uint32_t attr = pinDesc .ulPinAttribute ;
206194
207- if ( (attr & PIN_ATTR_ANALOG ) == PIN_ATTR_ANALOG )
195+ if ((attr & PIN_ATTR_ANALOG ) == PIN_ATTR_ANALOG )
208196 {
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)
211200 return ;
212201 }
213202
214- ulValue = mapResolution (ulValue , _writeResolution , 10 );
203+ value = mapResolution (value , _writeResolution , 10 );
215204
216205 syncDAC ();
217- DAC -> DATA .reg = ulValue & 0x3FF ; // DAC on 10 bits.
206+ DAC -> DATA .reg = value & 0x3FF ; // DAC on 10 bits.
218207 syncDAC ();
219208 DAC -> CTRLA .bit .ENABLE = 0x01 ; // Enable DAC
220209 syncDAC ();
221- return ;
210+ return ;
222211 }
223212
224- if ( (attr & PIN_ATTR_PWM ) == PIN_ATTR_PWM )
213+ if ((attr & PIN_ATTR_PWM ) == PIN_ATTR_PWM )
225214 {
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 );
235237 }
236- } else {
237- // We suppose that attr has PIN_ATTR_TIMER_ALT bit set...
238- pinPeripheral (ulPin , PIO_TIMER_ALT );
239- }
240238
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+ }
325307 }
326-
327- return ;
308+ return ;
328309 }
329310
330311 // -- 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 );
340318 }
341319}
342320
0 commit comments