printf("signal %s of I/O-%u is low while it should be set high by signal %s of I/O-%u\n",busvoodoo_io_names[pin2],busvoodoo_io_groups[pin2],busvoodoo_io_names[pin1],busvoodoo_io_groups[pin1]);// warn user about the error
printf("signal %s of I/O-%u is high while it should not be set high by signal %s of I/O-%u\n",busvoodoo_io_names[pin2],busvoodoo_io_groups[pin2],busvoodoo_io_names[pin1],busvoodoo_io_groups[pin1]);// warn user about the error
gotoerror;
}
}
gpio_set_mode(busvoodoo_io_ports[pin1],GPIO_MODE_INPUT,GPIO_CNF_INPUT_PULL_UPDOWN,busvoodoo_io_pins[pin1]);// set pin back to input
gpio_clear(busvoodoo_io_ports[pin1],busvoodoo_io_pins[pin1]);// pull pin back down
}
// set individual pin low and ensure only pins in the same group are at the same level
printf("signal %s of I/O-%u is high while it should be set low by signal %s of I/O-%u\n",busvoodoo_io_names[pin2],busvoodoo_io_groups[pin2],busvoodoo_io_names[pin1],busvoodoo_io_groups[pin1]);// warn user about the error
printf("signal %s of I/O-%u is low while it should not be set low by signal %s of I/O-%u\n",busvoodoo_io_names[pin2],busvoodoo_io_groups[pin2],busvoodoo_io_names[pin1],busvoodoo_io_groups[pin1]);// warn user about the error
gotoerror;
}
}
gpio_set_mode(busvoodoo_io_ports[pin1],GPIO_MODE_INPUT,GPIO_CNF_INPUT_PULL_UPDOWN,busvoodoo_io_pins[pin1]);// set pin back to input
gpio_set(busvoodoo_io_ports[pin1],busvoodoo_io_pins[pin1]);// pull pin back up
gpio_set_mode(GPIO(BUSVOODOO_RS485_TX_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,GPIO(BUSVOODOO_RS485_TX_PIN));// set TX as output
gpio_set_mode(GPIO(BUSVOODOO_RS485_RX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_PULL_UPDOWN,GPIO(BUSVOODOO_RS485_RX_PIN));// set RX as input with pull up/down
// test low signal
gpio_set(GPIO(BUSVOODOO_RS485_RX_PORT),GPIO(BUSVOODOO_RS485_RX_PIN));// pull RX up
gpio_clear(GPIO(BUSVOODOO_RS485_TX_PORT),GPIO(BUSVOODOO_RS485_TX_PIN));// set TX low
sleep_us(100);// let voltage settle
if(gpio_get(GPIO(BUSVOODOO_RS485_RX_PORT),GPIO(BUSVOODOO_RS485_RX_PIN))){// test if RX is still high
printf("RS-485 RX is high while TX is set low\n");// warn user about the error
gotoerror;
}
// test high signal
gpio_clear(GPIO(BUSVOODOO_RS485_RX_PORT),GPIO(BUSVOODOO_RS485_RX_PIN));// pull RX down
gpio_set(GPIO(BUSVOODOO_RS485_TX_PORT),GPIO(BUSVOODOO_RS485_TX_PIN));// set TX high
sleep_us(100);// let voltage settle
if(0==gpio_get(GPIO(BUSVOODOO_RS485_RX_PORT),GPIO(BUSVOODOO_RS485_RX_PIN))){// test if RX is still low
printf("RS-485 RX is low while TX is set high\n");// warn user about the error
gotoerror;
}
// release transceiver
gpio_set(GPIO(BUSVOODOO_RS485_RE_PORT),GPIO(BUSVOODOO_RS485_RE_PIN));// set high to disable receiver
gpio_clear(GPIO(BUSVOODOO_RS485_DE_PORT),GPIO(BUSVOODOO_RS485_DE_PIN));// set low to disable transmitter
gpio_set_mode(GPIO(BUSVOODOO_RS485_TX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT,GPIO(BUSVOODOO_RS485_TX_PIN));// set pin to floating
gpio_set_mode(GPIO(BUSVOODOO_RS485_RX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT,GPIO(BUSVOODOO_RS485_RX_PIN));// set pin to floating
}
#if BUSVOODOO_HARDWARE_VERSION!=0
// test CAN transceiver
if(busvoodoo_full){
// configure transceiver
gpio_clear(GPIO(BUSVOODOO_CAN_EN_PORT),GPIO(BUSVOODOO_CAN_EN_PIN));// pull low to power transceiver
gpio_set_mode(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_OPENDRAIN,GPIO(BUSVOODOO_CAN_TX_PIN));// set TX as output (there is a pull-up resistor to 5V)
gpio_set_mode(GPIO(BUSVOODOO_CAN_RX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_PULL_UPDOWN,GPIO(BUSVOODOO_CAN_RX_PIN));// set RX as input with pull up/down
// test high signal
gpio_clear(GPIO(BUSVOODOO_CAN_RX_PORT),GPIO(BUSVOODOO_CAN_RX_PIN));// pull RX down
gpio_set(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO(BUSVOODOO_CAN_TX_PIN));// set TX high
sleep_us(100);// let voltage settle
if(0==gpio_get(GPIO(BUSVOODOO_CAN_RX_PORT),GPIO(BUSVOODOO_CAN_RX_PIN))){// test if RX is still low
printf("CAN RX is low while TX is set high\n");// warn user about the error
gotoerror;
}
// test low signal
gpio_set(GPIO(BUSVOODOO_CAN_RX_PORT),GPIO(BUSVOODOO_CAN_RX_PIN));// pull RX up
gpio_clear(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO(BUSVOODOO_CAN_TX_PIN));// set TX low
sleep_us(100);// let voltage settle
if(gpio_get(GPIO(BUSVOODOO_CAN_RX_PORT),GPIO(BUSVOODOO_CAN_RX_PIN))){// test if RX is still high
printf("CAN RX is high while TX is set low\n");// warn user about the error
gotoerror;
}
// test dominant timeout
sleep_ms(10);// after 5 ms the output should be switched back from dominant to recessive respite TX being low
if(!gpio_get(GPIO(BUSVOODOO_CAN_RX_PORT),GPIO(BUSVOODOO_CAN_RX_PIN))){// test if RX is now low
printf("CAN RX is low while the output should be back to recessive\n");// warn user about the error
gotoerror;
}
// release transceiver
gpio_set(GPIO(BUSVOODOO_CAN_EN_PORT),GPIO(BUSVOODOO_CAN_EN_PIN));// set high to power off transceiver
gpio_set_mode(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT,GPIO(BUSVOODOO_CAN_TX_PIN));// set pin to floating
gpio_set_mode(GPIO(BUSVOODOO_CAN_RX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT,GPIO(BUSVOODOO_CAN_RX_PIN));// set pin to floating
// test GND on pin 1 by shorting LV_CTL to ground (through 40k resistor) and measure short
gpio_set(GPIO(BUSVOODOO_LVCTL_PORT),GPIO(BUSVOODOO_LVCTL_PIN));// set pin high
gpio_set_mode(GPIO(BUSVOODOO_LVCTL_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,GPIO(BUSVOODOO_LVCTL_PIN));// set LV control pin as output
printf("%sI/O pin 1\n",lv_to);// ask user for action
busvoodoo_leds_off();// clear LEDs
busvoodoo_led_red_on();// notify user to perform action
pinout[0]="O";// set target testing pin
busvoodoo_oled_text_pinout((constchar**)pinout,true);// display pins to user
busvoodoo_oled_update();// update screen
do{
sleep_ms(100);// wait for user to make connection
}while(busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL)>0.2&&!user_input_available);// wait until pin is shorted to ground
busvoodoo_led_red_off();// clear red LED
busvoodoo_led_blue_on();// notify user test is running
if(user_input_available){// user interruption
gotoerror;
}
gpio_clear(GPIO(BUSVOODOO_LVCTL_PORT),GPIO(BUSVOODOO_LVCTL_PIN));// set pin low
gpio_set_mode(GPIO(BUSVOODOO_LVCTL_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,GPIO(BUSVOODOO_LVCTL_PIN));// set LV control pin as output
sleep_ms(100);// wait for voltage to settle an debounce
if(busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL)>0.2){
printf("I/O pin 4 is high while it should be low and shorted to ground\n");
gotoerror;
}
gpio_set_mode(GPIO(BUSVOODOO_LVCTL_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_ANALOG,GPIO(BUSVOODOO_LVCTL_PIN));// set LV control pin back to analog input for DAC
}while((busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL)<0.2||busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL)>3.5)&&!user_input_available);// wait until pin is connected
sleep_ms(100);// wait for stable connection
}while((busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL)<0.2||busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL)>3.5)&&!user_input_available);// check to be sure it really is not on the 5V pin
busvoodoo_led_red_on();// clear red LED
busvoodoo_led_blue_on();// notify user test is running
for(uint8_tpin=0;pin<LENGTH(busvoodoo_io_ports)&&pin<LENGTH(busvoodoo_io_pins)&&pin<LENGTH(busvoodoo_io_groups);pin++){// look for a pin mapped on this I/O
if(busvoodoo_io_groups[pin]==io){
gpio_set(busvoodoo_io_ports[pin],busvoodoo_io_pins[pin]);// set pin high
gpio_set_mode(busvoodoo_io_ports[pin],GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,busvoodoo_io_pins[pin]);// set pin to output
printf("%sI/O pin %u\n",lv_to,io+4);
busvoodoo_leds_off();// clear LEDs
busvoodoo_led_red_on();// notify user to perform action
gpio_clear(GPIO(BUSVOODOO_CAN_EN_PORT),GPIO(BUSVOODOO_CAN_EN_PIN));// pull low to power transceiver
gpio_set_mode(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_OPENDRAIN,GPIO(BUSVOODOO_CAN_TX_PIN));// set TX as output (there is a pull-up resistor to 5V)
// test recessive output
gpio_set(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO(BUSVOODOO_CAN_TX_PIN));// set TX high
sleep_us(100);// let voltage settle
voltage=busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL);// get output voltage
if(voltage<0.4){// normally the lower limit is 2V, put pin 4 pulls it down because it is not strongly driven
printf("CAN L output is low while it should be at recessive 2.5V\n");
gotoerror;
}
if(voltage>3.0){// normally the upper limit is 3V
printf("CAN L output is high while it should be at recessive 2.5V\n");
gotoerror;
}
// test dominant output
gpio_clear(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO(BUSVOODOO_CAN_TX_PIN));// set TX low
sleep_us(100);// let voltage settle
voltage=busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL);// get output voltage
if(voltage>2.5){
printf("CAN L output is high while it should at dominant <2.25V\n");
gotoerror;
}
// release transceiver
gpio_set(GPIO(BUSVOODOO_CAN_EN_PORT),GPIO(BUSVOODOO_CAN_EN_PIN));// set high to power off transceiver
gpio_set_mode(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT,GPIO(BUSVOODOO_CAN_TX_PIN));// set pin to floating
gpio_clear(GPIO(BUSVOODOO_CAN_EN_PORT),GPIO(BUSVOODOO_CAN_EN_PIN));// pull low to power transceiver
gpio_set_mode(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_OPENDRAIN,GPIO(BUSVOODOO_CAN_TX_PIN));// set TX as output (there is a pull-up resistor to 5V)
// test recessive output
gpio_set(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO(BUSVOODOO_CAN_TX_PIN));// set TX high
sleep_us(100);// let voltage settle
voltage=busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL);// get output voltage
if(voltage<0.5){// normally the lower limit is 2V, put pin 4 pulls it down because it is not strongly driven
printf("CAN H output is low while it should be at recessive 2.5V\n");
gotoerror;
}
if(voltage>3.0){// normally the upper limit is 3V
printf("CAN H output is high while it should be at recessive 2.5V\n");
gotoerror;
}
// test dominant output
gpio_clear(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO(BUSVOODOO_CAN_TX_PIN));// set TX low
sleep_us(100);// let voltage settle
voltage=busvoodoo_vreg_get(BUSVOODOO_LV_CHANNEL);// get output voltage
if(voltage<2.5){
printf("CAN H output is low while it dominant >2.75V\n");
printf("%.02f\n",voltage);
gotoerror;
}
// release transceiver
gpio_set(GPIO(BUSVOODOO_CAN_EN_PORT),GPIO(BUSVOODOO_CAN_EN_PIN));// set high to power off transceiver
gpio_set_mode(GPIO(BUSVOODOO_CAN_TX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT,GPIO(BUSVOODOO_CAN_TX_PIN));// set pin to floating
rcc_periph_clock_enable(RCC_GPIO(BUSVOODOO_RS232_EN_PORT));// enable clock for GPIO domain
gpio_clear(GPIO(BUSVOODOO_RS232_EN_PORT),GPIO(BUSVOODOO_RS232_EN_PIN));// set low to enable receiver
gpio_set_mode(GPIO(BUSVOODOO_RS232_EN_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_OPENDRAIN,GPIO(BUSVOODOO_RS232_EN_PIN));// set pin as output (open-drain pulled high to disable receiver)
rcc_periph_clock_enable(RCC_GPIO(BUSVOODOO_RS232_SHDN_PORT));// enable clock for GPIO domain
gpio_set(GPIO(BUSVOODOO_RS232_SHDN_PORT),GPIO(BUSVOODOO_RS232_SHDN_PIN));// set high to enable transmitter
gpio_set_mode(GPIO(BUSVOODOO_RS232_SHDN_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,GPIO(BUSVOODOO_RS232_SHDN_PIN));// set pin as output (push-pull pulled low to disable transmitter)
rcc_periph_clock_enable(RCC_GPIO(BUSVOODOO_RS232_TX_PORT));// enable clock for GPIO
gpio_set_mode(GPIO(BUSVOODOO_RS232_TX_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,GPIO(BUSVOODOO_RS232_TX_PIN));// set pin as output (push-pull)
rcc_periph_clock_enable(RCC_GPIO(BUSVOODOO_RS232_RX_PORT));// enable clock for GPIO
gpio_set_mode(GPIO(BUSVOODOO_RS232_RX_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_PULL_UPDOWN,GPIO(BUSVOODOO_RS232_RX_PIN));// set pin as input (with pull resistors)
// start by setting low since unconnected (pulled to ground by 3 kO) is considered as high
gpio_clear(GPIO(BUSVOODOO_RS232_TX_PORT),GPIO(BUSVOODOO_RS232_TX_PIN));// set low
gpio_set(GPIO(BUSVOODOO_RS232_RX_PORT),GPIO(BUSVOODOO_RS232_RX_PIN));// pull high to avoid false negative
sleep_ms(5);
printf("connect RS/CAN pin 2 to RS/CAN pin 3\n");
busvoodoo_leds_off();// clear LEDs
busvoodoo_led_red_on();// notify user to perform action
pinout[2]="O";// set target testing pin
pinout[4]="O";// set target testing pin
busvoodoo_oled_text_pinout((constchar**)pinout,false);// display pins to user
busvoodoo_oled_update();// update screen
do{
sleep_ms(100);// wait for user to make connection
}while(gpio_get(GPIO(BUSVOODOO_RS232_RX_PORT),GPIO(BUSVOODOO_RS232_RX_PIN))&&!user_input_available);// wait until pin is connected
busvoodoo_led_red_off();// clear red LED
busvoodoo_led_blue_on();// notify user test is running
if(user_input_available){// user interruption
gotoerror;
}
gpio_set(GPIO(BUSVOODOO_RS232_TX_PORT),GPIO(BUSVOODOO_RS232_TX_PIN));// set high
gpio_clear(GPIO(BUSVOODOO_RS232_RX_PORT),GPIO(BUSVOODOO_RS232_RX_PIN));// pull low to avoid false negative
sleep_ms(100);// wait for voltage to settle and debounce
if(!gpio_get(GPIO(BUSVOODOO_RS232_RX_PORT),GPIO(BUSVOODOO_RS232_RX_PIN))){// check if RX is set low by TX
printf("RS-232 RX is high while it should be set low by RS-232 TX\n");
rcc_periph_clock_enable(RCC_GPIO(BUSVOODOO_RS232_RTS_PORT));// enable clock for GPIO
gpio_set_mode(GPIO(BUSVOODOO_RS232_RTS_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,GPIO(BUSVOODOO_RS232_RTS_PIN));// set pin as output (push-pull)
rcc_periph_clock_enable(RCC_GPIO(BUSVOODOO_RS232_CTS_PORT));// enable clock for GPIO
gpio_set_mode(GPIO(BUSVOODOO_RS232_CTS_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_PULL_UPDOWN,GPIO(BUSVOODOO_RS232_CTS_PIN));// set pin as input (with pull resistors)
// start by setting low since unconnected (pulled to ground by 3 kO) is considered as high
gpio_clear(GPIO(BUSVOODOO_RS232_RTS_PORT),GPIO(BUSVOODOO_RS232_RTS_PIN));// set low
gpio_set(GPIO(BUSVOODOO_RS232_CTS_PORT),GPIO(BUSVOODOO_RS232_CTS_PIN));// pull high to avoid false negative
printf("connect RS/CAN pin 4 to RS/CAN pin 5\n");
busvoodoo_leds_off();// clear LEDs
busvoodoo_led_red_on();// notify user to perform action
pinout[6]="O";// set target testing pin
pinout[8]="O";// set target testing pin
busvoodoo_oled_text_pinout((constchar**)pinout,false);// display pins to user
busvoodoo_oled_update();// update screen
do{
sleep_ms(100);// wait for user to make connection
}while(gpio_get(GPIO(BUSVOODOO_RS232_CTS_PORT),GPIO(BUSVOODOO_RS232_CTS_PIN))&&!user_input_available);// wait until pin is connected
busvoodoo_led_red_off();// clear red LED
busvoodoo_led_blue_on();// notify user test is running
if(user_input_available){// user interruption
gotoerror;
}
gpio_set(GPIO(BUSVOODOO_RS232_RTS_PORT),GPIO(BUSVOODOO_RS232_RTS_PIN));// set high
gpio_clear(GPIO(BUSVOODOO_RS232_CTS_PORT),GPIO(BUSVOODOO_RS232_CTS_PIN));// pull low to avoid false negative
sleep_ms(100);// wait for voltage to settle an debounce
if(!gpio_get(GPIO(BUSVOODOO_RS232_CTS_PORT),GPIO(BUSVOODOO_RS232_CTS_PIN))){// check if CTS is set high by RTS
printf("RS-232 CTS is high while it should be set low by RS-232 RTS\n");