Skip to content

Commit 82089ed

Browse files
committed
Add 'wait_for_pulse' to ap3_pwm_output
This waits until a pulse has just been completed to change the compare register values. This attempts to solve isse #16. servoWrite could cause the signal to be inverted if/when the compare registers were changed at the same time that they matched the timer. This attempts to wait until the timer value is below the smaller compare register to make any changes.
1 parent 1d2f969 commit 82089ed

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

cores/arduino/ard_sup/analog/ap3_analog.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,37 @@ ap3_err_t ap3_change_channel(uint8_t padNumber)
354354
}
355355

356356

357+
void ap3_pwm_wait_for_pulse(uint32_t timer, uint32_t segment, uint32_t output, uint32_t margin){
358+
359+
volatile uint32_t *pui32CompareReg;
360+
volatile uint32_t ctimer_val;
361+
uint32_t cmpr0;
362+
363+
// Get the comapre register address
364+
if( segment == AM_HAL_CTIMER_TIMERA ){
365+
if( output == AM_HAL_CTIMER_OUTPUT_NORMAL ){
366+
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRA0);
367+
}else{
368+
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRAUXA0);
369+
}
370+
}else{
371+
if( output == AM_HAL_CTIMER_OUTPUT_NORMAL ){
372+
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRB0);
373+
}else{
374+
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRAUXB0);
375+
}
376+
}
377+
378+
// Get the compare value
379+
cmpr0 = ((uint32_t)(*(pui32CompareReg)) & 0x0000FFFF);
380+
381+
// Wait for the timer value to be less than the compare value so that it is safe to change
382+
ctimer_val = am_hal_ctimer_read( timer, segment);
383+
while( (ctimer_val + 0) > cmpr0 ){
384+
ctimer_val = am_hal_ctimer_read( timer, segment);
385+
}
386+
}
387+
357388
//**********************************************
358389
// ap3_pwm_output
359390
// - This function allows you to specify an arbitrary pwm output signal with a given frame width (fw) and time high (th).
@@ -476,6 +507,9 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
476507
// (AM_HAL_CTIMER_FN_PWM_REPEAT | AP3_ANALOG_CLK | AM_HAL_CTIMER_INT_ENABLE) );
477508
(AM_HAL_CTIMER_FN_PWM_REPEAT | clk));
478509

510+
// Wait until after high pulse to change the state (avoids inversion)
511+
ap3_pwm_wait_for_pulse( timer, segment, output, 10);
512+
479513
// If this pad uses secondary output:
480514
if (output == AM_HAL_CTIMER_OUTPUT_SECONDARY)
481515
{

0 commit comments

Comments
 (0)