@@ -121,15 +121,16 @@ static const uint8_t outcfg_tbl[32][4] =
121
121
122
122
#define AP3_MAX_ANALOG_WRITE_WIDTH 0x0000FFFF
123
123
124
- uint16_t _analogBits = 10 ; // 10-bit by default
125
- uint8_t _analogWriteBits = 8 ; // 8-bit by default for writes
126
- uint8_t _servoWriteBits = 8 ; // 8-bit by default for writes
124
+ uint16_t _analogBits = 10 ; // 10-bit by default
125
+ uint8_t _analogWriteBits = 8 ; // 8-bit by default for writes
126
+ uint8_t _servoWriteBits = 8 ; // 8-bit by default for writes
127
127
static bool ap3_adc_initialized = false ; // flag to show if the ADC has been initialized
128
128
static uint32_t _analogWriteWidth = 0x0000FFFF ;
129
129
130
130
uint16_t analogRead (uint8_t pinNumber)
131
131
{
132
- if (!ap3_adc_initialized){
132
+ if (!ap3_adc_initialized)
133
+ {
133
134
ap3_adc_setup ();
134
135
ap3_adc_initialized = true ;
135
136
}
@@ -222,6 +223,35 @@ uint16_t analogRead(uint8_t pinNumber)
222
223
}
223
224
}
224
225
226
+ // Returns the internal temperature of the Apollo3
227
+ float getInternalTemp ()
228
+ {
229
+ const float fReferenceVoltage = 2.0 ;
230
+ float fADCTempDegreesC = 0.0 ;
231
+
232
+ uint16_t internalTemp = analogRead (ADC_INTERNAL_TEMP); // Read internal temp sensor channel
233
+
234
+ //
235
+ // Convert and scale the temperature.
236
+ // Temperatures are in Fahrenheit range -40 to 225 degrees.
237
+ // Voltage range is 0.825V to 1.283V
238
+ // First get the ADC voltage corresponding to temperature.
239
+ //
240
+ float fADCTempVolts = ((float )internalTemp) * fReferenceVoltage / ((float )(pow (2 , _analogBits)));
241
+
242
+ float fVT [3 ];
243
+ fVT [0 ] = fADCTempVolts ;
244
+ fVT [1 ] = 0 .0f ;
245
+ fVT [2 ] = -123.456 ;
246
+ uint32_t ui32Retval = am_hal_adc_control (g_ADCHandle, AM_HAL_ADC_REQ_TEMP_CELSIUS_GET, fVT );
247
+ if (ui32Retval == AM_HAL_STATUS_SUCCESS)
248
+ {
249
+ fADCTempDegreesC = fVT [1 ]; // Get the temperature
250
+ }
251
+
252
+ return (fADCTempDegreesC );
253
+ }
254
+
225
255
// Power down ADC. Comes from adc_lpmode2.c example from Ambiq SDK
226
256
bool power_adc_disable ()
227
257
{
@@ -508,19 +538,21 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
508
538
509
539
// if timer is running wait for timer value to roll over (will indicate that at least one pulse has been emitted)
510
540
AM_CRITICAL_BEGIN // critical section when reading / writing config registers
511
- if (*((uint32_t *)CTIMERADDRn (CTIMER, timer, CTRL0)) & (CTIMER_CTRL0_TMRA0EN_Msk | CTIMER_CTRL0_TMRB0EN_Msk)){
541
+ if (*((uint32_t *)CTIMERADDRn (CTIMER, timer, CTRL0)) & (CTIMER_CTRL0_TMRA0EN_Msk | CTIMER_CTRL0_TMRB0EN_Msk))
542
+ {
512
543
uint32_t current = 0 ;
513
544
uint32_t last = 0 ;
514
- do {
545
+ do
546
+ {
515
547
last = current;
516
- current = am_hal_ctimer_read ( timer, segment);
517
- }while (current >= last);
548
+ current = am_hal_ctimer_read (timer, segment);
549
+ } while (current >= last);
518
550
}
519
551
520
552
AM_CRITICAL_END // end critical section
521
553
522
- // clear timer (also stops the timer)
523
- am_hal_ctimer_clear (timer, segment);
554
+ // clear timer (also stops the timer)
555
+ am_hal_ctimer_clear (timer, segment);
524
556
525
557
// Configure the repeated pulse mode with our clock source
526
558
am_hal_ctimer_config_single (timer,
@@ -538,25 +570,27 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
538
570
pui32ConfigReg = (uint32_t *)CTIMERADDRn (CTIMER, timer, AUX0);
539
571
uint32_t ui32WriteVal = AM_REGVAL (pui32ConfigReg);
540
572
uint32_t ui32ConfigVal = (1 << CTIMER_AUX0_TMRA0EN23_Pos); // using CTIMER_AUX0_TMRA0EN23_Pos because for now this number is common to all CTimer instances
541
- volatile uint32_t *pui32CompareRegA = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRA0);
542
- volatile uint32_t *pui32CompareRegB = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRB0);
543
- uint32_t masterPeriod = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRA0_CMPR1A0_Msk) >> CTIMER_CMPRA0_CMPR1A0_Pos;
544
- uint32_t masterRisingTrigger = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRA0_CMPR0A0_Msk) >> CTIMER_CMPRA0_CMPR0A0_Pos;
545
-
573
+ volatile uint32_t *pui32CompareRegA = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRA0);
574
+ volatile uint32_t *pui32CompareRegB = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRB0);
575
+ uint32_t masterPeriod = (uint32_t )(*(pui32CompareRegA)& CTIMER_CMPRA0_CMPR1A0_Msk) >> CTIMER_CMPRA0_CMPR1A0_Pos;
576
+ uint32_t masterRisingTrigger = (uint32_t )(*(pui32CompareRegA)& CTIMER_CMPRA0_CMPR0A0_Msk) >> CTIMER_CMPRA0_CMPR0A0_Pos;
577
+
546
578
if (segment == AM_HAL_CTIMER_TIMERB)
547
579
{
548
580
ui32ConfigVal = ((ui32ConfigVal & 0xFFFF ) << 16 );
549
- masterPeriod = (uint32_t )(*(pui32CompareRegB) & CTIMER_CMPRB0_CMPR1B0_Msk) >> CTIMER_CMPRB0_CMPR1B0_Pos;
550
- masterRisingTrigger = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRB0_CMPR0B0_Msk) >> CTIMER_CMPRB0_CMPR0B0_Pos;
581
+ masterPeriod = (uint32_t )(*(pui32CompareRegB)& CTIMER_CMPRB0_CMPR1B0_Msk) >> CTIMER_CMPRB0_CMPR1B0_Pos;
582
+ masterRisingTrigger = (uint32_t )(*(pui32CompareRegA)& CTIMER_CMPRB0_CMPR0B0_Msk) >> CTIMER_CMPRB0_CMPR0B0_Pos;
551
583
}
552
584
ui32WriteVal |= ui32ConfigVal;
553
585
AM_REGVAL (pui32ConfigReg) = ui32WriteVal;
554
586
555
- if (masterPeriod != fw){
587
+ if (masterPeriod != fw)
588
+ {
556
589
// the master output fw dictates the secondary fw... so if they are different try to change the master while preserving duty cycle
557
590
uint32_t masterTH = ((masterPeriod - masterRisingTrigger) * fw) / masterPeriod; // try to compensate in case _analogWriteWidth was changed
558
- if (masterPeriod == 0 ){ // if masterPeriod was 0 then masterTH will be invalid (divide by 0). This usually means that the master timer output did not have a set duty cycle. This also means the output is probably not configured and so it is okay to choose an arbitrary duty cycle
559
- masterTH = fw - 1 ;
591
+ if (masterPeriod == 0 )
592
+ { // if masterPeriod was 0 then masterTH will be invalid (divide by 0). This usually means that the master timer output did not have a set duty cycle. This also means the output is probably not configured and so it is okay to choose an arbitrary duty cycle
593
+ masterTH = fw - 1 ;
560
594
}
561
595
am_hal_ctimer_period_set (timer, segment, fw, masterTH); // but this overwrites the non-aux compare regs for this timer / segment
562
596
// Serial.printf("th = %d, fw = %d, (masterPeriod - masterRisingTrigger) = (%d - %d) = %d\n", th, fw, masterPeriod, masterRisingTrigger, (masterPeriod - masterRisingTrigger));
@@ -570,25 +604,28 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk)
570
604
// Try to preserve settings of the secondary output
571
605
uint32_t *pui32ConfigReg = NULL ;
572
606
pui32ConfigReg = (uint32_t *)CTIMERADDRn (CTIMER, timer, AUX0);
573
- volatile uint32_t *pui32CompareRegA = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRAUXA0);
574
- volatile uint32_t *pui32CompareRegB = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRAUXB0);
575
- uint32_t slavePeriod = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRA0_CMPR1A0_Msk) >> CTIMER_CMPRA0_CMPR1A0_Pos;
576
- uint32_t slaveRisingTrigger = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRA0_CMPR0A0_Msk) >> CTIMER_CMPRA0_CMPR0A0_Pos;
577
-
607
+ volatile uint32_t *pui32CompareRegA = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRAUXA0);
608
+ volatile uint32_t *pui32CompareRegB = (uint32_t *)CTIMERADDRn (CTIMER, timer, CMPRAUXB0);
609
+ uint32_t slavePeriod = (uint32_t )(*(pui32CompareRegA)& CTIMER_CMPRA0_CMPR1A0_Msk) >> CTIMER_CMPRA0_CMPR1A0_Pos;
610
+ uint32_t slaveRisingTrigger = (uint32_t )(*(pui32CompareRegA)& CTIMER_CMPRA0_CMPR0A0_Msk) >> CTIMER_CMPRA0_CMPR0A0_Pos;
611
+
578
612
uint32_t auxEnabled = (AM_REGVAL (pui32ConfigReg) & CTIMER_AUX0_TMRA0EN23_Msk);
579
-
613
+
580
614
if (segment == AM_HAL_CTIMER_TIMERB)
581
615
{
582
616
auxEnabled = (AM_REGVAL (pui32ConfigReg) & (CTIMER_AUX0_TMRA0EN23_Msk << 16 ));
583
- slavePeriod = (uint32_t )(*(pui32CompareRegB) & CTIMER_CMPRB0_CMPR1B0_Msk) >> CTIMER_CMPRB0_CMPR1B0_Pos;
584
- slaveRisingTrigger = (uint32_t )(*(pui32CompareRegA) & CTIMER_CMPRB0_CMPR0B0_Msk) >> CTIMER_CMPRB0_CMPR0B0_Pos;
617
+ slavePeriod = (uint32_t )(*(pui32CompareRegB)& CTIMER_CMPRB0_CMPR1B0_Msk) >> CTIMER_CMPRB0_CMPR1B0_Pos;
618
+ slaveRisingTrigger = (uint32_t )(*(pui32CompareRegA)& CTIMER_CMPRB0_CMPR0B0_Msk) >> CTIMER_CMPRB0_CMPR0B0_Pos;
585
619
}
586
620
587
- if ( auxEnabled ){ // if secondary outputs are enabled
588
- if ( slavePeriod != fw ){ // and if fw is different from previous slavePeriod
621
+ if (auxEnabled)
622
+ { // if secondary outputs are enabled
623
+ if (slavePeriod != fw)
624
+ { // and if fw is different from previous slavePeriod
589
625
uint32_t slaveTH = ((slavePeriod - slaveRisingTrigger) * fw) / slavePeriod; // try to compensate in case _analogWriteWidth was changed
590
- if (slavePeriod == 0 ){ // if masterPeriod was 0 then masterTH will be invalid (divide by 0). This usually means that the master timer output did not have a set duty cycle. This also means the output is probably not configured and so it is okay to choose an arbitrary duty cycle
591
- slaveTH = fw - 1 ;
626
+ if (slavePeriod == 0 )
627
+ { // if masterPeriod was 0 then masterTH will be invalid (divide by 0). This usually means that the master timer output did not have a set duty cycle. This also means the output is probably not configured and so it is okay to choose an arbitrary duty cycle
628
+ slaveTH = fw - 1 ;
592
629
}
593
630
am_hal_ctimer_aux_period_set (timer, segment, fw, slaveTH); // but this overwrites the non-aux compare regs for this timer / segment
594
631
}
@@ -615,20 +652,25 @@ ap3_err_t analogWriteResolution(uint8_t res)
615
652
return AP3_OK;
616
653
}
617
654
618
- ap3_err_t analogWriteFrameWidth (uint32_t fw){
655
+ ap3_err_t analogWriteFrameWidth (uint32_t fw)
656
+ {
619
657
_analogWriteWidth = fw;
620
- if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH){
658
+ if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH)
659
+ {
621
660
_analogWriteWidth = AP3_MAX_ANALOG_WRITE_WIDTH;
622
661
}
623
662
return AP3_OK;
624
663
}
625
664
626
- ap3_err_t analogWriteFrequency (float freq){
665
+ ap3_err_t analogWriteFrequency (float freq)
666
+ {
627
667
_analogWriteWidth = (uint32_t )(12000000 / freq);
628
- if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH){
668
+ if (_analogWriteWidth > AP3_MAX_ANALOG_WRITE_WIDTH)
669
+ {
629
670
return AP3_ERR;
630
671
}
631
- if (_analogWriteWidth < 3 ){
672
+ if (_analogWriteWidth < 3 )
673
+ {
632
674
return AP3_ERR;
633
675
}
634
676
return AP3_OK;
@@ -655,12 +697,12 @@ ap3_err_t servoWriteResolution(uint8_t res)
655
697
656
698
uint8_t getServoResolution ()
657
699
{
658
- return (_servoWriteBits);
700
+ return (_servoWriteBits);
659
701
}
660
702
661
703
ap3_err_t servoWrite (uint8_t pin, uint32_t val)
662
704
{
663
- return (servoWrite (pin, val, 544 , 2400 )); // Call servoWrite with Arduino default min/max microseconds. See: https://www.arduino.cc/en/Reference/ServoAttach
705
+ return (servoWrite (pin, val, 544 , 2400 )); // Call servoWrite with Arduino default min/max microseconds. See: https://www.arduino.cc/en/Reference/ServoAttach
664
706
}
665
707
666
708
ap3_err_t servoWrite (uint8_t pin, uint32_t val, uint16_t minMicros, uint16_t maxMicros)
@@ -672,9 +714,9 @@ ap3_err_t servoWrite(uint8_t pin, uint32_t val, uint16_t minMicros, uint16_t max
672
714
uint32_t fw = 60000 ; // 20 ms wide frame
673
715
674
716
// Convert microSeconds to PWM counts.
675
- uint32_t min = minMicros * 3 ;
717
+ uint32_t min = minMicros * 3 ;
676
718
uint32_t max = maxMicros * 3 ;
677
-
719
+
678
720
uint32_t th = (uint32_t )(((max - min) * val) / fsv) + min;
679
721
680
722
return ap3_pwm_output (pin, th, fw, clk);
0 commit comments