#include "adc.h"
#include "registers.h"
#include "stm32f401xe.h"
void adc_init(adc_t* adc, ADC_TypeDef* periph) {
adc->periph = periph;
}
void adc_configure(adc_t *adc, adc_resolution_t resolution,
adc_alignment_t alignment, bool continuous) {
reg_write_bits(&adc->periph->CR1, resolution << ADC_CR1_RES_Pos, ADC_CR1_RES_Msk);
reg_write_bits(&adc->periph->CR2, ((continuous == true) << ADC_CR2_CONT_Pos) | (alignment << ADC_CR2_ALIGN_Pos), ADC_CR2_CONT_Msk | ADC_CR2_ALIGN_Msk);
}
void adc_enable(adc_t *adc, bool enable) {
reg_set_bits(&adc->periph->CR2, ADC_CR2_ADON);
}
void adc_sequence(adc_t *adc, uint8_t count) {
reg_write_bits(&adc->periph->SQR1, count << ADC_SQR1_L_Pos, ADC_SQR1_L_Msk);
}
void adc_select(adc_t *adc, uint8_t conversion_idx, uint8_t channel) {
uint8_t reg = conversion_idx / 6;
uint8_t pos = (conversion_idx % 6) * 4;
volatile uint32_t* reg_ptr = &adc->periph->SQR3 - reg;
reg_write_bits_pos(reg_ptr, channel & 0xF, pos, 0xF);
}
void adc_external_trigger(adc_t* adc, adc_external_trigger_regular_t config, adc_external_trigger_source_regular_t source) {
reg_write_bits(&adc->periph->CR2,
(source << ADC_CR2_EXTSEL_Pos) | (config << ADC_CR2_EXTEN_Pos),
ADC_CR2_EXTSEL_Msk | ADC_CR2_EXTEN_Msk);
}
/* void adc_start_capture(adc_t* adc); */
bool adc_is_captured(adc_t *adc) {
return adc->periph->SR & ADC_SR_EOC;
}
uint32_t adc_captured_value(adc_t *adc) {
// TODO: different resolutions, right or left aligned
return adc->periph->DR & 0xFFF;
}
uint32_t adc_convert_voltage(uint32_t capture, uint32_t min, uint32_t max) {
return 0;
}