Skip to content

Commit 6a85d51

Browse files
committed
Address #42
#42 was caused by the 'ap3_pwm_wait_for_pulse' function when the cmpr0 value was equal to zero. Now when the cmpr0 value is zero the wait function exits immediately. Additionally the comparison is less strict (greater than or equal to cmpr0)
1 parent beca4c4 commit 6a85d51

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed

cores/arduino/ard_sup/analog/ap3_analog.cpp

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,13 @@ void ap3_pwm_wait_for_pulse(uint32_t timer, uint32_t segment, uint32_t output, u
415415

416416
// Get the compare value
417417
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
420-
ctimer_val = am_hal_ctimer_read( timer, segment);
421-
while( (ctimer_val + 0) > cmpr0 ){
418+
419+
if( cmpr0 ){ // Only wait when cmpr0 is greater than 0 to avoid an infinite while loop
420+
// Wait for the timer value to be less than the compare value so that it is safe to change
422421
ctimer_val = am_hal_ctimer_read( timer, segment);
422+
while( (ctimer_val + 0) >= cmpr0 ){
423+
ctimer_val = am_hal_ctimer_read( timer, segment);
424+
}
423425
}
424426
}
425427
}
@@ -526,13 +528,16 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
526528
}
527529

528530
// Test for AM_HAL_CTIMER_OUTPUT_FORCE0 or AM_HAL_CTIMER_OUTPUT_FORCE1
531+
bool set_periods = true;
529532
if ((th == 0) || (fw == 0))
530533
{
531534
output = AM_HAL_CTIMER_OUTPUT_FORCE0;
535+
set_periods = false; // disable setting periods when going into a forced mode
532536
}
533537
else if (th == fw)
534538
{
535539
output = AM_HAL_CTIMER_OUTPUT_FORCE1;
540+
set_periods = false; // disable setting periods when going into a forced mode
536541
}
537542

538543
// Wait until after high pulse to change the state (avoids inversion)
@@ -551,31 +556,33 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
551556
// (AM_HAL_CTIMER_FN_PWM_REPEAT | AP3_ANALOG_CLK | AM_HAL_CTIMER_INT_ENABLE) );
552557
(AM_HAL_CTIMER_FN_PWM_REPEAT | clk));
553558

554-
// If this pad uses secondary output:
555-
if (output == AM_HAL_CTIMER_OUTPUT_SECONDARY)
556-
{
557-
// Need to explicitly enable compare registers 2/3
558-
uint32_t *pui32ConfigReg = NULL;
559-
pui32ConfigReg = (uint32_t *)CTIMERADDRn(CTIMER, timer, AUX0);
560-
uint32_t ui32WriteVal = AM_REGVAL(pui32ConfigReg);
561-
uint32_t ui32ConfigVal = (1 << CTIMER_AUX0_TMRA0EN23_Pos); // using CTIMER_AUX0_TMRA0EN23_Pos because for now this number is common to all CTimer instances
562-
if (segment == AM_HAL_CTIMER_TIMERB)
559+
if(set_periods){
560+
// If this pad uses secondary output:
561+
if (output == AM_HAL_CTIMER_OUTPUT_SECONDARY)
562+
{
563+
// Need to explicitly enable compare registers 2/3
564+
uint32_t *pui32ConfigReg = NULL;
565+
pui32ConfigReg = (uint32_t *)CTIMERADDRn(CTIMER, timer, AUX0);
566+
uint32_t ui32WriteVal = AM_REGVAL(pui32ConfigReg);
567+
uint32_t ui32ConfigVal = (1 << CTIMER_AUX0_TMRA0EN23_Pos); // using CTIMER_AUX0_TMRA0EN23_Pos because for now this number is common to all CTimer instances
568+
if (segment == AM_HAL_CTIMER_TIMERB)
569+
{
570+
ui32ConfigVal = ((ui32ConfigVal & 0xFFFF) << 16);
571+
}
572+
ui32WriteVal = (ui32WriteVal & ~(segment)) | ui32ConfigVal;
573+
AM_REGVAL(pui32ConfigReg) = ui32WriteVal;
574+
575+
// then set the duty cycle with the 'aux' function
576+
am_hal_ctimer_aux_period_set(timer, segment, fw, th);
577+
}
578+
else
563579
{
564-
ui32ConfigVal = ((ui32ConfigVal & 0xFFFF) << 16);
580+
// Otherwise simply set the primary duty cycle
581+
am_hal_ctimer_period_set(timer, segment, fw, th);
565582
}
566-
ui32WriteVal = (ui32WriteVal & ~(segment)) | ui32ConfigVal;
567-
AM_REGVAL(pui32ConfigReg) = ui32WriteVal;
568583

569-
// then set the duty cycle with the 'aux' function
570-
am_hal_ctimer_aux_period_set(timer, segment, fw, th);
584+
am_hal_ctimer_start(timer, segment); // Start the timer only when there are periods to compare to
571585
}
572-
else
573-
{
574-
// Otherwise simply set the primary duty cycle
575-
am_hal_ctimer_period_set(timer, segment, fw, th);
576-
}
577-
578-
am_hal_ctimer_start(timer, segment);
579586

580587
return AP3_OK;
581588
}
@@ -594,17 +601,17 @@ ap3_err_t analogWriteResolution(uint8_t res)
594601
ap3_err_t analogWrite(uint8_t pin, uint32_t val)
595602
{
596603
// Determine the high time based on input value and the current resolution setting
597-
uint32_t fw = 0xFFFF; // Choose the frame width in clock periods (32767 -> ~ 180 Hz)
598-
if (val == ((0x01 << _analogWriteBits) - 1))
604+
uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock
605+
uint32_t fw = 0xFFFF; // Choose the frame width in clock periods (32767 -> ~ 180 Hz)
606+
if (val >= ((0x01 << _analogWriteBits) - 1))
599607
{
600608
val = fw; // Enable FORCE1
601609
}
602610
else
603611
{
604-
val <<= (16 - _analogWriteBits); // Shift over the value to fill available resolution
612+
val <<= (16 - _analogWriteBits); // Shift over the value to fill available resolution
605613
}
606-
uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock
607-
614+
608615
return ap3_pwm_output(pin, val, fw, clk);
609616
}
610617

0 commit comments

Comments
 (0)