BV: add hardware revision variable and identification
This commit is contained in:
parent
400df7c392
commit
d75b42377d
|
@ -49,6 +49,12 @@ static volatile bool busvoodoo_global_led_blue = false;
|
|||
/** red LED status */
|
||||
static volatile bool busvoodoo_global_led_red = false;
|
||||
|
||||
/** existing hardware revisions identifiable with voltages */
|
||||
static const uint8_t busvoodoo_revision_numbers[] = {27};
|
||||
/** hardware revision voltages (calculated from divider ratios) */
|
||||
static const float busvoodoo_revision_voltages[] = {100.0/(10.0+100.0)*3.3};
|
||||
|
||||
|
||||
const char* busvoodoo_global_pinout_io[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
const char* busvoodoo_global_pinout_rscan[5] = {NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
|
@ -58,6 +64,7 @@ const uint32_t busvoodoo_io_pins[13] = {GPIO12, GPIO2, GPIO13, GPIO11, GPIO11, G
|
|||
const uint8_t busvoodoo_io_groups[13] = {6, 6, 4, 4, 1, 1, 5, 5, 2, 2, 3, 3, 3};
|
||||
|
||||
bool busvoodoo_full = false;
|
||||
uint8_t busvoodoo_revision = 0;
|
||||
|
||||
void busvoodoo_setup(void)
|
||||
{
|
||||
|
@ -80,6 +87,48 @@ void busvoodoo_setup(void)
|
|||
busvoodoo_full = true;
|
||||
}
|
||||
|
||||
// setup ADC to measure hardware revision voltage
|
||||
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_HW_REV_CHANNEL)); // enable clock for GPIO domain for hardware revision channel
|
||||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_HW_REV_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_HW_REV_CHANNEL)); // set hardware revision 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 rev_channels[] = {ADC_CHANNEL17, ADC_CHANNEL(BUSVOODOO_HW_REV_CHANNEL)}; // voltages to convert: internal, hardware revision
|
||||
adc_set_regular_sequence(ADC1, LENGTH(rev_channels), rev_channels); // set channels to convert
|
||||
adc_enable_discontinuous_mode_regular(ADC1, LENGTH(rev_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(rev_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 revision_voltage = channels[1]*1.2/channels[0]; // calculate voltage
|
||||
|
||||
// find out revision of the board
|
||||
gpio_set_mode(GPIO(BUSVOODOO_HW_REV_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO(BUSVOODOO_HW_REV_PIN)); // use pull up and down to check if a voltage divider is present on the pin
|
||||
gpio_set(GPIO(BUSVOODOO_HW_REV_PORT), GPIO(BUSVOODOO_HW_REV_PIN)); // pull up
|
||||
bool rev_up = (0!=gpio_get(GPIO(BUSVOODOO_HW_REV_PORT), GPIO(BUSVOODOO_HW_REV_PIN))); // check if the signal is still up
|
||||
gpio_clear(GPIO(BUSVOODOO_HW_REV_PORT), GPIO(BUSVOODOO_HW_REV_PIN)); // pull down
|
||||
bool rev_down = (0==gpio_get(GPIO(BUSVOODOO_HW_REV_PORT), GPIO(BUSVOODOO_HW_REV_PIN))); // check if the signal is still down
|
||||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_HW_REV_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_HW_REV_CHANNEL)); // put back to analog input
|
||||
// get revision
|
||||
if (rev_up && rev_down) { // no voltage divider on pin
|
||||
busvoodoo_revision = 18; // the pin is floating only for revision 18
|
||||
} else { // voltage divider on pin
|
||||
for (uint8_t i=0; i<LENGTH(busvoodoo_revision_numbers) && i<LENGTH(busvoodoo_revision_voltages); i++) { // go through expected revision voltages
|
||||
if (revision_voltage>busvoodoo_revision_voltages[i]-0.2 && revision_voltage<busvoodoo_revision_voltages[i]+0.2) { // verify if voltage matches
|
||||
busvoodoo_revision = busvoodoo_revision_numbers[i]; // remember revision number for matching voltage
|
||||
break; // stop searching
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setup ADC to measure the 5V, 3.3V, LV, and HV power rails voltages
|
||||
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
|
||||
|
@ -89,14 +138,16 @@ void busvoodoo_setup(void)
|
|||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_LV_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_LV_CHANNEL)); // set LV channel as analogue input for the ADC
|
||||
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_HV_CHANNEL)); // enable clock for GPIO domain for HV channel
|
||||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_HV_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_HV_CHANNEL)); // set HV channel as analogue input for the ADC
|
||||
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_HW_REV_CHANNEL)); // enable clock for GPIO domain for hardware revision channel
|
||||
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_HW_REV_CHANNEL), GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, ADC12_IN_PIN(BUSVOODOO_HW_REV_CHANNEL)); // set hardware revision 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 channels[] = {ADC_CHANNEL17, ADC_CHANNEL(BUSVOODOO_5V_CHANNEL), ADC_CHANNEL(BUSVOODOO_3V3_CHANNEL), ADC_CHANNEL(BUSVOODOO_LV_CHANNEL), ADC_CHANNEL(BUSVOODOO_HV_CHANNEL)}; // voltages to convert: internal, 5V, 3.3V, LV, HV
|
||||
adc_set_regular_sequence(ADC1, LENGTH(channels), channels); // set channels to convert
|
||||
adc_enable_discontinuous_mode_regular(ADC1, LENGTH(channels)); // convert all channels
|
||||
uint8_t rail_channels[] = {ADC_CHANNEL17, ADC_CHANNEL(BUSVOODOO_5V_CHANNEL), ADC_CHANNEL(BUSVOODOO_3V3_CHANNEL), ADC_CHANNEL(BUSVOODOO_LV_CHANNEL), ADC_CHANNEL(BUSVOODOO_HV_CHANNEL)}; // voltages to convert: internal, 5V, 3.3V, LV, HV
|
||||
adc_set_regular_sequence(ADC1, LENGTH(rail_channels), rail_channels); // set channels to convert
|
||||
adc_enable_discontinuous_mode_regular(ADC1, LENGTH(rail_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
|
||||
|
@ -201,7 +252,7 @@ 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
|
||||
return NAN;
|
||||
}
|
||||
uint16_t channels[5] = {0}; // to start converted values: internal reference 1.2V, 5V rail, 3.3V rail, LV rail, HV rail
|
||||
uint16_t channels[5] = {0}; // to start converted values: internal reference 1.2V, 5V rail, 3.3V rail, LV rail, HV rail, hardware version
|
||||
adc_start_conversion_regular(ADC1); // start conversion to get first voltage
|
||||
for (uint8_t channel_i=0; channel_i<LENGTH(channels); channel_i++) { // get all conversions
|
||||
while (!adc_eoc(ADC1)); // wait until conversion finished
|
||||
|
@ -619,7 +670,7 @@ const struct menu_command_t busvoodoo_global_commands[] = {
|
|||
&busvoodoo_global_power,
|
||||
},
|
||||
{
|
||||
'l',
|
||||
'L',
|
||||
"LV",
|
||||
"set voltage on low voltage power rail (0, 0.3-4.8, 5V)",
|
||||
MENU_ARGUMENT_FLOAT,
|
||||
|
|
|
@ -97,6 +97,13 @@
|
|||
#define BUSVOODOO_CAN_RX_PIN 8 /**< CAN Receive input pin */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup busvoodoo_revision ADC pin used to identify hardware revision based on voltage
|
||||
*/
|
||||
#define BUSVOODOO_HW_REV_PORT B /**< pin to identify hardware revision */
|
||||
#define BUSVOODOO_HW_REV_PIN 0 /**< pin to identify hardware revision */
|
||||
#define BUSVOODOO_HW_REV_CHANNEL 8 /**< ADC to identify hardware revision */
|
||||
/** @} */
|
||||
|
||||
/** BusVoodoo mode interface */
|
||||
struct busvoodoo_mode_t {
|
||||
const char* name;
|
||||
|
@ -118,6 +125,8 @@ extern const uint8_t busvoodoo_io_groups[13]; /**< which I/O pin (group) does th
|
|||
|
||||
/** is the BusVoodoo board fully populated (with HV voltage regulator, RS-232, RS-485, CAN transceiver on the back side) */
|
||||
extern bool busvoodoo_full;
|
||||
/** revision of the hardware board */
|
||||
extern uint8_t busvoodoo_revision;
|
||||
/** list of supported commands */
|
||||
extern const struct menu_command_t busvoodoo_global_commands[4];
|
||||
|
||||
|
|
Loading…
Reference in New Issue