@@ -119,10 +119,13 @@ static const uint8_t outcfg_tbl[32][4] =
119119 {OUTC (1 , 7 , 1 ), OUTC (0 , 6 , 0 ), OUTC (1 , 7 , 0 ), OUTC (1 , 3 , 1 )}, // CTX31: B7OUT2, A6OUT, B7OUT, B3OUT2
120120};
121121
122+ #define AP3_MAX_ANALOG_WRITE_WIDTH 0x0000FFFF
123+
122124uint16_t _analogBits = 10 ; // 10-bit by default
123125uint8_t _analogWriteBits = 8 ; // 8-bit by default for writes
124126uint8_t _servoWriteBits = 8 ; // 8-bit by default for writes
125127static bool ap3_adc_initialized = false ; // flag to show if the ADC has been initialized
128+ static uint32_t _analogWriteWidth = 0x0000FFFF ;
126129
127130uint16_t analogRead (uint8_t pinNumber)
128131{
@@ -382,92 +385,6 @@ ap3_err_t ap3_change_channel(uint8_t padNumber)
382385 return AP3_OK;
383386}
384387
385- bool ap3_pwm_is_running (uint32_t ui32TimerNumber, uint32_t ui32TimerSegment)
386- {
387- volatile uint32_t *pui32ConfigReg;
388- bool is_enabled = false ;
389-
390- //
391- // Find the correct control register.
392- //
393- pui32ConfigReg = (uint32_t *)CTIMERADDRn (CTIMER, ui32TimerNumber, CTRL0);
394-
395- //
396- // Begin critical section while config registers are read and modified.
397- //
398- AM_CRITICAL_BEGIN
399-
400- //
401- // Read the current value.
402- //
403- uint32_t ui32ConfigVal = *pui32ConfigReg;
404-
405- //
406- // Check the "enable bit"
407- //
408- if (ui32ConfigVal & (CTIMER_CTRL0_TMRA0EN_Msk | CTIMER_CTRL0_TMRB0EN_Msk))
409- {
410- is_enabled = true ;
411- }
412-
413- //
414- // Done with critical section.
415- //
416- AM_CRITICAL_END
417-
418- return is_enabled;
419- }
420-
421- void ap3_pwm_wait_for_pulse (uint32_t timer, uint32_t segment, uint32_t output, uint32_t margin)
422- {
423-
424- volatile uint32_t *pui32CompareReg;
425- volatile uint32_t ctimer_val;
426- uint32_t cmpr0;
427-
428- // Only wait if the ctimer is running to avoid a deadlock
429- if (ap3_pwm_is_running (timer, segment))
430- {
431-
432- // Get the comapre register address
433- if (segment == AM_HAL_CTIMER_TIMERA)
434- {
435- if (output == AM_HAL_CTIMER_OUTPUT_NORMAL)
436- {
437- pui32CompareReg = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRA0);
438- }
439- else
440- {
441- pui32CompareReg = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRAUXA0);
442- }
443- }
444- else
445- {
446- if (output == AM_HAL_CTIMER_OUTPUT_NORMAL)
447- {
448- pui32CompareReg = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRB0);
449- }
450- else
451- {
452- pui32CompareReg = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRAUXB0);
453- }
454- }
455-
456- // Get the compare value
457- cmpr0 = ((uint32_t )(*(pui32CompareReg)) & 0x0000FFFF );
458-
459- if (cmpr0)
460- { // Only wait when cmpr0 is greater than 0 to avoid an infinite while loop
461- // Wait for the timer value to be less than the compare value so that it is safe to change
462- ctimer_val = am_hal_ctimer_read (timer, segment);
463- while ((ctimer_val + 0 ) >= cmpr0)
464- {
465- ctimer_val = am_hal_ctimer_read (timer, segment);
466- }
467- }
468- }
469- }
470-
471388// **********************************************
472389// ap3_pwm_output
473390// - This function allows you to specify an arbitrary pwm output signal with a given frame width (fw) and time high (th).
@@ -582,16 +499,16 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
582499 set_periods = false ; // disable setting periods when going into a forced mode
583500 }
584501
585- // Wait until after high pulse to change the state (avoids inversion)
586- ap3_pwm_wait_for_pulse (timer, segment, output, 10 );
587-
588502 // Configure the pin
589503 am_hal_ctimer_output_config (timer,
590504 segment,
591505 pad,
592506 output,
593507 AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA); //
594508
509+ // clear timer (also stops the timer)
510+ am_hal_ctimer_clear (timer, segment);
511+
595512 // Configure the repeated pulse mode with our clock source
596513 am_hal_ctimer_config_single (timer,
597514 segment,
@@ -641,21 +558,32 @@ ap3_err_t analogWriteResolution(uint8_t res)
641558 return AP3_OK;
642559}
643560
561+ ap3_err_t analogWriteFrameWidth (uint32_t fw){
562+ _analogWriteWidth = fw;
563+ if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH){
564+ _analogWriteWidth = AP3_MAX_ANALOG_WRITE_WIDTH;
565+ }
566+ return AP3_OK;
567+ }
568+
569+ ap3_err_t analogWriteFrequency (float freq){
570+ _analogWriteWidth = (uint32_t )(12000000 / freq);
571+ Serial.println (_analogWriteWidth);
572+ if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH){
573+ return AP3_ERR;
574+ }
575+ if (_analogWriteWidth < 3 ){
576+ return AP3_ERR;
577+ }
578+ return AP3_OK;
579+ }
580+
644581ap3_err_t analogWrite (uint8_t pin, uint32_t val)
645582{
646583 // Determine the high time based on input value and the current resolution setting
647584 uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock
648- uint32_t fw = 0xFFFF ; // Choose the frame width in clock periods (32767 -> ~ 180 Hz)
649- if (val >= ((0x01 << _analogWriteBits) - 1 ))
650- {
651- val = fw; // Enable FORCE1
652- }
653- else
654- {
655- val <<= (16 - _analogWriteBits); // Shift over the value to fill available resolution
656- }
657-
658- return ap3_pwm_output (pin, val, fw, clk);
585+ uint32_t th = (uint32_t )(val * _analogWriteWidth) / ((0x01 << _analogWriteBits) - 1 );
586+ return ap3_pwm_output (pin, th, _analogWriteWidth, clk);
659587}
660588
661589ap3_err_t servoWriteResolution (uint8_t res)
0 commit comments