From 4846d1d7e7323d0dbeaf07c3dc36d31a0919e0d2 Mon Sep 17 00:00:00 2001 From: christophelandret <19358486+landret@users.noreply.github.com> Date: Mon, 28 Dec 2020 17:42:21 -1000 Subject: [PATCH 1/2] Update wiring_analog.c --- cores/arduino/wiring_analog.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index cda2b4da..4dda2c41 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -145,6 +145,8 @@ void analogWrite(uint8_t pin, int val) uint16_t* timer_cmp_out; TCB_t *timer_B; + uint8_t savedSREG; + /* Find out Port and Pin to correctly handle port mux, and timer. */ switch (digital_pin_timer) { @@ -153,7 +155,10 @@ void analogWrite(uint8_t pin, int val) timer_cmp_out = ((uint16_t*) (&TCA0.SINGLE.CMP0BUF)) + bit_pos; /* Configure duty cycle for correct compare channel */ - (*timer_cmp_out) = (val); + savedSREG = SREG; + cli(); + (*timer_cmp_out) = (val); // non-atomic 16-bit write operation + SREG = savedSREG; /* Enable output on pin */ TCA0.SINGLE.CTRLB |= (1 << (TCA_SINGLE_CMP0EN_bp + bit_pos)); @@ -170,7 +175,12 @@ void analogWrite(uint8_t pin, int val) timer_B = ((TCB_t *)&TCB0 + (digital_pin_timer - TIMERB0)); /* set duty cycle */ - timer_B->CCMPH = val; + // (16-bit read/write operation are non-atomic and use a temporary register) + savedSREG = SREG; + cli(); + timer_B->CCMPL = timer_B->CCMPL; // copy CCMPL into temporary register + timer_B->CCMPH = val; // set CCMPH value + copy temporary register content into CCMPL + SREG = savedSREG; /* Enable Timer Output */ timer_B->CTRLB |= (TCB_CCMPEN_bm); From c68af81e21d03b10b956b99043446a4c44b50c90 Mon Sep 17 00:00:00 2001 From: christophelandret <19358486+landret@users.noreply.github.com> Date: Mon, 28 Dec 2020 17:54:43 -1000 Subject: [PATCH 2/2] Update wiring_analog.c --- cores/arduino/wiring_analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 4dda2c41..36ddc680 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -178,8 +178,8 @@ void analogWrite(uint8_t pin, int val) // (16-bit read/write operation are non-atomic and use a temporary register) savedSREG = SREG; cli(); - timer_B->CCMPL = timer_B->CCMPL; // copy CCMPL into temporary register - timer_B->CCMPH = val; // set CCMPH value + copy temporary register content into CCMPL + timer_B->CCMPL = timer_B->CCMPL; // copy CCMPL into temporary register + timer_B->CCMPH = val; // set CCMPH value + copy temporary register content into CCMPL SREG = savedSREG; /* Enable Timer Output */