Skip to content

Commit b0774aa

Browse files
author
oclyke
committed
allow for users to change frequency of analogWrite
1 parent 5e4eef8 commit b0774aa

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

cores/arduino/ard_sup/analog/ap3_analog.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
/********************************************/
561575
ap3_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+
/********************************************/
569586
ap3_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

cores/arduino/ard_sup/ap3_analog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ ap3_err_t analogReadResolution(uint8_t bits);
4747

4848
ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk);
4949
ap3_err_t analogWriteResolution(uint8_t res);
50-
ap3_err_t analogWriteFrameWidth(uint32_t fw);
51-
ap3_err_t analogWriteFrequency(float freq);
50+
ap3_err_t analogWriteFrameWidth(uint32_t fw); // DANGER (One time use only - before any analogWrite calls)
51+
ap3_err_t analogWriteFrequency(float freq); // DANGER (One time use only - before any analogWrite calls)
5252
ap3_err_t analogWrite(uint8_t pin, uint32_t val);
5353
ap3_err_t servoWriteResolution(uint8_t res);
5454
uint8_t getServoResolution();

0 commit comments

Comments
 (0)