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 5 49 static volatile bool busvoodoo_global_led_blue = false; 59 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"};
60 const uint32_t
busvoodoo_io_ports[13] = {GPIOB, GPIOD, GPIOB, GPIOC, GPIOB, GPIOC, GPIOB, GPIOC, GPIOB, GPIOC, GPIOC, GPIOB, GPIOC};
61 const uint32_t
busvoodoo_io_pins[13] = {GPIO12, GPIO2, GPIO13, GPIO11, GPIO11, GPIO8, GPIO15, GPIO12, GPIO10, GPIO9, GPIO6, GPIO14, GPIO10};
62 const uint8_t
busvoodoo_io_groups[13] = {6, 6, 4, 4, 1, 1, 5, 5, 2, 2, 3, 3, 3};
71 rcc_periph_clock_enable(RCC_GPIOA);
72 rcc_periph_clock_enable(RCC_GPIOB);
73 rcc_periph_clock_enable(RCC_GPIOC);
74 rcc_periph_clock_enable(RCC_GPIOD);
75 rcc_periph_clock_enable(RCC_AFIO);
101 rcc_periph_clock_enable(RCC_ADC1);
103 adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC);
104 adc_enable_temperature_sensor(ADC1);
105 adc_enable_external_trigger_regular(ADC1, ADC_CR2_EXTSEL_SWSTART);
106 adc_set_single_conversion_mode(ADC1);
109 adc_reset_calibration(ADC1);
110 adc_calibration(ADC1);
120 if (version_up && version_down) {
134 rcc_periph_clock_enable(RCC_DAC);
142 dac_set_trigger_source(DAC_CR_TSEL1_SW);
143 dac_set_trigger_source(DAC_CR_TSEL2_SW);
169 gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, 0);
215 bool to_return =
true;
218 if (voltage<4.0 || voltage>5.5) {
222 if (voltage<3.0 || voltage>3.6) {
234 uint8_t channels[2] = {ADC_CHANNEL17, ADC_CHANNEL17};
254 adc_set_regular_sequence(ADC1,
LENGTH(channels), channels);
255 adc_enable_discontinuous_mode_regular(ADC1,
LENGTH(channels));
256 uint16_t values[
LENGTH(channels)] = {0};
258 adc_start_conversion_regular(ADC1);
259 for (uint8_t channel_i=0; channel_i<
LENGTH(channels); channel_i++) {
260 while (!adc_eoc(ADC1));
261 values[channel_i] = adc_read_regular(ADC1);
263 float to_return = NAN;
266 to_return = values[1]/(10.0/(10.0+10.0));
269 to_return = values[1]/(10.0/(10.0+10.0));
272 to_return = values[1]/(10.0/(10.0+10.0));
275 to_return = values[1]/(1.5/(10.0+1.5));
278 to_return = values[1];
284 if (!isnan(to_return)) {
285 to_return *= 1.2/values[0];
302 if (isnan(voltage)) {
333 if (isnan(voltage)) {
362 led_blink(0.01, 0.5);
375 if (ms>UINT16_MAX/2) {
394 if (ms>UINT16_MAX/2) {
410 bool busvoodoo_global_actions(
char* actions,
bool perform,
bool (*action_handler)(
const char* action, uint32_t repetition,
bool perform))
412 char* action_start = actions;
413 bool last_action =
false;
414 while (
'\0'!=*action_start && !last_action) {
416 char* action_end = action_start+1;
417 if (
'"'==*action_start ||
'\''==*action_start) {
418 while (
'\0'!=*action_end && *action_end!=*action_start) {
421 if (*action_end!=*action_start) {
426 while (
'\0'!=*action_end &&
':'!=*action_end &&
' '!=*action_end &&
','!=*action_end) {
431 char *separation = action_end;
432 while (
'\0'!=*separation &&
' '!=*separation &&
','!=*separation) {
435 if (
'\0'==*separation) {
441 uint32_t multiplier = 1;
442 if (separation>action_end) {
443 if (
':'==*action_end) {
444 if (separation==action_end+1) {
447 for (
char* digit=action_end+1; digit<separation; digit++) {
448 if (*digit<'0' || *digit>
'9') {
452 multiplier = strtol(action_end+1, NULL, 10);
459 if (!(*action_handler)(action_start, multiplier, perform)) {
464 action_start = separation+1;
484 }
else if (0==strcmp(
argument,
"on")) {
486 printf(
"power rails switched on\n");
488 printf(
"power rails switched on but malfunctioning\n");
492 printf(
"5V power rail: %.2fV\n", voltage);
494 printf(
"3V3 power rail: %.2fV\n", voltage);
495 }
else if (0==strcmp(
argument,
"off")) {
497 printf(
"power rails switched off\n");
499 printf(
"5V power rail: off\n");
500 printf(
"3V3 power rail: off\n");
513 printf(
"5V power rail used");
515 printf(
"adjustable voltage regulator used");
517 printf(
"external voltage input");
524 printf(
": %.2fV\n", voltage);
527 double voltage = *((
double*)
argument);
529 printf(
"LV rail switched off");
531 printf(
"LV rail set to %.2fV", voltage);
538 printf(
": %.2fV\n", voltage);
549 printf(
"function not available on BusVoodoo light");
559 printf(
"%.2fV\n", voltage);
562 double voltage = *((
double*)
argument);
563 printf(
"high voltage rail ");
567 printf(
"set to %.2fV", voltage);
574 printf(
": %.2fV\n", voltage);
585 bool no_pinout =
true;
589 bool pin_used =
false;
605 printf(
"RS/CAN connector pinout:\n");
608 for (uint8_t i=0; i<space; i++) {
627 for (uint8_t i=0; i<space; i++) {
636 bool pin_used =
false;
642 uint8_t spaces[5] = {0};
643 for (uint8_t i=0; i<
LENGTH(spaces); i++) {
660 printf(
"I/O connector pinout:\n");
663 for (uint16_t i=0; i<(uint16_t)(spaces[4]+spaces[3]+1); i++) {
666 for (uint16_t i=0; i<(uint16_t)(spaces[2]+2); i++) {
669 for (uint16_t i=0; i<(uint16_t)(spaces[1]+spaces[0]+1); i++) {
675 for (int8_t i=4; i>=0; i--) {
678 for (int16_t j=0; j<spaces[i]-1; j++) {
694 for (int8_t i=4; i>=0; i--) {
697 for (int16_t j=0; j<spaces[i]-1; j++) {
713 for (uint16_t i=0; i<spaces[4]+1+spaces[3]+1+spaces[2]+1+spaces[1]+1+spaces[0]; i++) {
722 printf(
"no pins are used\n");
731 "switch 3V3 and 5V power rails on/off",
739 "set voltage on low voltage power rail (0, 0.3-4.8, 5V)",
747 "set voltage on high voltage power rail (0, 3.3-24V)",
755 "show connector pinout",
#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
#define BUSVOODOO_HVCTL_CHANNEL
DAC channel to control HV output voltage.
#define TIM_ISR(x)
get interrupt service routine for timer base on TIM identifier
const struct menu_command_t busvoodoo_global_commands[]
list of supported commands
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
void busvoodoo_led_red_pulse(uint16_t ms)
pulse red 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
void led_off(void)
switch off board LED
static void busvoodoo_global_hv(void *argument)
set HV step-up voltage regulator voltage
#define NVIC_TIM_IRQ(x)
get NVIC IRQ for timer base on TIM identifier
#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.
#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 busvoodoo_led_blue_pulse(uint16_t ms)
pulse blue LED for short duration
void sleep_us(uint32_t duration)
go to sleep for some microseconds
#define BUSVOODOO_CAN_EN_PORT
signal to power CAN transceiver (active low, pulled high)
#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
static volatile bool busvoodoo_global_led_blue
blue LED status
#define BUSVOODOO_RS485_TX_PORT
RS-485 Transmit output pin.
#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
#define BUSVOODOO_CAN_RX_PIN
CAN Receive input pin.
#define ADC12_IN_PIN(x)
get pin based on ADC12_IN identifier
#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
#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
#define BUSVOODOO_CAN_TX_PIN
CAN Transmit output pin.
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)
#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.
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)
#define BUSVOODOO_LED_TIMER
timer peripheral
#define BUSVOODOO_LVEN_PORT
low voltage (LV) enable pin (active high)
float busvoodoo_embedded_pullup(bool on)
enable embedded pull-up resistors
static void busvoodoo_led_update(void)
update LED status according to LED flags
#define BUSVOODOO_RS232_RTS_PORT
RS-232 Request-To-Send output pin.
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_CAN_RX_PORT
CAN Receive input pin.
#define BUSVOODOO_OEPULLUP_PORT
bus switch output enable pin to enable embedded pull-ups (active low)
static volatile bool busvoodoo_global_led_red
red LED status
#define BUSVOODOO_5VPULLUP_PORT
5V pull-up enable pin (active low)
#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.
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.
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
#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
#define BUSVOODOO_CAN_TX_PORT
CAN Transmit output pin.
#define BUSVOODOO_CAN_EN_PIN
signal to power CAN transceiver (active low, pulled high)