@@ -415,11 +415,13 @@ void ap3_pwm_wait_for_pulse(uint32_t timer, uint32_t segment, uint32_t output, u
415
415
416
416
// Get the compare value
417
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
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
422
421
ctimer_val = am_hal_ctimer_read ( timer, segment);
422
+ while ( (ctimer_val + 0 ) >= cmpr0 ){
423
+ ctimer_val = am_hal_ctimer_read ( timer, segment);
424
+ }
423
425
}
424
426
}
425
427
}
@@ -526,13 +528,16 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
526
528
}
527
529
528
530
// Test for AM_HAL_CTIMER_OUTPUT_FORCE0 or AM_HAL_CTIMER_OUTPUT_FORCE1
531
+ bool set_periods = true ;
529
532
if ((th == 0 ) || (fw == 0 ))
530
533
{
531
534
output = AM_HAL_CTIMER_OUTPUT_FORCE0;
535
+ set_periods = false ; // disable setting periods when going into a forced mode
532
536
}
533
537
else if (th == fw)
534
538
{
535
539
output = AM_HAL_CTIMER_OUTPUT_FORCE1;
540
+ set_periods = false ; // disable setting periods when going into a forced mode
536
541
}
537
542
538
543
// 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)
551
556
// (AM_HAL_CTIMER_FN_PWM_REPEAT | AP3_ANALOG_CLK | AM_HAL_CTIMER_INT_ENABLE) );
552
557
(AM_HAL_CTIMER_FN_PWM_REPEAT | clk));
553
558
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
563
579
{
564
- ui32ConfigVal = ((ui32ConfigVal & 0xFFFF ) << 16 );
580
+ // Otherwise simply set the primary duty cycle
581
+ am_hal_ctimer_period_set (timer, segment, fw, th);
565
582
}
566
- ui32WriteVal = (ui32WriteVal & ~(segment)) | ui32ConfigVal;
567
- AM_REGVAL (pui32ConfigReg) = ui32WriteVal;
568
583
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
571
585
}
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);
579
586
580
587
return AP3_OK;
581
588
}
@@ -594,17 +601,17 @@ ap3_err_t analogWriteResolution(uint8_t res)
594
601
ap3_err_t analogWrite (uint8_t pin, uint32_t val)
595
602
{
596
603
// 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 ))
599
607
{
600
608
val = fw; // Enable FORCE1
601
609
}
602
610
else
603
611
{
604
- val <<= (16 - _analogWriteBits); // Shift over the value to fill available resolution
612
+ val <<= (16 - _analogWriteBits); // Shift over the value to fill available resolution
605
613
}
606
- uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock
607
-
614
+
608
615
return ap3_pwm_output (pin, val, fw, clk);
609
616
}
610
617
0 commit comments