Skip to content

Commit 9f0bb5d

Browse files
committed
Merge pull request #84 from arduino/zero-analogwrite-sync
Added missing synchronization code to analogWrite().
2 parents c6baf3f + 49e4bf1 commit 9f0bb5d

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

cores/arduino/wiring_analog.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ static void syncDAC() {
4242
;
4343
}
4444

45+
// Wait for synchronization of registers between the clock domains
46+
static __inline__ void syncTC_8(Tc* TCx) __attribute__((always_inline, unused));
47+
static void syncTC_8(Tc* TCx) {
48+
while (TCx->COUNT8.STATUS.bit.SYNCBUSY);
49+
}
50+
51+
// Wait for synchronization of registers between the clock domains
52+
static __inline__ void syncTCC(Tcc* TCCx) __attribute__((always_inline, unused));
53+
static void syncTCC(Tcc* TCCx) {
54+
while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK);
55+
}
56+
4557
void analogReadResolution( int res )
4658
{
4759
_readResolution = res ;
@@ -236,8 +248,6 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
236248
case 1: // TCC1
237249
// Enable GCLK for TCC0 and TCC1 (timer counter input clock)
238250
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
239-
240-
while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) ;
241251
break ;
242252

243253
case 2: // TCC2
@@ -259,6 +269,8 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
259269
break ;
260270
}
261271

272+
while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) ;
273+
262274
ulValue = mapResolution(ulValue, _writeResolution, 8);
263275

264276
// Set PORT
@@ -268,30 +280,39 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue )
268280

269281
// Disable TCx
270282
TCx->COUNT8.CTRLA.reg &= ~TC_CTRLA_ENABLE;
283+
syncTC_8(TCx);
271284
// Set Timer counter Mode to 8 bits
272285
TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8;
273286
// Set TCx as normal PWM
274287
TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM;
275288
// Set TCx in waveform mode Normal PWM
276289
TCx->COUNT8.CC[Channelx].reg = (uint8_t) ulValue;
290+
syncTC_8(TCx);
277291
// Set PER to maximum counter value (resolution : 0xFF)
278292
TCx->COUNT8.PER.reg = 0xFF;
293+
syncTC_8(TCx);
279294
// Enable TCx
280295
TCx->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE;
296+
syncTC_8(TCx);
281297
}
282298
else
283299
{
284300
// -- Configure TCC
285301
// Disable TCCx
286302
TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE;
303+
syncTCC(TCCx);
287304
// Set TCx as normal PWM
288305
TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
306+
syncTCC(TCCx);
289307
// Set TCx in waveform mode Normal PWM
290308
TCCx->CC[Channelx].reg = (uint32_t)ulValue;
309+
syncTCC(TCCx);
291310
// Set PER to maximum counter value (resolution : 0xFF)
292311
TCCx->PER.reg = 0xFF;
312+
syncTCC(TCCx);
293313
// Enable TCCx
294314
TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ;
315+
syncTCC(TCCx);
295316
}
296317

297318
return ;

0 commit comments

Comments
 (0)