rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_12V_CHANNEL));// enable clock for GPIO domain for 12V channel
gpio_set(ADC12_IN_PORT(BUSVOODOO_12V_CHANNEL),ADC12_IN_PIN(BUSVOODOO_12V_CHANNEL));// pull ADC 12V high
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_12V_CHANNEL),GPIO_MODE_INPUT,GPIO_CNF_INPUT_PULL_UPDOWN,ADC12_IN_PIN(BUSVOODOO_12V_CHANNEL));// set 12V channel as digital input with pull-up capabilities
// on a full version (fully populated board) the ADC 12V signal will be pulled low
if(gpio_get(ADC12_IN_PORT(BUSVOODOO_12V_CHANNEL),ADC12_IN_PIN(BUSVOODOO_12V_CHANNEL))){// check is ADC 12V is pulled low
busvoodoo_full=false;
}else{
busvoodoo_full=true;
}
// setup ADC to measure the 5V, 3.3V, xV, and 12V 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
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_3V3_CHANNEL));// enable clock for GPIO domain for 3.3V channel
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_3V3_CHANNEL),GPIO_MODE_INPUT,GPIO_CNF_INPUT_ANALOG,ADC12_IN_PIN(BUSVOODOO_3V3_CHANNEL));// set 3.3V channel as analogue input for the ADC
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_XV_CHANNEL));// enable clock for GPIO domain for xV channel
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_XV_CHANNEL),GPIO_MODE_INPUT,GPIO_CNF_INPUT_ANALOG,ADC12_IN_PIN(BUSVOODOO_XV_CHANNEL));// set xV channel as analogue input for the ADC
rcc_periph_clock_enable(RCC_ADC12_IN(BUSVOODOO_12V_CHANNEL));// enable clock for GPIO domain for 12V channel
gpio_set_mode(ADC12_IN_PORT(BUSVOODOO_12V_CHANNEL),GPIO_MODE_INPUT,GPIO_CNF_INPUT_ANALOG,ADC12_IN_PIN(BUSVOODOO_12V_CHANNEL));// set 12V 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_tchannels[]={ADC_CHANNEL17,ADC_CHANNEL(BUSVOODOO_5V_CHANNEL),ADC_CHANNEL(BUSVOODOO_3V3_CHANNEL),ADC_CHANNEL(BUSVOODOO_XV_CHANNEL),ADC_CHANNEL(BUSVOODOO_12V_CHANNEL)};// voltages to convert: internal, 5V, 3.3V, xV, 12V
adc_set_regular_sequence(ADC1,LENGTH(channels),channels);// set channels to convert
adc_enable_discontinuous_mode_regular(ADC1,LENGTH(channels));// convert all channels
adc_power_on(ADC1);// switch on ADC
sleep_us(1);// wait t_stab for the ADC to stabilize
adc_calibration(ADC1);// calibrate ADC for less accuracy errors
// setup DAC to control xV and 12V voltage outputs
gpio_set_mode(GPIO(BUSVOODOO_XVCTL_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_ANALOG,GPIO(BUSVOODOO_XVCTL_PIN));// set xV pin as analog (the DAC will use it as output)
rcc_periph_clock_enable(RCC_DAC);// enable clock for DAC domain
dac_disable(BUSVOODOO_XVCTL_CHANNEL);// disable output to configure it properly
dac_buffer_enable(BUSVOODOO_XVCTL_CHANNEL);// enable output buffer to be able to drive larger loads (should be per default)
if(busvoodoo_full){
gpio_set_mode(GPIO(BUSVOODOO_12VCTL_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_ANALOG,GPIO(BUSVOODOO_12VCTL_PIN));// set 12V pin as analog (the DAC will use it as output)
dac_disable(BUSVOODOO_12VCTL_CHANNEL);// disable output to configure it properly
dac_buffer_enable(BUSVOODOO_12VCTL_CHANNEL);// enable output buffer to be able to drive larger loads (should be per default)
}
dac_set_trigger_source(DAC_CR_TSEL1_SW);// use software to trigger the voltage change
dac_set_trigger_source(DAC_CR_TSEL2_SW);// use software to trigger the voltage change
timer_set_mode(TIM(BUSVOODOO_LED_TIMER),TIM_CR1_CKD_CK_INT,TIM_CR1_CMS_EDGE,TIM_CR1_DIR_UP);// configure timer to up counting mode
timer_set_prescaler(TIM(BUSVOODOO_LED_TIMER),(rcc_ahb_frequency/2000)-1);// set prescaler to have 2kHz ticks (the prescaler is not large enough for 1kHz ticks)
timer_set_period(TIM(BUSVOODOO_LED_TIMER),0xffff);// set period to maximum
nvic_enable_irq(NVIC_TIM_IRQ(BUSVOODOO_LED_TIMER));// enable interrupts for this timer
gpio_set(GPIO(BUSVOODOO_VOUTEN_PORT),GPIO(BUSVOODOO_VOUTEN_PIN));// disable 5V and 3.3V output on connector
gpio_set_mode(GPIO(BUSVOODOO_VOUTEN_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_OPENDRAIN,GPIO(BUSVOODOO_VOUTEN_PIN));// set pin as output (open-drain pulled high to disable the pMOS)
gpio_clear(GPIO(BUSVOODOO_XVEN_PORT),GPIO(BUSVOODOO_XVEN_PIN));// disable xV voltage regulator
gpio_set_mode(GPIO(BUSVOODOO_XVEN_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,GPIO(BUSVOODOO_XVEN_PIN));// set pin as output (push-pull, pulled low for safety)
gpio_set(GPIO(BUSVOODOO_12VEN_PORT),GPIO(BUSVOODOO_12VEN_PIN));// disable 12V voltage regulator
gpio_set_mode(GPIO(BUSVOODOO_12VEN_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_OPENDRAIN,GPIO(BUSVOODOO_12VEN_PIN));// set pin as output (open-drain pulled high to disable the pMOS)
// set DAC channel back to analog
gpio_set_mode(GPIO(BUSVOODOO_XVCTL_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_ANALOG,GPIO(BUSVOODOO_XVCTL_PIN));// set xV pin as analog
gpio_set_mode(GPIO(BUSVOODOO_12VCTL_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_ANALOG,GPIO(BUSVOODOO_12VCTL_PIN));// set 12V pin as analog
// disable embedded pull-ups
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON,0);// disable JTAG (but keep SWD) so to use the underlying GPIOs (PA15, PB3, PB4)
gpio_set(GPIO(BUSVOODOO_5VPULLUP_PORT),GPIO(BUSVOODOO_5VPULLUP_PIN));// set pin high to disable 5V embedded pull-up
gpio_set_mode(GPIO(BUSVOODOO_5VPULLUP_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_OPENDRAIN,GPIO(BUSVOODOO_5VPULLUP_PIN));// set pin as output (open-drain pulled high to disable the pMOS)
gpio_set(GPIO(BUSVOODOO_OEPULLUP_PORT),GPIO(BUSVOODOO_OEPULLUP_PIN));// set pin high to disable embedded pull-up bus switch
gpio_set_mode(GPIO(BUSVOODOO_OEPULLUP_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_OPENDRAIN,GPIO(BUSVOODOO_OEPULLUP_PIN));// set pin as output (open-drain pulled high to disable the bus switch)