You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.4 KiB
54 lines
1.4 KiB
|
|
typedef struct {
|
|
ADC_TypeDef *adc;
|
|
uint8_t channel;
|
|
} adc_channel_t;
|
|
|
|
void adc_init(ADC_TypeDef *adc) {
|
|
adc->CR &= ~(ADC_CR_DEEPPWD); // Reset deep-power-down mode
|
|
adc->CR |= ADC_CR_ADVREGEN; // Enable ADC regulator
|
|
while(!(adc->ISR & ADC_ISR_LDORDY) && (adc != ADC3));
|
|
|
|
if (adc != ADC3) {
|
|
adc->CR &= ~(ADC_CR_ADCALDIF); // Choose single-ended calibration
|
|
adc->CR |= ADC_CR_ADCALLIN; // Lineriality calibration
|
|
}
|
|
adc->CR |= ADC_CR_ADCAL; // Start calibrtation
|
|
while((adc->CR & ADC_CR_ADCAL) != 0);
|
|
|
|
adc->ISR |= ADC_ISR_ADRDY;
|
|
adc->CR |= ADC_CR_ADEN;
|
|
while(!(adc->ISR & ADC_ISR_ADRDY));
|
|
}
|
|
|
|
uint16_t adc_get_raw(ADC_TypeDef *adc, uint8_t channel) {
|
|
adc->SQR1 &= ~(ADC_SQR1_L);
|
|
adc->SQR1 = ((uint32_t) channel << 6U);
|
|
|
|
if (channel < 10U) {
|
|
adc->SMPR1 = (0x7U << (channel * 3U));
|
|
} else {
|
|
adc->SMPR2 = (0x7U << ((channel - 10U) * 3U));
|
|
}
|
|
adc->PCSEL_RES0 = (0x1U << channel);
|
|
|
|
adc->CR |= ADC_CR_ADSTART;
|
|
while (!(adc->ISR & ADC_ISR_EOC));
|
|
|
|
uint16_t res = adc->DR;
|
|
|
|
while (!(adc->ISR & ADC_ISR_EOS));
|
|
adc->ISR |= ADC_ISR_EOS;
|
|
|
|
return res;
|
|
}
|
|
|
|
uint16_t adc_get_mV(ADC_TypeDef *adc, uint8_t channel) {
|
|
uint16_t ret = 0;
|
|
if ((adc == ADC1) || (adc == ADC2)) {
|
|
ret = (adc_get_raw(adc, channel) * current_board->avdd_mV) / 65535U;
|
|
} else if (adc == ADC3) {
|
|
ret = (adc_get_raw(adc, channel) * current_board->avdd_mV) / 4095U;
|
|
} else {}
|
|
return ret;
|
|
}
|
|
|