@@ -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+
357392void 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