6#include "../../hardware_api.h"
7#include "../../../drivers/hardware_specific/samd/samd_mcu.h"
10static uint16_t adc_raw[3] = {0, 0, 0};
11static uint8_t current_phase = 0;
12static bool is_high_side =
true;
14#define _SAMD21_ADC_VOLTAGE 3.3f
15#define _SAMD21_ADC_RESOLUTION 4095.0f
20 ADC->CTRLA.bit.ENABLE = 0;
21 while (ADC->STATUS.bit.SYNCBUSY);
23 ADC->REFCTRL.reg = ADC_REFCTRL_REFSEL_INTVCC1;
24 ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV16 | ADC_CTRLB_RESSEL_12BIT;
25 ADC->CTRLB.bit.FREERUN = 0;
26 while (ADC->STATUS.bit.SYNCBUSY);
28 ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[_pinA].ulADCChannelNumber;
33 while (ADC->STATUS.bit.SYNCBUSY);
36 ADC->EVCTRL.bit.STARTEI = 1;
37 ADC->INTENSET.bit.RESRDY = 1;
38 NVIC_EnableIRQ(ADC_IRQn);
41 uint8_t tcc_num = par->tccPinConfigurations[1]->tcc.tccn;
46 case 0: tcc = TCC0;
break;
47 case 1: tcc = TCC1;
break;
48 case 2: tcc = TCC2;
break;
49 default: tcc = TCC0;
break;
56 tcc->CTRLA.bit.ENABLE = 0;
57 while (tcc->SYNCBUSY.bit.ENABLE);
58 tcc->EVCTRL.reg |= TCC_EVCTRL_OVFEO;
59 tcc->CTRLA.bit.ENABLE = 1;
60 while (tcc->SYNCBUSY.bit.ENABLE);
67 case 0: evgen = EVSYS_ID_GEN_TCC0_OVF;
break;
68 case 1: evgen = EVSYS_ID_GEN_TCC1_OVF;
break;
69 case 2: evgen = EVSYS_ID_GEN_TCC2_OVF;
break;
70 default: evgen = EVSYS_ID_GEN_TCC0_OVF;
break;
73 PM->APBCMASK.reg |= PM_APBCMASK_EVSYS;
74 EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(0)
75 | EVSYS_CHANNEL_EVGEN(evgen)
76 | EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
77 EVSYS->USER.reg = EVSYS_USER_USER(EVSYS_ID_USER_ADC_START)
78 | EVSYS_USER_CHANNEL(1);
81 ADC->CTRLA.bit.ENABLE = 1;
82 while (ADC->STATUS.bit.SYNCBUSY);
90 is_high_side = !is_high_side;
92 ADC->INTFLAG.reg = ADC_INTFLAG_RESRDY;
98 if (ADC->INTFLAG.bit.RESRDY) {
99 uint16_t result = ADC->RESULT.reg;
101 adc_raw[current_phase] = result;
102 if (current_phase == 0) {
103 ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[_pinB].ulADCChannelNumber;
105 }
else if (current_phase == 1) {
107 ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[_pinC].ulADCChannelNumber;
110 ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[_pinA].ulADCChannelNumber;
114 ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[_pinA].ulADCChannelNumber;
117 ADC->INTFLAG.reg = ADC_INTFLAG_RESRDY;
128 SIMPLEFOC_DEBUG(
"SAMD-CUR: ERR: Pins already in use for current sensing!");
145 .adc_voltage_conv = (_SAMD21_ADC_VOLTAGE) / (_SAMD21_ADC_RESOLUTION),
160 if (p == pin)
return adc_raw[i] * countsToVolts;
#define SIMPLEFOC_DEBUG(msg,...)
void * _driverSyncLowSide(void *driver_params, void *cs_params)
#define SIMPLEFOC_CURRENT_SENSE_INIT_FAILED
void * _configureADCLowSide(const void *driver_params, const int pinA, const int pinB, const int pinC=NOT_SET)
float _readADCVoltageLowSide(const int pinA, const void *cs_params)
const int const int const int pinC
GenericCurrentSenseParams * params