Skip to content

Commit 5ee8252

Browse files
committed
Fix 'wait_for_pulse' when timer is not running
Checks if timer is running to allow waiting for the pulse to complete. Also moves the pulse wait function before the 'configure' step b/c configure stops the timer and therefore the pulse would never be waited for.
1 parent 82089ed commit 5ee8252

File tree

1 file changed

+60
-21
lines changed

1 file changed

+60
-21
lines changed

cores/arduino/ard_sup/analog/ap3_analog.cpp

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

356356

357+
bool ap3_pwm_is_running(uint32_t ui32TimerNumber, uint32_t ui32TimerSegment){
358+
volatile uint32_t *pui32ConfigReg;
359+
bool is_enabled = false;
360+
361+
//
362+
// Find the correct control register.
363+
//
364+
pui32ConfigReg = (uint32_t*)CTIMERADDRn(CTIMER, ui32TimerNumber, CTRL0);
365+
366+
//
367+
// Begin critical section while config registers are read and modified.
368+
//
369+
AM_CRITICAL_BEGIN
370+
371+
//
372+
// Read the current value.
373+
//
374+
uint32_t ui32ConfigVal = *pui32ConfigReg;
375+
376+
//
377+
// Check the "enable bit"
378+
//
379+
if( ui32ConfigVal & (CTIMER_CTRL0_TMRA0EN_Msk | CTIMER_CTRL0_TMRB0EN_Msk) ){
380+
is_enabled = true;
381+
}
382+
383+
//
384+
// Done with critical section.
385+
//
386+
AM_CRITICAL_END
387+
388+
return is_enabled;
389+
}
390+
391+
357392
void ap3_pwm_wait_for_pulse(uint32_t timer, uint32_t segment, uint32_t output, uint32_t margin){
358393

359394
volatile uint32_t *pui32CompareReg;
360395
volatile uint32_t ctimer_val;
361396
uint32_t cmpr0;
362397

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);
398+
// Only wait if the ctimer is running to avoid a deadlock
399+
if( ap3_pwm_is_running( timer, segment) ){
400+
401+
// Get the comapre register address
402+
if( segment == AM_HAL_CTIMER_TIMERA ){
403+
if( output == AM_HAL_CTIMER_OUTPUT_NORMAL ){
404+
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRA0);
405+
}else{
406+
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRAUXA0);
407+
}
373408
}else{
374-
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRAUXB0);
409+
if( output == AM_HAL_CTIMER_OUTPUT_NORMAL ){
410+
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRB0);
411+
}else{
412+
pui32CompareReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, CMPRAUXB0);
413+
}
375414
}
376-
}
377415

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 ){
416+
// Get the compare value
417+
cmpr0 = ((uint32_t)(*(pui32CompareReg)) & 0x0000FFFF);
418+
419+
// Wait for the timer value to be less than the compare value so that it is safe to change
384420
ctimer_val = am_hal_ctimer_read( timer, segment);
421+
while( (ctimer_val + 0) > cmpr0 ){
422+
ctimer_val = am_hal_ctimer_read( timer, segment);
423+
}
385424
}
386425
}
387426

@@ -494,6 +533,9 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
494533
output = AM_HAL_CTIMER_OUTPUT_FORCE1;
495534
}
496535

536+
// Wait until after high pulse to change the state (avoids inversion)
537+
ap3_pwm_wait_for_pulse( timer, segment, output, 10);
538+
497539
// Configure the pin
498540
am_hal_ctimer_output_config(timer,
499541
segment,
@@ -507,9 +549,6 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
507549
// (AM_HAL_CTIMER_FN_PWM_REPEAT | AP3_ANALOG_CLK | AM_HAL_CTIMER_INT_ENABLE) );
508550
(AM_HAL_CTIMER_FN_PWM_REPEAT | clk));
509551

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

0 commit comments

Comments
 (0)