BV: unify ADC readout
This commit is contained in:
parent
b04fcb7d3e
commit
db930f645c
|
@ -85,49 +85,7 @@ void busvoodoo_setup(void)
|
|||
busvoodoo_safe_state(); // also put the full version pins in safe state
|
||||
}
|
||||
|
||||
// setup ADC to measure hardware version voltage
|
||||
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_HW_VERSION_CHANNEL)); // enable clock for GPIO domain for hardware version channel
|
||||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_HW_VERSION_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_HW_VERSION_CHANNEL)); // set hardware version channel as analogue input for the ADC
|
||||
rcc_periph_clock_enable(RCC_ADC1); // enable clock for ADC domain
|
||||
adc_off(ADC1); // switch off ADC while configuring it
|
||||
adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); // use 28.5 cycles to sample (long enough to be stable)
|
||||
adc_enable_temperature_sensor(ADC1); // enable internal voltage reference
|
||||
adc_enable_external_trigger_regular(ADC1, ADC_CR2_EXTSEL_SWSTART); // use software trigger to start conversion
|
||||
uint8_t version_channels[] = {ADC_CHANNEL17, ADC_CHANNEL(BUSVOODOO_HW_VERSION_CHANNEL)}; // voltages to convert: internal, hardware version
|
||||
adc_set_regular_sequence(ADC1, LENGTH(version_channels), version_channels); // set channels to convert
|
||||
adc_enable_discontinuous_mode_regular(ADC1, LENGTH(version_channels)); // convert all channels
|
||||
adc_power_on(ADC1); // switch on ADC
|
||||
sleep_us(1); // wait t_stab for the ADC to stabilize
|
||||
adc_reset_calibration(ADC1); // remove previous non-calibration
|
||||
adc_calibration(ADC1); // calibrate ADC for less accuracy errors
|
||||
adc_start_conversion_regular(ADC1); // start conversion to get first voltage
|
||||
uint16_t channels[LENGTH(version_channels)] = {0}; // to store the values measured on the channels
|
||||
for (uint8_t channel_i=0; channel_i<LENGTH(channels); channel_i++) { // get all conversions
|
||||
while (!adc_eoc(ADC1)); // wait until conversion finished
|
||||
channels[channel_i] = adc_read_regular(ADC1); // read voltage value (clears flag)
|
||||
}
|
||||
float version_voltage = channels[1]*1.2/channels[0]; // calculate voltage
|
||||
|
||||
// find out version of the board
|
||||
gpio_set_mode(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO(BUSVOODOO_HW_VERSION_PIN)); // use pull up and down to check if a voltage divider is present on the pin
|
||||
gpio_set(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO(BUSVOODOO_HW_VERSION_PIN)); // pull up
|
||||
bool version_up = (0!=gpio_get(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO(BUSVOODOO_HW_VERSION_PIN))); // check if the signal is still up
|
||||
gpio_clear(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO(BUSVOODOO_HW_VERSION_PIN)); // pull down
|
||||
bool version_down = (0==gpio_get(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO(BUSVOODOO_HW_VERSION_PIN))); // check if the signal is still down
|
||||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_HW_VERSION_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_HW_VERSION_CHANNEL)); // put back to analog input
|
||||
// get version
|
||||
if (version_up && version_down) { // no voltage divider on pin
|
||||
busvoodoo_version = '0'; // the pin is floating only for version 0 (= revision 18)
|
||||
} else { // voltage divider on pin
|
||||
for (uint8_t i=0; i<LENGTH(busvoodoo_version_voltages); i++) { // go through expected version voltages
|
||||
if (version_voltage>busvoodoo_version_voltages[i]-0.2 && version_voltage<busvoodoo_version_voltages[i]+0.2) { // verify if voltage matches
|
||||
busvoodoo_version = 'A'+i; // remember version name for matching voltage
|
||||
break; // stop searching
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setup ADC to measure the 5V, 3.3V, LV, and HV power rails voltages
|
||||
// setup ADC to measure the 5V, 3.3V, LV, and HV power rails voltages, and hardware version channel
|
||||
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_5V_CHANNEL)); // enable clock for GPIO domain for 5V channel
|
||||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_5V_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_5V_CHANNEL)); // set 5V channel as analogue input for the ADC
|
||||
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_3V3_CHANNEL)); // enable clock for GPIO domain for 3.3V channel
|
||||
|
@ -143,11 +101,32 @@ void busvoodoo_setup(void)
|
|||
adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); // use 28.5 cycles to sample (long enough to be stable)
|
||||
adc_enable_temperature_sensor(ADC1); // enable internal voltage reference
|
||||
adc_enable_external_trigger_regular(ADC1, ADC_CR2_EXTSEL_SWSTART); // use software trigger to start conversion
|
||||
adc_set_single_conversion_mode(ADC1); // we only convert one channel after another
|
||||
adc_power_on(ADC1); // switch on ADC
|
||||
sleep_us(1); // wait t_stab for the ADC to stabilize
|
||||
adc_reset_calibration(ADC1); // remove previous non-calibration
|
||||
adc_calibration(ADC1); // calibrate ADC for less accuracy errors
|
||||
|
||||
// find out version of the board
|
||||
gpio_set_mode(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO(BUSVOODOO_HW_VERSION_PIN)); // use pull up and down to check if a voltage divider is present on the pin
|
||||
gpio_set(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO(BUSVOODOO_HW_VERSION_PIN)); // pull up
|
||||
bool version_up = (0!=gpio_get(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO(BUSVOODOO_HW_VERSION_PIN))); // check if the signal is still up
|
||||
gpio_clear(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO(BUSVOODOO_HW_VERSION_PIN)); // pull down
|
||||
bool version_down = (0==gpio_get(GPIO(BUSVOODOO_HW_VERSION_PORT), GPIO(BUSVOODOO_HW_VERSION_PIN))); // check if the signal is still down
|
||||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_HW_VERSION_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_HW_VERSION_CHANNEL)); // put back to analog input
|
||||
// get version
|
||||
if (version_up && version_down) { // no voltage divider on pin
|
||||
busvoodoo_version = '0'; // the pin is floating only for version 0 (= revision 18)
|
||||
} else { // voltage divider on pin
|
||||
float version_voltage = busvoodoo_vreg_get(BUSVOODOO_HW_VERSION_CHANNEL); // measure hardware version voltage
|
||||
for (uint8_t i=0; i<LENGTH(busvoodoo_version_voltages); i++) { // go through expected version voltages
|
||||
if (version_voltage>busvoodoo_version_voltages[i]-0.2 && version_voltage<busvoodoo_version_voltages[i]+0.2) { // verify if voltage matches
|
||||
busvoodoo_version = 'A'+i; // remember version name for matching voltage
|
||||
break; // stop searching
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setup DAC to control LV and HV voltage outputs
|
||||
gpio_set_mode(GPIO(BUSVOODOO_LVCTL_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO(BUSVOODOO_LVCTL_PIN)); // set LV pin as analog (the DAC will use it as output)
|
||||
rcc_periph_clock_enable(RCC_DAC); // enable clock for DAC domain
|
||||
|
@ -246,9 +225,10 @@ bool busvoodoo_vout_switch(bool on)
|
|||
|
||||
float busvoodoo_vreg_get(uint8_t channel)
|
||||
{
|
||||
if (channel!=BUSVOODOO_5V_CHANNEL && channel!=BUSVOODOO_3V3_CHANNEL && channel!=BUSVOODOO_LV_CHANNEL && channel!=BUSVOODOO_HV_CHANNEL) { // check channel
|
||||
if (channel!=BUSVOODOO_5V_CHANNEL && channel!=BUSVOODOO_3V3_CHANNEL && channel!=BUSVOODOO_LV_CHANNEL && channel!=BUSVOODOO_HV_CHANNEL && channel!=BUSVOODOO_HW_VERSION_CHANNEL) { // check channel
|
||||
return NAN;
|
||||
}
|
||||
|
||||
uint8_t channels[2] = {ADC_CHANNEL17, ADC_CHANNEL17}; // voltages to convert: internal and internal (as fallback)
|
||||
switch (channel) { // set desired channel
|
||||
case BUSVOODOO_5V_CHANNEL:
|
||||
|
@ -263,14 +243,17 @@ float busvoodoo_vreg_get(uint8_t channel)
|
|||
case BUSVOODOO_HV_CHANNEL:
|
||||
channels[1] = ADC_CHANNEL(BUSVOODOO_HV_CHANNEL);
|
||||
break;
|
||||
case BUSVOODOO_HW_VERSION_CHANNEL:
|
||||
channels[1] = ADC_CHANNEL(BUSVOODOO_HW_VERSION_CHANNEL);
|
||||
break;
|
||||
default: // unknown channel
|
||||
break;
|
||||
}
|
||||
adc_set_regular_sequence(ADC1, LENGTH(channels), channels); // set channels to convert
|
||||
adc_enable_discontinuous_mode_regular(ADC1, LENGTH(channels)); // convert all channels
|
||||
ADC_SR(ADC1) = 0; // reset flags
|
||||
adc_start_conversion_regular(ADC1); // start conversion to get first voltage
|
||||
uint16_t values[LENGTH(channels)] = {0}; // to store converted values
|
||||
ADC_SR(ADC1) = 0; // reset flags
|
||||
adc_start_conversion_regular(ADC1); // start conversion for individual channels
|
||||
for (uint8_t channel_i=0; channel_i<LENGTH(channels); channel_i++) { // get all conversions
|
||||
while (!adc_eoc(ADC1)); // wait until conversion finished
|
||||
values[channel_i] = adc_read_regular(ADC1); // read voltage value (clears flag)
|
||||
|
@ -289,6 +272,9 @@ float busvoodoo_vreg_get(uint8_t channel)
|
|||
case BUSVOODOO_HV_CHANNEL:
|
||||
to_return = values[1]/(1.5/(10.0+1.5));
|
||||
break;
|
||||
case BUSVOODOO_HW_VERSION_CHANNEL:
|
||||
to_return = values[1];
|
||||
break;
|
||||
default: // unknown channel
|
||||
to_return = NAN;
|
||||
break;
|
||||
|
@ -301,7 +287,6 @@ float busvoodoo_vreg_get(uint8_t channel)
|
|||
|
||||
float busvoodoo_lv_set(float voltage)
|
||||
{
|
||||
|
||||
float volt = NAN; // common variable for voltages
|
||||
if (voltage<=0.3) { // disable voltage regulator
|
||||
gpio_clear(GPIO(BUSVOODOO_LVEN_PORT), GPIO(BUSVOODOO_LVEN_PIN)); // disable LV voltage regulator
|
||||
|
|
Loading…
Reference in New Issue