@@ -525,13 +525,24 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
525
525
pui32ConfigReg = (uint32_t *)CTIMERADDRn (CTIMER, timer, AUX0);
526
526
uint32_t ui32WriteVal = AM_REGVAL (pui32ConfigReg);
527
527
uint32_t ui32ConfigVal = (1 << CTIMER_AUX0_TMRA0EN23_Pos); // using CTIMER_AUX0_TMRA0EN23_Pos because for now this number is common to all CTimer instances
528
+ volatile uint32_t *pui32CompareRegA = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRA0);
529
+ volatile uint32_t *pui32CompareRegB = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRB0);
530
+ uint32_t masterPeriod = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRA0_CMPR1A0_Msk) >> CTIMER_CMPRA0_CMPR1A0_Pos;
531
+ uint32_t masterRisingTrigger = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRA0_CMPR0A0_Msk) >> CTIMER_CMPRA0_CMPR0A0_Pos;
532
+
528
533
if (segment == AM_HAL_CTIMER_TIMERB)
529
534
{
530
535
ui32ConfigVal = ((ui32ConfigVal & 0xFFFF ) << 16 );
536
+ masterPeriod = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRA0_CMPR1A0_Msk) >> CTIMER_CMPRA0_CMPR1A0_Pos;
537
+ masterRisingTrigger = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRA0_CMPR0A0_Msk) >> CTIMER_CMPRA0_CMPR0A0_Pos;
531
538
}
532
- ui32WriteVal = (ui32WriteVal & ~(segment)) | ui32ConfigVal;
539
+ ui32WriteVal |= ui32ConfigVal;
533
540
AM_REGVAL (pui32ConfigReg) = ui32WriteVal;
534
541
542
+ // enable the non-auxiliary timer b/c without it the auxialiary timer won't work
543
+ uint32_t masterTH = ((masterPeriod - masterRisingTrigger) * fw) / masterPeriod; // try to compensate in case _analogWriteWidth was changed
544
+ am_hal_ctimer_period_set (timer, segment, fw, masterTH); // but this overwrites the non-aux compare regs for this timer / segment
545
+
535
546
// then set the duty cycle with the 'aux' function
536
547
am_hal_ctimer_aux_period_set (timer, segment, fw, th);
537
548
}
@@ -558,6 +569,9 @@ ap3_err_t analogWriteResolution(uint8_t res)
558
569
return AP3_OK;
559
570
}
560
571
572
+ /* *******************************************/
573
+ /* WARNING! Changing the frame width or frequency of analogWrite() after starting a timer can have totally unexpected and frustration-inducing results
574
+ /********************************************/
561
575
ap3_err_t analogWriteFrameWidth (uint32_t fw){
562
576
_analogWriteWidth = fw;
563
577
if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH){
@@ -566,9 +580,11 @@ ap3_err_t analogWriteFrameWidth(uint32_t fw){
566
580
return AP3_OK;
567
581
}
568
582
583
+ /* *******************************************/
584
+ /* WARNING! Changing the frame width or frequency of analogWrite() after starting a timer can have totally unexpected and frustration-inducing results
585
+ /********************************************/
569
586
ap3_err_t analogWriteFrequency (float freq){
570
587
_analogWriteWidth = (uint32_t )(12000000 / freq);
571
- Serial.println (_analogWriteWidth);
572
588
if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH){
573
589
return AP3_ERR;
574
590
}
@@ -582,7 +598,7 @@ ap3_err_t analogWrite(uint8_t pin, uint32_t val)
582
598
{
583
599
// Determine the high time based on input value and the current resolution setting
584
600
uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock
585
- uint32_t th = (uint32_t )(val * _analogWriteWidth) / ((0x01 << _analogWriteBits) - 1 );
601
+ uint32_t th = (uint32_t )(( val * _analogWriteWidth) / ((0x01 << _analogWriteBits) - 1 ) );
586
602
return ap3_pwm_output (pin, th, _analogWriteWidth, clk);
587
603
}
588
604
0 commit comments