diff options
Diffstat (limited to 'src/voltdisc.c')
-rw-r--r-- | src/voltdisc.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/voltdisc.c b/src/voltdisc.c new file mode 100644 index 0000000..034fdf8 --- /dev/null +++ b/src/voltdisc.c @@ -0,0 +1,44 @@ +#include "voltdisc.h" + +#include "ch573/adc.h" +#include "gpio.h" +#include "risc-v.h" + +#define ADC_I CH573_ADC__ADC_T_INTF +#define ADC ch573_adc__adc + +#define VOLTAGE_DIVIDER_COEF (11) + +millivolts_t get_input_voltage() +{ + // Pull down the voltage of the pin. Do this in case the MCU is in a chassis + // which does not have the voltage divider. + gpio_configure_pin(PIN_PA4, PIN_CFG_INPUT_PULL_DOWN); + + // Wait for the pin to discharge. + for (int i = 0; i < 10; ++i) { + __nop(); + } + + // Configure the pin to "floating". + gpio_configure_pin(PIN_PA4, PIN_CFG_INPUT_FLOATING); + + // Configure the ADC for reading. + ADC_I.cfg.adc_buf_en.set(ADC, ENABLED); + ADC_I.cfg.adc_power_on.set(ADC, ENABLED); + ADC_I.channel_select.set(ADC, 0); + ADC_I.dma_interrupt_control.auto_en.set(ADC, 1); + ADC_I.convert.adc_start.set(ADC, ON); + + uint32_t raw_value; + // Wait until the ADC is ready for reading. + while (!ADC_I.interrupt_flag.if_eoc.get(ADC)); + raw_value = ADC_I.data.get(ADC); + + ADC_I.convert.adc_start.set(ADC, OFF); + ADC_I.cfg.adc_power_on.set(ADC, DISABLED); + + // Attempt to calculate the original voltage + return (millivolts_t)(raw_value * 1.05 / 2048.0 * 1000) * + VOLTAGE_DIVIDER_COEF; +} |