29 #include <libopencm3/cm3/nvic.h> 30 #include <libopencm3/stm32/gpio.h> 31 #include <libopencm3/stm32/rcc.h> 32 #include <libopencm3/stm32/adc.h> 33 #include <libopencm3/stm32/dac.h> 34 #include <libopencm3/stm32/timer.h> 45 #define BUSVOODOO_LED_TIMER 1 49 static volatile uint32_t busvoodoo_global_led_blue_timeout = 0; 65 const char*
busvoodoo_io_names[13] = {
"I2C_SMBA/SPI_NSS/I2S_WS/UART1_CK",
"SDIO_CMD",
"UART1_CTS/SPI_SCK/I2S_CK",
"SDIO_D3/UART2_RX",
"I2C_SDA/UART1_RX",
"SDIO_D0",
"SPI_MOSI/I2S_SD",
"SDIO_CK",
"I2C_SCL/UART1_TX",
"SDIO_D1",
"I2S_MCK",
"UART1_RTS/SPI_MISO",
"SDIO_D2/UART2_TX"};
66 const uint32_t
busvoodoo_io_ports[13] = {GPIOB, GPIOD, GPIOB, GPIOC, GPIOB, GPIOC, GPIOB, GPIOC, GPIOB, GPIOC, GPIOC, GPIOB, GPIOC};
67 const uint32_t
busvoodoo_io_pins[13] = {GPIO12, GPIO2, GPIO13, GPIO11, GPIO11, GPIO8, GPIO15, GPIO12, GPIO10, GPIO9, GPIO6, GPIO14, GPIO10};
68 const uint8_t
busvoodoo_io_groups[13] = {6, 6, 4, 4, 1, 1, 5, 5, 2, 2, 3, 3, 3};
77 rcc_periph_clock_enable(RCC_GPIOA);
78 rcc_periph_clock_enable(RCC_GPIOB);
79 rcc_periph_clock_enable(RCC_GPIOC);
80 rcc_periph_clock_enable(RCC_GPIOD);
81 rcc_periph_clock_enable(RCC_AFIO);
107 rcc_periph_clock_enable(RCC_ADC1);
109 adc_disable_scan_mode(ADC1);
110 adc_disable_discontinuous_mode_regular(ADC1);
111 adc_set_single_conversion_mode(ADC1);
112 adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC);
113 adc_enable_temperature_sensor();
116 adc_reset_calibration(ADC1);
127 if (version_up && version_down) {
141 rcc_periph_clock_enable(RCC_DAC);
149 dac_set_trigger_source(DAC_CR_TSEL1_SW);
150 dac_set_trigger_source(DAC_CR_TSEL2_SW);
161 nvic_enable_irq(NVIC_TIM1_UP_IRQ);
163 gpio_set_mode(
GPIO(LED_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO(LED_PIN));
186 gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, 0);
216 #if BUSVOODOO_HARDWARE_VERSION!=0 218 gpio_set_mode(
GPIO(BUSVOODOO_CAN_TX_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO(BUSVOODOO_CAN_TX_PIN));
219 gpio_set_mode(
GPIO(BUSVOODOO_CAN_RX_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO(BUSVOODOO_CAN_RX_PIN));
220 gpio_set(
GPIO(BUSVOODOO_CAN_EN_PORT),
GPIO(BUSVOODOO_CAN_EN_PIN));
221 gpio_set_mode(
GPIO(BUSVOODOO_CAN_EN_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN,
GPIO(BUSVOODOO_CAN_EN_PIN));
234 bool to_return =
true;
237 if (voltage<4.0 || voltage>5.5) {
241 if (voltage<3.0 || voltage>3.6) {
254 uint8_t channels[1] = {ADC_CHANNEL17};
255 adc_set_regular_sequence(ADC1,
LENGTH(channels), channels);
257 adc_start_conversion_direct(ADC1);
258 while (!adc_eoc(ADC1));
259 uint16_t internal_value = adc_read_regular(ADC1);
281 adc_set_regular_sequence(ADC1,
LENGTH(channels), channels);
283 adc_start_conversion_direct(ADC1);
284 while (!adc_eoc(ADC1));
285 uint16_t desired_value = adc_read_regular(ADC1);
288 float to_return = NAN;
291 to_return = desired_value/(10.0/(10.0+10.0));
294 to_return = desired_value/(10.0/(10.0+10.0));
297 to_return = desired_value/(10.0/(10.0+10.0));
300 to_return = desired_value/(1.5/(10.0+1.5));
303 to_return = desired_value;
309 if (!isnan(to_return)) {
310 to_return *= 1.2/internal_value;
327 if (isnan(voltage)) {
358 if (isnan(voltage)) {
402 gpio_set_mode(
GPIO(LED_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO(LED_PIN));
406 gpio_set(
GPIO(LED_PORT),
GPIO(LED_PIN));
407 gpio_set_mode(
GPIO(LED_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
GPIO(LED_PIN));
410 gpio_clear(
GPIO(LED_PORT),
GPIO(LED_PIN));
411 gpio_set_mode(
GPIO(LED_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
GPIO(LED_PIN));
414 gpio_set_mode(
GPIO(LED_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
GPIO(LED_PIN));
513 if (period<0.0 || period>6.0 || duty<0.0 || duty>1.0) {
534 gpio_set_mode(
GPIO(LED_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO(LED_PIN));
547 bool power_led_on =
false;
561 bool busvoodoo_global_actions(
char* actions,
bool perform,
bool (*action_handler)(
const char* action, uint32_t repetition,
bool perform))
563 char* action_start = actions;
564 bool last_action =
false;
565 while (
'\0'!=*action_start && !last_action) {
567 char* action_end = action_start+1;
568 if (
'"'==*action_start ||
'\''==*action_start) {
569 while (
'\0'!=*action_end && *action_end!=*action_start) {
572 if (*action_end!=*action_start) {
577 while (
'\0'!=*action_end &&
':'!=*action_end &&
' '!=*action_end &&
','!=*action_end) {
582 char *separation = action_end;
583 while (
'\0'!=*separation &&
' '!=*separation &&
','!=*separation) {
586 if (
'\0'==*separation) {
592 uint32_t multiplier = 1;
593 if (separation>action_end) {
594 if (
':'==*action_end) {
595 if (separation==action_end+1) {
598 for (
char* digit=action_end+1; digit<separation; digit++) {
599 if (*digit<'0' || *digit>
'9') {
603 multiplier = strtol(action_end+1, NULL, 10);
610 if (!(*action_handler)(action_start, multiplier, perform)) {
615 action_start = separation+1;
635 }
else if (0==strcmp(
argument,
"on")) {
637 printf(
"power rails switched on\n");
639 printf(
"power rails switched on but malfunctioning\n");
643 printf(
"5V power rail: %.2fV\n", voltage);
645 printf(
"3V3 power rail: %.2fV\n", voltage);
646 }
else if (0==strcmp(
argument,
"off")) {
648 printf(
"power rails switched off\n");
650 printf(
"5V power rail: off\n");
651 printf(
"3V3 power rail: off\n");
665 printf(
"5V power rail used");
667 printf(
"adjustable voltage regulator used");
669 printf(
"external voltage input");
676 printf(
": %.2fV\n", voltage);
679 double voltage = *((
double*)
argument);
681 printf(
"LV rail switched off");
683 printf(
"LV rail set to %.2fV", voltage);
690 printf(
": %.2fV\n", voltage);
702 printf(
"function not available on BusVoodoo light");
712 printf(
"%.2fV\n", voltage);
715 double voltage = *((
double*)
argument);
716 printf(
"high voltage rail ");
720 printf(
"set to %.2fV", voltage);
727 printf(
": %.2fV\n", voltage);
739 bool no_pinout =
true;
743 bool pin_used =
false;
759 printf(
"RS/CAN connector pinout:\n");
762 for (uint8_t i=0; i<space; i++) {
781 for (uint8_t i=0; i<space; i++) {
790 bool pin_used =
false;
796 uint8_t spaces[5] = {0};
797 for (uint8_t i=0; i<
LENGTH(spaces); i++) {
814 printf(
"I/O connector pinout:\n");
817 for (uint16_t i=0; i<(uint16_t)(spaces[4]+spaces[3]+1); i++) {
820 for (uint16_t i=0; i<(uint16_t)(spaces[2]+2); i++) {
823 for (uint16_t i=0; i<(uint16_t)(spaces[1]+spaces[0]+1); i++) {
829 for (int8_t i=4; i>=0; i--) {
832 for (int16_t j=0; j<spaces[i]-1; j++) {
848 for (int8_t i=4; i>=0; i--) {
851 for (int16_t j=0; j<spaces[i]-1; j++) {
867 for (uint16_t i=0; i<spaces[4]+1+spaces[3]+1+spaces[2]+1+spaces[1]+1+spaces[0]; i++) {
876 printf(
"no pins are used\n");
884 .command_description =
"show connector pinout",
886 .argument_description = NULL,
892 .command_description =
"switch 3V3 and 5V power rails on/off, or read internal voltages",
894 .argument_description =
"[on|off]",
900 .command_description =
"set voltage on low voltage power rail (0, 0.3-4.8, 5V), or read voltage on pin",
902 .argument_description =
"[voltage]",
913 .command_description =
"set voltage on high voltage power rail (0, 3.3-24V), or read voltage on pin",
915 .argument_description =
"[voltage]",
void busvoodoo_leds_off(void)
switch off blue and red LEDs
#define BUSVOODOO_5V_CHANNEL
ADC channel to measure 3.3V rail.
float busvoodoo_hv_set(float voltage)
set voltage on high voltage adjustable voltage regulator
static void busvoodoo_global_power_led_update(void)
updates the red power LED status
#define BUSVOODOO_HVCTL_CHANNEL
DAC channel to control HV output voltage.
const struct menu_command_t busvoodoo_global_commands[]
list of supported commands for base BusVoodoo
static void busvoodoo_global_power(void *argument)
switch 3V3 and 5V power rails on/off
BusVoodoo global definitions and methods (API)
#define BUSVOODOO_HVEN_PIN
high voltage (HV) enable pin (active low)
#define BUSVOODOO_HW_VERSION_CHANNEL
ADC to identify hardware version.
static void busvoodoo_global_lv(void *argument)
set LV linear drop-out voltage regulator voltage
static volatile bool busvoodoo_global_led_blinking
if the LEDs are in a blinking pattern
void busvoodoo_led_blue_pulse(uint32_t ms)
pulse blue LED for short duration
#define BUSVOODOO_LVCTL_PORT
pin to control LV output voltage
bool busvoodoo_vout_switch(bool on)
switch 3V3 and 5V power outputs on I/O connector
#define BUSVOODOO_RS232_EN_PORT
RS-232 pin to enable receiver (active low, pulled up)
#define BUSVOODOO_HW_VERSION_PORT
pin to identify hardware version
static void busvoodoo_global_hv(void *argument)
set HV step-up voltage regulator voltage
#define BUSVOODOO_HV_SET(x)
voltage to output for the DAC to set the desired HV output voltage (based on resistor values on the H...
#define BUSVOODOO_HVCTL_PORT
pin to control HV output voltage
#define BUSVOODOO_HVEN_PORT
high voltage (HV) enable pin (active low)
#define BUSVOODOO_RS232_CTS_PORT
RS-232 Clear-To-Send input pin.
float busvoodoo_lv_set(float voltage)
set voltage on low voltage adjustable voltage regulator
#define BUSVOODOO_LVEN_PIN
low voltage (LV) enable pin (active high)
const char * busvoodoo_global_pinout_rscan[5]
RS/CAN connector pinout.
static volatile uint32_t busvoodoo_global_led_red_timeout
number of remaining milliseconds the red LED should stay on
#define BUSVOODOO_LV_SET(x)
voltage to output for the DAC to set the desired LV output voltage (based on resistor values on the L...
const uint32_t busvoodoo_io_pins[13]
pin of individual signals
#define BUSVOODOO_RS232_TX_PORT
RS-232 Transmit output pin.
global definitions and methods (API)
enum menu_argument_t argument
what kind of argument it accepts
#define GPIO(x)
get GPIO based on GPIO identifier
#define BUSVOODOO_RS485_RX_PORT
RS-485 Receive input pin.
void sleep_us(uint32_t duration)
go to sleep for some microseconds
#define BUSVOODOO_RS485_RE_PORT
RS-485 pin to enable receiver (active low, pulled up)
bool busvoodoo_full
is the BusVoodoo board fully populated (with HV voltage regulator, RS-232, RS-485, CAN transceiver on the back side)
#define RCC_TIM(x)
get RCC for timer based on TIM identifier
const uint32_t busvoodoo_io_ports[13]
port of individual signals
#define BUSVOODOO_RS485_TX_PORT
RS-485 Transmit output pin.
void busvoodoo_led_blue_off(void)
switch off blue LED
#define BUSVOODOO_OEPULLUP_PIN
bus switch output enable pin to enable embedded pull-ups (active low)
#define ADC12_IN_PORT(x)
get port based on ADC12_IN identifier
#define BUSVOODOO_RS232_CTS_PIN
RS-232 Clear-To-Send input pin.
#define BUSVOODOO_LV_CHANNEL
ADC channel to measure LV rail.
#define BUSVOODOO_RS232_TX_PIN
RS-232 Transmit output pin.
#define BUSVOODOO_RS485_DE_PORT
RS-485 pin to enable transmitter (active high, pulled low)
#define BUSVOODOO_RS232_RTS_PIN
RS-232 Request-To-Send output pin.
const uint8_t busvoodoo_io_groups[13]
which I/O pin (group) does the signal belong to
char shortcut
short command code (0 if not available)
#define ADC12_IN_PIN(x)
get pin based on ADC12_IN identifier
void busvoodoo_leds_blink(double period, double duty)
set LED blinking pattern
void busvoodoo_led_blue_on(void)
switch on blue LED
#define BUSVOODOO_HV_CHANNEL
ADC channel to measure HV rail.
const char * busvoodoo_global_pinout_io[10]
I/O connector pinout.
#define BUSVOODOO_LVCTL_PIN
pin to control LV output voltage
#define BUSVOODOO_RS232_EN_PIN
RS-232 pin to enable receiver (active low, pulled up)
float busvoodoo_vreg_get(uint8_t channel)
read voltage from power rail
const char * busvoodoo_io_names[13]
I/O individual signal names.
char busvoodoo_global_string[64]
shared string buffer, i.e.
#define BUSVOODOO_5VPULLUP_PIN
5V pull-up enable pin (active low)
const uint8_t busvoodoo_global_commands_nb
number supported commands for base BusVoodoo
#define BUSVOODOO_VOUTEN_PORT
voltage output (5V and 3.3V) enable pin (active low)
bool busvoodoo_global_actions(char *actions, bool perform, bool(*action_handler)(const char *action, uint32_t repetition, bool perform))
parse and perform actions
void sleep_ms(uint32_t duration)
go to sleep for some milliseconds
static void busvoodoo_leds_update(void)
update LED status according to LED flags
size_t printf(const char *format,...)
print format string on user output
#define BUSVOODOO_VOUTEN_PIN
voltage output (5V and 3.3V) enable pin (active low)
const uint8_t busvoodoo_global_full_commands_nb
number supported commands for BusVoodoo full only
#define BUSVOODOO_LVCTL_CHANNEL
DAC channel to control LV output voltage.
#define BUSVOODOO_HW_VERSION_PIN
pin to identify hardware version
#define BUSVOODOO_RS232_RX_PORT
RS-232 Receive input pin.
void busvoodoo_led_red_pulse(uint32_t ms)
pulse red LED for short duration
printing utilities to replace the large printf from the standard library (API)
#define BUSVOODOO_RS485_DE_PIN
RS-485 pin to enable transmitter (active high, pulled low)
void tim1_up_isr(void)
interrupt service routine called on LED timeout
static volatile bool busvoodoo_global_led_red_timer
if the timer for the red LED is enabled
#define BUSVOODOO_LED_TIMER
timer peripheral ID
#define BUSVOODOO_LVEN_PORT
low voltage (LV) enable pin (active high)
float busvoodoo_embedded_pullup(bool on)
enable embedded pull-up resistors
void busvoodoo_led_red_off(void)
switch off red LED
#define BUSVOODOO_RS232_RTS_PORT
RS-232 Request-To-Send output pin.
static volatile bool busvoodoo_global_led_blue_timer
if the timer for the blue LED is enabled
static void busvoodoo_global_pinout(void *argument)
display I/O and RS/CAN connector pinouts
#define LENGTH(x)
get the length of an array
#define BUSVOODOO_RS485_RE_PIN
RS-485 pin to enable receiver (active low, pulled up)
#define ADC_CHANNEL(x)
get channel based on ADC12_IN identifier
#define BUSVOODOO_OEPULLUP_PORT
bus switch output enable pin to enable embedded pull-ups (active low)
#define BUSVOODOO_5VPULLUP_PORT
5V pull-up enable pin (active low)
void busvoodoo_led_red_on(void)
switch on red LED
#define BUSVOODOO_RS232_RX_PIN
RS-232 Receive input pin.
#define TIM(x)
get TIM based on TIM identifier
#define BUSVOODOO_RS485_RX_PIN
RS-485 Receive input pin.
const struct menu_command_t busvoodoo_global_full_commands[]
list of supported commands for BusVoodoo full only
static const float busvoodoo_version_voltages[]
hardware version voltages, calculated from divider ratios, starting with version A ...
#define BUSVOODOO_RS485_TX_PIN
RS-485 Transmit output pin.
static void busvoodoo_led_pulse_setup(void)
setup the timer for pulsing LEDs
void busvoodoo_safe_state(void)
set safe state by disabling all outputs
char busvoodoo_version
version of the hardware board
void busvoodoo_setup(void)
setup BusVoodoo board
static volatile uint32_t busvoodoo_global_led_blue_timeout
number of remaining milliseconds the blue LED should stay on
#define BUSVOODOO_RS232_SHDN_PORT
RS-232 pin to enable transmitter (active high, pulled low)
#define BUSVOODOO_3V3_CHANNEL
ADC channel to measure 5V rail.
#define BUSVOODOO_RS232_SHDN_PIN
RS-232 pin to enable transmitter (active high, pulled low)
#define BUSVOODOO_HVCTL_PIN
pin to control HV output voltage
#define RCC_ADC12_IN(x)
get RCC based on ADC12_IN identifier