@@ -525,13 +525,24 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
525525 pui32ConfigReg = (uint32_t *)CTIMERADDRn (CTIMER, timer, AUX0);
526526 uint32_t ui32WriteVal = AM_REGVAL (pui32ConfigReg);
527527 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+
528533 if (segment == AM_HAL_CTIMER_TIMERB)
529534 {
530535 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;
531538 }
532- ui32WriteVal = (ui32WriteVal & ~(segment)) | ui32ConfigVal;
539+ ui32WriteVal |= ui32ConfigVal;
533540 AM_REGVAL (pui32ConfigReg) = ui32WriteVal;
534541
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+
535546 // then set the duty cycle with the 'aux' function
536547 am_hal_ctimer_aux_period_set (timer, segment, fw, th);
537548 }
@@ -558,6 +569,9 @@ ap3_err_t analogWriteResolution(uint8_t res)
558569 return AP3_OK;
559570}
560571
572+ /* *******************************************/
573+ /* WARNING! Changing the frame width or frequency of analogWrite() after starting a timer can have totally unexpected and frustration-inducing results
574+ /********************************************/
561575ap3_err_t analogWriteFrameWidth (uint32_t fw){
562576 _analogWriteWidth = fw;
563577 if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH){
@@ -566,9 +580,11 @@ ap3_err_t analogWriteFrameWidth(uint32_t fw){
566580 return AP3_OK;
567581}
568582
583+ /* *******************************************/
584+ /* WARNING! Changing the frame width or frequency of analogWrite() after starting a timer can have totally unexpected and frustration-inducing results
585+ /********************************************/
569586ap3_err_t analogWriteFrequency (float freq){
570587 _analogWriteWidth = (uint32_t )(12000000 / freq);
571- Serial.println (_analogWriteWidth);
572588 if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH){
573589 return AP3_ERR;
574590 }
@@ -582,7 +598,7 @@ ap3_err_t analogWrite(uint8_t pin, uint32_t val)
582598{
583599 // Determine the high time based on input value and the current resolution setting
584600 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 ) );
586602 return ap3_pwm_output (pin, th, _analogWriteWidth, clk);
587603}
588604
0 commit comments