@@ -119,10 +119,13 @@ static const uint8_t outcfg_tbl[32][4] =
119
119
{OUTC (1 , 7 , 1 ), OUTC (0 , 6 , 0 ), OUTC (1 , 7 , 0 ), OUTC (1 , 3 , 1 )}, // CTX31: B7OUT2, A6OUT, B7OUT, B3OUT2
120
120
};
121
121
122
+ #define AP3_MAX_ANALOG_WRITE_WIDTH 0x0000FFFF
123
+
122
124
uint16_t _analogBits = 10 ; // 10-bit by default
123
125
uint8_t _analogWriteBits = 8 ; // 8-bit by default for writes
124
126
uint8_t _servoWriteBits = 8 ; // 8-bit by default for writes
125
127
static bool ap3_adc_initialized = false ; // flag to show if the ADC has been initialized
128
+ static uint32_t _analogWriteWidth = 0x0000FFFF ;
126
129
127
130
uint16_t analogRead (uint8_t pinNumber)
128
131
{
@@ -382,92 +385,6 @@ ap3_err_t ap3_change_channel(uint8_t padNumber)
382
385
return AP3_OK;
383
386
}
384
387
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
-
471
388
// **********************************************
472
389
// ap3_pwm_output
473
390
// - 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)
582
499
set_periods = false ; // disable setting periods when going into a forced mode
583
500
}
584
501
585
- // Wait until after high pulse to change the state (avoids inversion)
586
- ap3_pwm_wait_for_pulse (timer, segment, output, 10 );
587
-
588
502
// Configure the pin
589
503
am_hal_ctimer_output_config (timer,
590
504
segment,
591
505
pad,
592
506
output,
593
507
AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA); //
594
508
509
+ // clear timer (also stops the timer)
510
+ am_hal_ctimer_clear (timer, segment);
511
+
595
512
// Configure the repeated pulse mode with our clock source
596
513
am_hal_ctimer_config_single (timer,
597
514
segment,
@@ -641,21 +558,32 @@ ap3_err_t analogWriteResolution(uint8_t res)
641
558
return AP3_OK;
642
559
}
643
560
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
+
644
581
ap3_err_t analogWrite (uint8_t pin, uint32_t val)
645
582
{
646
583
// Determine the high time based on input value and the current resolution setting
647
584
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);
659
587
}
660
588
661
589
ap3_err_t servoWriteResolution (uint8_t res)
0 commit comments