33#include < PendSV.h>
44#include < wiring_private.h>
55
6+ #ifdef FAMILY_SAMD5X
7+ #ifndef NVMCTRL_TEMP_LOG
8+ #ifdef NVMCTRL_TEMP_LOG_W0
9+ #define NVMCTRL_TEMP_LOG NVMCTRL_TEMP_LOG_W0
10+ #endif
11+ #endif
12+ #endif
13+
614static inline float decToFrac (uint8_t val) {
715 // Temperature fuse decimal part is 4 bits only (0-15):
816 // 0-9 represent tenths (0.0-0.9), 10-15 represent hundredths (0.10-0.15)
@@ -113,6 +121,34 @@ constexpr uint8_t kMaxAdjres = 4;
113121constexpr uint8_t kAdcPendSvServiceId = PendSV::kMaxServices - 1 ;
114122constexpr uint32_t kAdcNvicPriority = (1u << __NVIC_PRIO_BITS) - 1u ;
115123
124+ #ifdef FAMILY_SAMD5X
125+ #ifdef ADC_EVCTRL_SYNCEI
126+ constexpr uint8_t kAdcEvctrlSynceiBit = ADC_EVCTRL_SYNCEI;
127+ #elif defined(ADC_EVCTRL_FLUSHEI)
128+ constexpr uint8_t kAdcEvctrlSynceiBit = ADC_EVCTRL_FLUSHEI;
129+ #else
130+ constexpr uint8_t kAdcEvctrlSynceiBit = 0u ;
131+ #endif
132+ #else
133+ constexpr uint8_t kAdcEvctrlSynceiBit = ADC_EVCTRL_SYNCEI;
134+ #endif
135+
136+ uint8_t adcDmacResrdyTrigger () {
137+ #ifdef FAMILY_SAMD5X
138+ return ADC0_DMAC_ID_RESRDY;
139+ #else
140+ return ADC_DMAC_ID_RESRDY;
141+ #endif
142+ }
143+
144+ inline Adc *adcInstance () {
145+ #ifdef FAMILY_SAMD5X
146+ return ADC0;
147+ #else
148+ return ADC;
149+ #endif
150+ }
151+
116152// ADC IRQ routing mirrors SERCOM family handling:
117153// - SAMD2x exposes a single ADC_IRQn vector.
118154// - SAME/SAMD5x splits ADC0 interrupts across two NVIC lines:
@@ -230,11 +266,14 @@ bool AdcEngine::begin() {
230266 return false ;
231267 }
232268
233- dma_.setTrigger (ADC_DMAC_ID_RESRDY );
269+ dma_.setTrigger (adcDmacResrdyTrigger () );
234270 dma_.setAction (DMA_TRIGGER_ACTON_BEAT);
235271 dma_.setCallback (AdcEngine::dmaDoneCallback, DMA_CALLBACK_TRANSFER_DONE);
236- dmaDescriptor_ = dma_.addDescriptor ((void *)&ADC->RESULT .reg , (void *)&dmaLatestResult_, 1 ,
237- DMA_BEAT_SIZE_HWORD, false , false );
272+ Adc *const adc = adcInstance ();
273+
274+ dmaDescriptor_ =
275+ dma_.addDescriptor ((void *)&adc->RESULT .reg , (void *)&dmaLatestResult_,
276+ 1 , DMA_BEAT_SIZE_HWORD, false , false );
238277 if (dmaDescriptor_ == nullptr ) {
239278 dma_.free ();
240279 PendSV::instance ().clearService (kAdcPendSvServiceId );
@@ -249,8 +288,8 @@ bool AdcEngine::begin() {
249288 NVIC_EnableIRQ (irq);
250289 }
251290
252- ADC ->INTFLAG .reg = ADC_INTFLAG_RESRDY | ADC_INTFLAG_WINMON;
253- ADC ->INTENSET .bit .RESRDY = 1 ;
291+ adc ->INTFLAG .reg = ADC_INTFLAG_RESRDY | ADC_INTFLAG_WINMON;
292+ adc ->INTENSET .bit .RESRDY = 1 ;
254293 initialized_ = true ;
255294 return true ;
256295}
@@ -264,16 +303,19 @@ void AdcEngine::end() {
264303 NVIC_DisableIRQ (irq);
265304 NVIC_ClearPendingIRQ (irq);
266305 }
267- ADC->INTENCLR .bit .RESRDY = 1 ;
306+ Adc *const adc = adcInstance ();
307+
308+ adc->INTENCLR .bit .RESRDY = 1 ;
268309
269310 if (dmaActive_)
270311 dma_.abort ();
271312
272313 dma_.free ();
273314 dmaDescriptor_ = nullptr ;
274315
275- ADC->CTRLA .bit .SWRST = 1 ;
276- while (ADC->CTRLA .bit .SWRST );
316+ adc->CTRLA .bit .SWRST = 1 ;
317+ while (adc->CTRLA .bit .SWRST )
318+ ;
277319 waitAdcSync ();
278320
279321 PendSV::instance ().clearService (kAdcPendSvServiceId );
@@ -389,20 +431,22 @@ uint32_t AdcEngine::enabledMask() const {
389431}
390432
391433void AdcEngine::onResrdyIsr () {
392- const uint8_t flags = static_cast <uint8_t >(ADC->INTFLAG .reg & 0x0F );
393-
394- if ((flags & ADC_INTFLAG_WINMON) != 0u ) {
395- ChannelADC *channel = activeChannel_;
396- if (channel != nullptr && channel->windowEnabled_ && channel->onWindowMonitor_ != nullptr ) {
397- const uint16_t result = ADC->RESULT .reg ;
398- channel->onWindowMonitor_ (channel, result, channel->windowUserData_ );
399- }
434+ Adc *const adc = adcInstance ();
435+ const uint8_t flags = static_cast <uint8_t >(adc->INTFLAG .reg & 0x0F );
436+
437+ if ((flags & ADC_INTFLAG_WINMON) != 0u ) {
438+ ChannelADC *channel = activeChannel_;
439+ if (channel != nullptr && channel->windowEnabled_ &&
440+ channel->onWindowMonitor_ != nullptr ) {
441+ const uint16_t result = adc->RESULT .reg ;
442+ channel->onWindowMonitor_ (channel, result, channel->windowUserData_ );
400443 }
444+ }
401445
402446 if ((flags & ADC_INTFLAG_RESRDY) != 0u )
403- ADC ->INTFLAG .reg = ADC_INTFLAG_RESRDY;
447+ adc ->INTFLAG .reg = ADC_INTFLAG_RESRDY;
404448
405- ADC ->INTFLAG .reg = 0x0F ;
449+ adc ->INTFLAG .reg = 0x0F ;
406450}
407451
408452void AdcEngine::onPendSv () {
@@ -458,28 +502,30 @@ bool AdcEngine::applyChannelAndStart(ChannelADC *channel, bool monitorMode) {
458502 if (channel == nullptr )
459503 return false ;
460504
461- ADC->CTRLA .bit .ENABLE = 0 ;
505+ Adc *const adc = adcInstance ();
506+
507+ adc->CTRLA .bit .ENABLE = 0 ;
462508 waitAdcSync ();
463509
464510 const uint8_t refctrlReg = static_cast <uint8_t >(ADC_REFCTRL_REFSEL (channel->refSel_ ));
465- ADC ->REFCTRL .reg = refctrlReg;
511+ adc ->REFCTRL .reg = refctrlReg;
466512
467513#ifdef FAMILY_SAMD5X
468514 const uint16_t inputCtrlReg = static_cast <uint16_t >(
469515 ADC_INPUTCTRL_MUXPOS (channel->muxPos_ ) | ADC_INPUTCTRL_MUXNEG (channel->muxNeg_ ) |
470516 (channel->differentialMode_ ? ADC_INPUTCTRL_DIFFMODE : 0u ));
471- ADC ->INPUTCTRL .reg = inputCtrlReg;
517+ adc ->INPUTCTRL .reg = inputCtrlReg;
472518
473519 const uint8_t avgCtrlReg =
474520 static_cast <uint8_t >(ADC_AVGCTRL_SAMPLENUM (sampleNumToCode (channel->sampleNum_ )) |
475521 ADC_AVGCTRL_ADJRES (channel->adjres_ ));
476- ADC ->AVGCTRL .reg = avgCtrlReg;
522+ adc ->AVGCTRL .reg = avgCtrlReg;
477523
478- uint16_t ctrlaReg = ADC ->CTRLA .reg ;
524+ uint16_t ctrlaReg = adc ->CTRLA .reg ;
479525 ctrlaReg =
480526 static_cast <uint16_t >((ctrlaReg & ~ADC_CTRLA_PRESCALER_Msk) |
481527 ADC_CTRLA_PRESCALER (static_cast <uint8_t >(channel->prescaler_ )));
482- ADC ->CTRLA .reg = ctrlaReg;
528+ adc ->CTRLA .reg = ctrlaReg;
483529
484530 const uint16_t ctrlbReg = static_cast <uint16_t >(
485531 (channel->leftAdjust_ ? ADC_CTRLB_LEFTADJ : 0u ) |
@@ -489,30 +535,30 @@ bool AdcEngine::applyChannelAndStart(ChannelADC *channel, bool monitorMode) {
489535 ADC_CTRLB_WINMODE (channel->windowEnabled_
490536 ? static_cast <uint8_t >(channel->winMode_ )
491537 : static_cast <uint8_t >(AdcWinMode::ADC_WINMODE_DISABLE)));
492- ADC ->CTRLB .reg = ctrlbReg;
538+ adc ->CTRLB .reg = ctrlbReg;
493539
494540 const uint8_t evctrlReg =
495541 static_cast <uint8_t >((channel->evWinmonEo_ ? ADC_EVCTRL_WINMONEO : 0u ) |
496542 (channel->evResrdyEo_ ? ADC_EVCTRL_RESRDYEO : 0u ) |
497- (channel->evSyncei_ ? ADC_EVCTRL_SYNCEI : 0u ) |
543+ (channel->evSyncei_ ? kAdcEvctrlSynceiBit : 0u ) |
498544 (channel->evStartei_ ? ADC_EVCTRL_STARTEI : 0u ));
499- ADC ->EVCTRL .reg = evctrlReg;
545+ adc ->EVCTRL .reg = evctrlReg;
500546
501- ADC ->WINLT .reg = channel->windowLower_ ;
502- ADC ->WINUT .reg = channel->windowUpper_ ;
547+ adc ->WINLT .reg = channel->windowLower_ ;
548+ adc ->WINUT .reg = channel->windowUpper_ ;
503549
504- ADC ->OFFSETCORR .reg = static_cast <uint16_t >(channel->offsetCorr_ );
505- ADC ->GAINCORR .reg = channel->gainCorr_ ;
550+ adc ->OFFSETCORR .reg = static_cast <uint16_t >(channel->offsetCorr_ );
551+ adc ->GAINCORR .reg = channel->gainCorr_ ;
506552#else
507553 const uint16_t inputCtrlReg = static_cast <uint16_t >(
508554 ADC_INPUTCTRL_MUXPOS (channel->muxPos_ ) | ADC_INPUTCTRL_MUXNEG (channel->muxNeg_ ) |
509555 ADC_INPUTCTRL_GAIN (static_cast <uint8_t >(channel->gain_ )));
510- ADC ->INPUTCTRL .reg = inputCtrlReg;
556+ adc ->INPUTCTRL .reg = inputCtrlReg;
511557
512558 const uint8_t avgCtrlReg =
513559 static_cast <uint8_t >(ADC_AVGCTRL_SAMPLENUM (sampleNumToCode (channel->sampleNum_ )) |
514560 ADC_AVGCTRL_ADJRES (channel->adjres_ ));
515- ADC ->AVGCTRL .reg = avgCtrlReg;
561+ adc ->AVGCTRL .reg = avgCtrlReg;
516562
517563 const uint16_t ctrlbReg =
518564 static_cast <uint16_t >((channel->differentialMode_ ? ADC_CTRLB_DIFFMODE : 0u ) |
@@ -521,48 +567,49 @@ bool AdcEngine::applyChannelAndStart(ChannelADC *channel, bool monitorMode) {
521567 (channel->corrEnabled_ ? ADC_CTRLB_CORREN : 0u ) |
522568 ADC_CTRLB_RESSEL (static_cast <uint8_t >(channel->ressel_ )) |
523569 ADC_CTRLB_PRESCALER (static_cast <uint8_t >(channel->prescaler_ )));
524- ADC ->CTRLB .reg = ctrlbReg;
570+ adc ->CTRLB .reg = ctrlbReg;
525571
526572 const uint8_t evctrlReg =
527573 static_cast <uint8_t >((channel->evWinmonEo_ ? ADC_EVCTRL_WINMONEO : 0u ) |
528574 (channel->evResrdyEo_ ? ADC_EVCTRL_RESRDYEO : 0u ) |
529- (channel->evSyncei_ ? ADC_EVCTRL_SYNCEI : 0u ) |
575+ (channel->evSyncei_ ? kAdcEvctrlSynceiBit : 0u ) |
530576 (channel->evStartei_ ? ADC_EVCTRL_STARTEI : 0u ));
531- ADC ->EVCTRL .reg = evctrlReg;
577+ adc ->EVCTRL .reg = evctrlReg;
532578
533- ADC ->WINLT .reg = channel->windowLower_ ;
534- ADC ->WINUT .reg = channel->windowUpper_ ;
579+ adc ->WINLT .reg = channel->windowLower_ ;
580+ adc ->WINUT .reg = channel->windowUpper_ ;
535581
536582 const uint8_t winctrlReg = static_cast <uint8_t >(
537583 ADC_WINCTRL_WINMODE (channel->windowEnabled_ ? static_cast <uint8_t >(channel->winMode_ ) : 0 ));
538- ADC ->WINCTRL .reg = winctrlReg;
584+ adc ->WINCTRL .reg = winctrlReg;
539585
540- ADC ->OFFSETCORR .reg = static_cast <uint16_t >(channel->offsetCorr_ );
541- ADC ->GAINCORR .reg = channel->gainCorr_ ;
586+ adc ->OFFSETCORR .reg = static_cast <uint16_t >(channel->offsetCorr_ );
587+ adc ->GAINCORR .reg = channel->gainCorr_ ;
542588#endif
543589
544590 waitAdcSync ();
545591
546- ADC ->INTENCLR .reg = 0x0F ;
592+ adc ->INTENCLR .reg = 0x0F ;
547593 const uint8_t intensetReg =
548594 static_cast <uint8_t >(ADC_INTENSET_RESRDY |
549595 ((monitorMode && channel->windowEnabled_ ) ? ADC_INTENSET_WINMON : 0u ));
550- ADC ->INTENSET .reg = intensetReg;
596+ adc ->INTENSET .reg = intensetReg;
551597
552- ADC ->INTFLAG .reg = 0x0F ;
598+ adc ->INTFLAG .reg = 0x0F ;
553599
554600 if (dmaDescriptor_ == nullptr )
555601 return false ;
556602
557- dma_.changeDescriptor (dmaDescriptor_, (void *)&ADC->RESULT .reg , (void *)&dmaLatestResult_, 1 );
603+ dma_.changeDescriptor (dmaDescriptor_, (void *)&adc->RESULT .reg ,
604+ (void *)&dmaLatestResult_, 1 );
558605 if (dma_.startJob () != DMA_STATUS_OK)
559606 return false ;
560607
561608 dmaActive_ = true ;
562609 activeChannel_ = channel;
563610 activeMonitorMode_ = monitorMode;
564611
565- ADC ->CTRLA .bit .ENABLE = 1 ;
612+ adc ->CTRLA .bit .ENABLE = 1 ;
566613 waitAdcSync ();
567614 startConversion ();
568615 return true ;
@@ -586,10 +633,13 @@ bool AdcEngine::startMonitorIfIdle() {
586633}
587634
588635void AdcEngine::waitAdcSync () const {
636+ Adc *const adc = adcInstance ();
589637#ifdef FAMILY_SAMD5X
590- while (ADC->SYNCBUSY .reg );
638+ while (adc->SYNCBUSY .reg )
639+ ;
591640#else
592- while (ADC->STATUS .bit .SYNCBUSY );
641+ while (adc->STATUS .bit .SYNCBUSY )
642+ ;
593643#endif
594644}
595645
0 commit comments