2016-01-17 14:54:54 +01:00
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*
*/
2017-12-12 13:56:28 +01:00
/** STM32F1 BusVoodoo application
2017-08-02 13:46:20 +02:00
* @ file application . c
2016-08-14 21:02:38 +02:00
* @ author King Kévin < kingkevin @ cuvoodoo . info >
2017-04-19 16:24:07 +02:00
* @ date 2016 - 2017
2016-08-14 21:02:38 +02:00
*/
2016-01-17 14:54:54 +01:00
/* standard libraries */
# include <stdint.h> // standard integer types
# include <stdlib.h> // standard utilities
2016-08-14 21:02:38 +02:00
# include <string.h> // string utilities
2017-12-12 13:56:28 +01:00
# include <math.h> // math utilities
2016-01-17 14:54:54 +01:00
/* STM32 (including CM3) libraries */
2016-01-18 16:23:35 +01:00
# include <libopencmsis/core_cm3.h> // Cortex M3 utilities
2016-10-23 17:42:27 +02:00
# include <libopencm3/cm3/scb.h> // vector table definition
2016-01-29 11:25:30 +01:00
# include <libopencm3/cm3/nvic.h> // interrupt utilities
2016-10-23 17:42:27 +02:00
# include <libopencm3/stm32/gpio.h> // general purpose input output library
# include <libopencm3/stm32/rcc.h> // real-time control clock library
2016-01-29 11:25:30 +01:00
# include <libopencm3/stm32/exti.h> // external interrupt utilities
2016-10-23 17:42:27 +02:00
# include <libopencm3/stm32/iwdg.h> // independent watchdog utilities
# include <libopencm3/stm32/dbgmcu.h> // debug utilities
# include <libopencm3/stm32/flash.h> // flash utilities
2017-12-12 13:56:28 +01:00
# include <libopencm3/stm32/desig.h> // design utilities
# include <libopencm3/stm32/adc.h> // ADC utilities
# include <libopencm3/stm32/dac.h> // DAC utilities
2016-01-17 14:54:54 +01:00
/* own libraries */
2016-01-28 21:21:50 +01:00
# include "global.h" // board definitions
2017-04-03 13:32:45 +02:00
# include "print.h" // printing utilities
2017-12-16 13:37:35 +01:00
# include "uart.h" // USART utilities
2016-01-18 16:23:35 +01:00
# include "usb_cdcacm.h" // USB CDC ACM utilities
2018-01-14 13:49:16 +01:00
# include "terminal.h" // handle the terminal interface
2016-01-17 14:54:54 +01:00
2017-12-15 19:10:56 +01:00
//#include "rs485.h" // RS-485 utilities
//#include "rs232.h" // RS-232 utilities
//#include "i2c_master.h" // I2C utilities
2017-12-12 13:56:28 +01:00
2016-10-23 17:42:27 +02:00
# define WATCHDOG_PERIOD 10000 /**< watchdog period in ms */
2017-12-12 13:56:28 +01:00
/** @defgroup busvoodoo_peripherals peripheral pin definitions
* @ {
*/
2017-12-15 19:10:56 +01:00
# define BUSVOODOO_5VPULLUP_PORT B /**< 5V pull-up enable pin (active low) */
# define BUSVOODOO_5VPULLUP_PIN 4 /**< 5V pull-up enable pin (active low) */
# define BUSVOODOO_OEPULLUP_PORT A /**< bus switch output enable pin to enable embedded pull-ups (active low) */
# define BUSVOODOO_OEPULLUP_PIN 15 /**< bus switch output enable pin to enable embedded pull-ups (active low) */
2017-12-12 13:56:28 +01:00
# define BUSVOODOO_XVEN_PORT A /**< xV enable pin (active high) */
# define BUSVOODOO_XVEN_PIN 6 /**< xV enable pin (active high) */
2017-12-15 19:10:56 +01:00
# define BUSVOODOO_12VEN_PORT A /**< 12V enable pin (active low) */
# define BUSVOODOO_12VEN_PIN 7 /**< 12V enable pin (active low) */
2017-12-12 13:56:28 +01:00
# define BUSVOODOO_VOUTEN_PORT B /**< voltage output (5V and 3.3V) enable pin (active low) */
2017-12-15 19:10:56 +01:00
# define BUSVOODOO_VOUTEN_PIN 3 /**< voltage output (5V and 3.3V) enable pin (active low) */
2017-12-12 13:56:28 +01:00
/** @} */
2017-12-22 17:25:05 +01:00
/** @defgroup busvoodoo_adc ADC inputs to measure voltages from voltage regulators
2016-08-14 21:02:38 +02:00
* @ {
*/
2017-12-12 13:56:28 +01:00
# define BUSVOODOO_3V3_CHANNEL 12 /**< ADC channel to measure 5V rail */
2017-12-15 19:10:56 +01:00
# define BUSVOODOO_5V_CHANNEL 9 /**< ADC channel to measure 3.3V rail */
2017-12-12 13:56:28 +01:00
# define BUSVOODOO_XV_CHANNEL 11 /**< ADC channel to measure xV rail */
2017-12-15 19:10:56 +01:00
# define BUSVOODOO_12V_CHANNEL 15 /**< ADC channel to measure 12V rail */
2016-08-14 21:02:38 +02:00
/** @} */
2017-12-22 17:25:05 +01:00
/** @defgroup busvoodoo_dac DAC output to set voltages of voltage regulators
* @ {
*/
# define BUSVOODOO_XVCTL_PORT A /**< pin to control xV output voltage */
# define BUSVOODOO_XVCTL_PIN 4 /**< pin to control xV output voltage */
# define BUSVOODOO_XVCTL_CHANNEL CHANNEL_1 /**< DAC channel to control xV output voltage */
2017-12-15 19:10:56 +01:00
# define BUSVOODOO_XV_DEFAULT (0.8*(1+30.0 / 10.0)) /**< default (when not driven) xV voltage regulator output voltage based on R1 and R2 */
2017-12-12 13:56:28 +01:00
# define BUSVOODOO_XV_TEST 2.5 /**< target xV output voltage to test if we can set control the xV voltage regulator */
2017-12-15 19:10:56 +01:00
# define BUSVOODOO_XV_SET(x) ((0.8*(1+30.0 / 10.0)-x)*(10.0 / 30.0)+0.8) /**< voltage to output for the DAC to set the desired xV output voltage (based on resistor values on the xV adjust pins and xV voltage reference) */
2017-12-22 17:25:05 +01:00
# define BUSVOODOO_12VCTL_PORT A /**< pin to control 12V output voltage */
# define BUSVOODOO_12VCTL_PIN 5 /**< pin to control 12V output voltage */
# define BUSVOODOO_12VCTL_CHANNEL CHANNEL_2 /**< DAC channel to control 12V output voltage */
2017-12-12 13:56:28 +01:00
# define BUSVOODOO_12V_DEFAULT (1.25*(1+100.0 / 10.0)) /**< default (when not driven) 12V voltage regulator output voltage based on R1 and R2 */
# define BUSVOODOO_12V_TEST 12.0 /**< target 12V output voltage to test if we can set control the 12V voltage regulator */
# define BUSVOODOO_12V_SET(x) ((1.25*(1+100.0 / 10.0)-x)*(10.0 / 100.0)+1.25) / **< voltage to output for the DAC to set the desired
12 V output voltage ( based on resistor values on the 12 V adjust pins and 12 V voltage reference ) */
2017-12-22 17:25:05 +01:00
/** @} */
/** @defgroup busvoodoo_rs232 RS-232 transceiver connection definition
* @ {
*/
# define BUSVOODOO_RS232_EN_PORT B /**< RS-232 pin to enable receiver (active low, pulled up) */
# define BUSVOODOO_RS232_EN_PIN 5 /**< RS-232 pin to enable receiver (active low, pulled up) */
# define BUSVOODOO_RS232_SHDN_PORT C /**< RS-232 pin to enable transmitter (active high, pulled low) */
# define BUSVOODOO_RS232_SHDN_PIN 15 /**< RS-232 pin to enable transmitter (active high, pulled low) */
# define BUSVOODOO_RS232_RTS_PORT A /**< RS-232 Request-To-Send output pin */
# define BUSVOODOO_RS232_RTS_PIN 1 /**< RS-232 Request-To-Send output pin */
# define BUSVOODOO_RS232_CTS_PORT A /**< RS-232 Clear-To-Send input pin */
# define BUSVOODOO_RS232_CTS_PIN 0 /**< RS-232 Clear-To-Send input pin */
# define BUSVOODOO_RS232_TX_PORT A /**< RS-232 Transmit output pin */
# define BUSVOODOO_RS232_TX_PIN 2 /**< RS-232 Transmit output pin */
# define BUSVOODOO_RS232_RX_PORT A /**< RS-232 Receive input pin */
# define BUSVOODOO_RS232_RX_PIN 3 /**< RS-232 Receive input pin */
/** @} */
2017-12-12 13:56:28 +01:00
2017-12-22 17:25:05 +01:00
/** @defgroup busvoodoo_can CAN transceiver connection definition
* @ {
*/
# define BUSVOODOO_CAN_EN_PORT C /**< CAN pin to enable transceiver (active high, pulled low) */
# define BUSVOODOO_CAN_EN_PIN 14 /**< CAN pin to enable transceiver (active high, pulled low) */
# define BUSVOODOO_CAN_S_PORT C /**< CAN pin to set to silent mode (active low, pulled high) */
# define BUSVOODOO_CAN_S_PIN 13 /**< CAN pin to set to silent mode (active low, pulled high) */
# define BUSVOODOO_CAN_TX_PORT B /**< CAN Transmit output pin */
# define BUSVOODOO_CAN_TX_PIN 9 /**< CAN Transmit output pin */
# define BUSVOODOO_CAN_RX_PORT B /**< CAN Receive input pin */
# define BUSVOODOO_CAN_RX_PIN 8 /**< CAN Receive input pin */
/** @} */
/** @defgroup busvoodoo_io I/O connector pin definition
2017-12-12 13:56:28 +01:00
* @ {
*/
static const char * busvoodoo_io_names [ 13 ] = { " I2C_SMBA/SPI_NSS/I2S_WS " , " SDIO_CMD " , " USART_CTS/SPI_SCK/I2S_CK " , " SDIO_D3/UART_RX " , " I2C_SDA/USART_RX " , " SDIO_D0 " , " SPI_MOSI/I2S_SD " , " SDIO_CK/USART_CK " , " I2C_SCL/USART_TX " , " SDIO_D1 " , " I2S_MCK " , " USART_RTS/SPI_MISO " , " SDIO_D2/UART_TX " } ; /**< I/O individual signal names */
static const uint32_t busvoodoo_io_ports [ 13 ] = { GPIOB , GPIOD , GPIOB , GPIOC , GPIOB , GPIOC , GPIOB , GPIOC , GPIOB , GPIOC , GPIOC , GPIOB , GPIOC } ; /**< port of individual signals */
static const uint32_t busvoodoo_io_pins [ 13 ] = { GPIO12 , GPIO2 , GPIO13 , GPIO11 , GPIO11 , GPIO8 , GPIO15 , GPIO12 , GPIO10 , GPIO9 , GPIO6 , GPIO14 , GPIO10 } ; /**< pin of individual signals */
2017-12-15 19:10:56 +01:00
static const uint8_t busvoodoo_io_groups [ 13 ] = { 6 , 6 , 4 , 4 , 1 , 1 , 5 , 5 , 2 , 2 , 3 , 3 , 3 } ; /**< which I/O pin (group) does the signal belong to */
2017-12-12 13:56:28 +01:00
/** @} */
2017-04-03 13:32:45 +02:00
2017-12-22 17:25:05 +01:00
/** is the BusVoodoo board fully populated (with 12V voltage regulator, RS-232, RS-485, CAN transceiver on the back side) */
static bool busvoodoo_full = false ;
2017-04-03 13:32:45 +02:00
size_t putc ( char c )
2016-01-17 14:54:54 +01:00
{
2017-04-03 13:32:45 +02:00
size_t length = 0 ; // number of characters printed
2018-01-14 13:49:16 +01:00
static char last_c = 0 ; // to remember on which character we last sent
if ( ' \n ' = = c ) { // send carriage return (CR) + line feed (LF) newline for each LF
if ( ' \r ' ! = last_c ) { // CR has not already been sent
2017-12-16 13:37:35 +01:00
uart_putchar_nonblocking ( ' \r ' ) ; // send CR over USART
2017-04-19 16:24:07 +02:00
usb_cdcacm_putchar ( ' \r ' ) ; // send CR over USB
2018-01-14 13:49:16 +01:00
length + + ; // remember we printed 1 character
2016-01-17 14:54:54 +01:00
}
}
2018-01-14 13:49:16 +01:00
uart_putchar_nonblocking ( c ) ; // send byte over USART
usb_cdcacm_putchar ( c ) ; // send byte over USB
length + + ; // remember we printed 1 character
last_c = c ; // remember last character
2017-04-03 13:32:45 +02:00
return length ; // return number of characters printed
2016-01-17 14:54:54 +01:00
}
2017-12-12 13:56:28 +01:00
static bool wait_space ( void )
{
// disable watchdog when waiting for user input
printf ( " press space to continue, or any other key to abort \n " ) ;
2017-12-16 13:37:35 +01:00
while ( ! uart_received & & ! usb_cdcacm_received ) { // wait for user input
2017-12-12 13:56:28 +01:00
__WFI ( ) ; // go to sleep
}
char c = 0 ;
2017-12-16 13:37:35 +01:00
if ( uart_received ) {
c = uart_getchar ( ) ; // read user input from UART
2017-12-12 13:56:28 +01:00
} else if ( usb_cdcacm_received ) {
c = usb_cdcacm_getchar ( ) ; // read user input from USB
} else {
return false ; // this should not happen
}
if ( ' ' = = c ) { // space entered
return true ;
} else { // something else entered
return false ;
}
}
/** set safe state by disabling all outputs */
static void safe_state ( void )
{
// disable voltage outputs
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)
2017-12-15 19:10:56 +01:00
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)
2017-12-12 13:56:28 +01:00
2017-12-22 17:25:05 +01:00
// 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
2017-12-12 13:56:28 +01:00
// 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)
2017-12-15 19:10:56 +01:00
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)
2017-12-12 13:56:28 +01:00
// disable all signal I/O outputs
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) ; pin + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , busvoodoo_io_pins [ pin ] ) ; // set pin back to input (floating)
}
2017-12-22 17:25:05 +01:00
// disable all RS-232 and some RS-485 signals (put back to input floating)
gpio_set_mode ( GPIO ( BUSVOODOO_RS232_TX_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_RS232_TX_PIN ) ) ;
gpio_set_mode ( GPIO ( BUSVOODOO_RS232_RX_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_RS232_RX_PIN ) ) ;
gpio_set_mode ( GPIO ( BUSVOODOO_RS232_RTS_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_RS232_RTS_PIN ) ) ;
gpio_set_mode ( GPIO ( BUSVOODOO_RS232_CTS_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_RS232_CTS_PIN ) ) ;
gpio_set ( GPIO ( BUSVOODOO_RS232_EN_PORT ) , GPIO ( BUSVOODOO_RS232_EN_PIN ) ) ; // set high to disable receiver
gpio_clear ( GPIO ( BUSVOODOO_RS232_SHDN_PORT ) , GPIO ( BUSVOODOO_RS232_SHDN_PIN ) ) ; // set low to disable transmitter
// disable all CAN and some RS-458 signals (put back to input floating)
gpio_set_mode ( GPIO ( BUSVOODOO_CAN_TX_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_CAN_TX_PIN ) ) ;
gpio_set_mode ( GPIO ( BUSVOODOO_CAN_RX_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_CAN_RX_PIN ) ) ;
gpio_set_mode ( GPIO ( BUSVOODOO_CAN_EN_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_CAN_EN_PIN ) ) ;
gpio_set_mode ( GPIO ( BUSVOODOO_CAN_S_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_CAN_S_PIN ) ) ;
2017-12-12 13:56:28 +01:00
}
/** read power rail voltage
* @ param [ in ] channel which ADC channel to read voltage from
* @ return voltage of NaN if channel is invalid
*/
static float rail_voltage ( uint8_t channel )
{
if ( channel ! = BUSVOODOO_5V_CHANNEL & & channel ! = BUSVOODOO_3V3_CHANNEL & & channel ! = BUSVOODOO_XV_CHANNEL & & channel ! = BUSVOODOO_12V_CHANNEL ) { // check channel
return NAN ;
}
uint16_t channels [ 5 ] = { 0 } ; // to start converted values: internal reference 1.2V, 5V rail, 3.3V rail, xV rail, 12V rail
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
channels [ channel_i ] = adc_read_regular ( ADC1 ) ; // read voltage value (clears flag)
}
float to_return = NAN ; // voltage to return
switch ( channel ) { // get converter value and calculate according to the voltage divider on this channel
case BUSVOODOO_5V_CHANNEL :
to_return = channels [ 1 ] / ( 10.0 / ( 10.0 + 10.0 ) ) ;
break ;
case BUSVOODOO_3V3_CHANNEL :
to_return = channels [ 2 ] / ( 10.0 / ( 10.0 + 10.0 ) ) ;
break ;
case BUSVOODOO_XV_CHANNEL :
to_return = channels [ 3 ] / ( 10.0 / ( 10.0 + 10.0 ) ) ;
break ;
case BUSVOODOO_12V_CHANNEL :
to_return = channels [ 4 ] / ( 1.5 / ( 10.0 + 1.5 ) ) ;
break ;
default : // unknown channel
to_return = NAN ;
break ;
}
if ( ! isnan ( to_return ) ) {
to_return * = 1.2 / channels [ 0 ] ; // calculate voltage from converted values using internal 1.2V voltage reference
}
return to_return ;
}
/** perform self tests
* @ return if self tests passed
*/
static bool test_self ( void )
{
bool to_return = false ; // success of the self-test
safe_state ( ) ; // start from a safe state
2017-12-22 17:25:05 +01:00
printf ( " remove all cables from connector \n " ) ;
wait_space ( ) ;
2017-12-12 13:56:28 +01:00
// get device information
// get device identifier (DEV_ID)
// 0x412: low-density, 16-32 kB flash
// 0x410: medium-density, 64-128 kB flash
// 0x414: high-density, 256-512 kB flash
// 0x430: XL-density, 768-1024 kB flash
// 0x418: connectivity
2017-12-22 17:25:05 +01:00
if ( 0 = = ( DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK ) ) {
printf ( " device identifier not set: this is probably a defective micro-controller \n " ) ;
} else if ( 0x414 ! = ( DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK ) ) {
printf ( " this (DEV_ID=%03x) is not a high-density device: a wrong micro-controller might have been used \n " , ( DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK ) ) ;
2017-12-12 13:56:28 +01:00
}
// ensure flash size is ok
if ( 0xffff = = DESIG_FLASH_SIZE ) {
printf ( " unknown flash size: this is probably a defective micro-controller \n " ) ;
}
// check 5V power rail
float voltage = rail_voltage ( BUSVOODOO_5V_CHANNEL ) ; // get 5V power rail voltage
if ( voltage < 4.0 ) {
2017-12-22 17:25:05 +01:00
printf ( " 5V power rail voltage is too low: %.2fV \n " , voltage ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( voltage > 5.5 ) {
2017-12-22 17:25:05 +01:00
printf ( " 5V power rail voltage is too high: %.2fV \n " , voltage ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
// check 3.3V power rail
voltage = rail_voltage ( BUSVOODOO_3V3_CHANNEL ) ; // get 3.3V power rail voltage
if ( voltage < 3.0 ) {
2017-12-22 17:25:05 +01:00
printf ( " 3.3V power rail voltage is too low: %.2fV \n " , voltage ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( voltage > 3.6 ) {
2017-12-22 17:25:05 +01:00
printf ( " 3.3V power rail voltage is too high: %.2fV \n " , voltage ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
2017-12-22 17:25:05 +01:00
// test 5V and 3.3V outputs
gpio_clear ( GPIO ( BUSVOODOO_VOUTEN_PORT ) , GPIO ( BUSVOODOO_VOUTEN_PIN ) ) ; // enable Vout
sleep_ms ( 1 ) ; // wait a bit for voltage to settle
voltage = rail_voltage ( BUSVOODOO_5V_CHANNEL ) ; // get 5V power rail voltage
if ( voltage < 4.0 ) {
printf ( " 5V power rail voltage is too low when 5V output is enabled: %.2fV \n " , voltage ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( voltage > 5.5 ) {
printf ( " 5V power rail voltage is too high when 5V output is enabled: %.2fV \n " , voltage ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
voltage = rail_voltage ( BUSVOODOO_3V3_CHANNEL ) ; // get 3.3V power rail voltage
if ( voltage < 3.0 ) {
printf ( " 3.3V power rail voltage is too low when 3V3 output is enabled: %.2fV \n " , voltage ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( voltage > 3.6 ) {
printf ( " 3.3V power rail voltage is too high when 3V3 is enabled: %.2fV \n " , voltage ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
gpio_set ( GPIO ( BUSVOODOO_VOUTEN_PORT ) , GPIO ( BUSVOODOO_VOUTEN_PIN ) ) ; // disable Vout
2017-12-12 13:56:28 +01:00
// check xV voltage regulator
2017-12-15 19:10:56 +01:00
gpio_clear ( GPIO ( BUSVOODOO_XVEN_PORT ) , GPIO ( BUSVOODOO_XVEN_PIN ) ) ; // disable xV voltage regulator
sleep_ms ( 1 ) ; // let voltage settle
voltage = rail_voltage ( BUSVOODOO_XV_CHANNEL ) ; // get xV voltage
if ( voltage > 0.2 ) { // ensure the output is at 0V when the regulator is not enabled
2017-12-22 17:25:05 +01:00
printf ( " xV voltage is %.2fV instead of 0V when the regulator is disabled \n " , voltage ) ;
2017-12-15 19:10:56 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
2017-12-12 13:56:28 +01:00
gpio_set ( GPIO ( BUSVOODOO_XVEN_PORT ) , GPIO ( BUSVOODOO_XVEN_PIN ) ) ; // enable xV voltage regulator
2017-12-22 17:25:05 +01:00
sleep_ms ( 5 ) ; // let the voltage regulator start and voltage settle
2017-12-12 13:56:28 +01:00
voltage = rail_voltage ( BUSVOODOO_XV_CHANNEL ) ; // get xV voltage
// without being driven it should be around the default voltage
if ( voltage < BUSVOODOO_XV_DEFAULT - 0.2 ) {
2017-12-22 17:25:05 +01:00
printf ( " xV voltage is lower (%.2fV) than expected (%.2fV) when the regulator is enabled \n " , voltage , BUSVOODOO_XV_DEFAULT ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( voltage > BUSVOODOO_XV_DEFAULT + 0.2 ) {
2017-12-22 17:25:05 +01:00
printf ( " xV voltage is higher (%.2fV) than expected (%.2fV) when the regulator is enabled \n " , voltage , BUSVOODOO_XV_DEFAULT ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
// check if we can control xV
voltage = rail_voltage ( BUSVOODOO_3V3_CHANNEL ) ; // get reference voltage
if ( isnan ( voltage ) ) {
printf ( " can get 3V3 rail voltage " ) ;
goto error ;
}
uint16_t dac_set = BUSVOODOO_XV_SET ( BUSVOODOO_XV_TEST ) / voltage * 4095 ; // DAC value corresponding to the voltage
2017-12-22 17:25:05 +01:00
dac_load_data_buffer_single ( dac_set , RIGHT12 , BUSVOODOO_XVCTL_CHANNEL ) ; // set output so the voltage regulator is set to 2.5V
dac_software_trigger ( BUSVOODOO_XVCTL_CHANNEL ) ; // transfer the value to the DAC
dac_enable ( BUSVOODOO_XVCTL_CHANNEL ) ; // enable DAC
2017-12-12 13:56:28 +01:00
sleep_ms ( 5 ) ; // let voltage settle
voltage = rail_voltage ( BUSVOODOO_XV_CHANNEL ) ; // get xV voltage
// check if it matched desired voltage
2017-12-22 17:25:05 +01:00
if ( voltage < BUSVOODOO_XV_TEST - 0.2 ) {
printf ( " xV voltage is lower (%.2fV) than set (%.2fV) \n " , voltage , BUSVOODOO_XV_TEST ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( voltage > BUSVOODOO_XV_TEST + 0.2 ) {
2017-12-22 17:25:05 +01:00
printf ( " xV voltage is highed (%.2fV) than set (%.2fV) \n " , voltage , BUSVOODOO_XV_TEST ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
2017-12-22 17:25:05 +01:00
dac_disable ( BUSVOODOO_XVCTL_CHANNEL ) ; // disable xV control
2017-12-12 13:56:28 +01:00
gpio_clear ( GPIO ( BUSVOODOO_XVEN_PORT ) , GPIO ( BUSVOODOO_XVEN_PIN ) ) ; // disable xV voltage regulator
sleep_ms ( 1 ) ; // let voltage settle
// check 12V voltage regulator
2017-12-22 17:25:05 +01:00
if ( busvoodoo_full ) {
gpio_set ( GPIO ( BUSVOODOO_12VEN_PORT ) , GPIO ( BUSVOODOO_12VEN_PIN ) ) ; // disable 12V voltage regulator
sleep_ms ( 1 ) ; // let voltage settle
voltage = rail_voltage ( BUSVOODOO_12V_CHANNEL ) ; // get 12V voltage
if ( voltage > 0.2 ) { // ensure the output is at 0V when the regulator is not enabled
printf ( " 12V voltage is %.2fV instead of 0V when the regulator is disabled \n " , voltage ) ;
2017-12-15 19:10:56 +01:00
# if DEBUG
2017-12-22 17:25:05 +01:00
while ( true ) ;
2017-12-15 19:10:56 +01:00
# else
2017-12-22 17:25:05 +01:00
goto error ;
2017-12-15 19:10:56 +01:00
# endif
2017-12-22 17:25:05 +01:00
}
gpio_clear ( GPIO ( BUSVOODOO_12VEN_PORT ) , GPIO ( BUSVOODOO_12VEN_PIN ) ) ; // enable 12V voltage regulator
sleep_ms ( 10 ) ; // let the voltage regulator start and voltage settle
voltage = rail_voltage ( BUSVOODOO_12V_CHANNEL ) ; // get 12V voltage
// without being driven it should be around the default voltage
if ( voltage < BUSVOODOO_12V_DEFAULT - 0.3 ) {
printf ( " 12V voltage is lower (%.2fV) than expected (%.2fV) when regulator is enabled \n " , voltage , BUSVOODOO_12V_DEFAULT ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
2017-12-22 17:25:05 +01:00
while ( true ) ;
2017-12-12 13:56:28 +01:00
# else
2017-12-22 17:25:05 +01:00
goto error ;
2017-12-12 13:56:28 +01:00
# endif
2017-12-22 17:25:05 +01:00
} else if ( voltage > BUSVOODOO_12V_DEFAULT + 0.3 ) {
printf ( " 12V voltage is higher (%.2fV) than expected (%.2fV) when regulator is enabled \n " , voltage , BUSVOODOO_12V_DEFAULT ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
2017-12-22 17:25:05 +01:00
while ( true ) ;
2017-12-12 13:56:28 +01:00
# else
2017-12-22 17:25:05 +01:00
goto error ;
2017-12-12 13:56:28 +01:00
# endif
2017-12-22 17:25:05 +01:00
}
2017-12-12 13:56:28 +01:00
2017-12-22 17:25:05 +01:00
// check if we can control 12V voltage regulator
voltage = rail_voltage ( BUSVOODOO_3V3_CHANNEL ) ; // get reference voltage
if ( isnan ( voltage ) ) {
printf ( " can get 3V3 rail voltage " ) ;
goto error ;
}
dac_set = BUSVOODOO_12V_SET ( BUSVOODOO_12V_TEST ) / voltage * 4095 ; // DAC value corresponding to the voltage
dac_load_data_buffer_single ( dac_set , RIGHT12 , BUSVOODOO_12VCTL_CHANNEL ) ; // set output so the voltage regulator is set to desired output voltage
dac_software_trigger ( BUSVOODOO_12VCTL_CHANNEL ) ; // transfer the value to the DAC
dac_enable ( BUSVOODOO_12VCTL_CHANNEL ) ; // enable DAC
sleep_ms ( 10 ) ; // let voltage settle
voltage = rail_voltage ( BUSVOODOO_12V_CHANNEL ) ; // get 12V voltage
if ( voltage < BUSVOODOO_12V_TEST - 0.3 ) {
printf ( " 12V voltage is lower (%.2fV) than set (%.2fV) \n " , voltage , BUSVOODOO_12V_TEST ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
2017-12-22 17:25:05 +01:00
while ( true ) ;
2017-12-12 13:56:28 +01:00
# else
2017-12-22 17:25:05 +01:00
goto error ;
2017-12-12 13:56:28 +01:00
# endif
2017-12-22 17:25:05 +01:00
} else if ( voltage > BUSVOODOO_12V_TEST + 0.3 ) {
printf ( " 12V voltage is higher (%.2fV) than set (%.2fV) \n " , voltage , BUSVOODOO_12V_TEST ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
2017-12-22 17:25:05 +01:00
while ( true ) ;
2017-12-12 13:56:28 +01:00
# else
2017-12-22 17:25:05 +01:00
goto error ;
2017-12-12 13:56:28 +01:00
# endif
2017-12-22 17:25:05 +01:00
}
dac_disable ( BUSVOODOO_12VCTL_CHANNEL ) ; // disable 12V control
gpio_set ( GPIO ( BUSVOODOO_12VEN_PORT ) , GPIO ( BUSVOODOO_12VEN_PIN ) ) ; // disable 12V voltage regulator
sleep_ms ( 1 ) ; // let voltage settle
2017-12-12 13:56:28 +01:00
}
// pull all pins down and ensure they are low
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) ; pin + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_PULL_UPDOWN , busvoodoo_io_pins [ pin ] ) ; // set pin to input
gpio_clear ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ; // pull down so it's not floating
}
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) & & pin < LENGTH ( busvoodoo_io_names ) ; pin + + ) {
if ( gpio_get ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ) { // ensure it really is low
printf ( " signal %s is high although it is pulled low (internal) \n " , busvoodoo_io_names [ pin ] ) ; // warn user about the error
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
}
// pull all pins up and ensure they are high
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) ; pin + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_PULL_UPDOWN , busvoodoo_io_pins [ pin ] ) ; // set pin to input
gpio_set ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ; // pull up using internal pull-up
}
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) & & pin < LENGTH ( busvoodoo_io_names ) ; pin + + ) {
if ( ! gpio_get ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ) { // ensure it really is high
2017-12-22 17:25:05 +01:00
printf ( " signal %s is low although it is pulled up (internal) \n " , busvoodoo_io_names [ pin ] ) ; // warn user about the error
2017-12-12 13:56:28 +01:00
# if DEBUG
2017-12-15 19:10:56 +01:00
while ( true ) ;
2017-12-12 13:56:28 +01:00
# else
2017-12-15 19:10:56 +01:00
goto error ;
2017-12-12 13:56:28 +01:00
# endif
}
}
// set individual pin high and ensure only pins in the same group are at the same level
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) ; pin + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_PULL_UPDOWN , busvoodoo_io_pins [ pin ] ) ; // set pin to input
gpio_clear ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ; // pull down to ensure it is not high by accident
}
for ( uint8_t pin1 = 0 ; pin1 < LENGTH ( busvoodoo_io_ports ) & & pin1 < LENGTH ( busvoodoo_io_pins ) & & pin1 < LENGTH ( busvoodoo_io_groups ) & & pin1 < LENGTH ( busvoodoo_io_names ) ; pin1 + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin1 ] , GPIO_MODE_OUTPUT_2_MHZ , GPIO_CNF_OUTPUT_PUSHPULL , busvoodoo_io_pins [ pin1 ] ) ; // set button pin to output
gpio_set ( busvoodoo_io_ports [ pin1 ] , busvoodoo_io_pins [ pin1 ] ) ; // set pin high
for ( uint8_t pin2 = 0 ; pin2 < LENGTH ( busvoodoo_io_ports ) & & pin2 < LENGTH ( busvoodoo_io_pins ) & & pin2 < LENGTH ( busvoodoo_io_groups ) & & pin2 < LENGTH ( busvoodoo_io_names ) ; pin2 + + ) {
if ( busvoodoo_io_groups [ pin1 ] = = busvoodoo_io_groups [ pin2 ] & & ! gpio_get ( busvoodoo_io_ports [ pin2 ] , busvoodoo_io_pins [ pin2 ] ) ) {
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
2017-12-22 17:25:05 +01:00
# if DEBUG
while ( true ) ;
# else
2017-12-12 13:56:28 +01:00
goto error ;
2017-12-22 17:25:05 +01:00
# endif
2017-12-12 13:56:28 +01:00
} else if ( busvoodoo_io_groups [ pin1 ] ! = busvoodoo_io_groups [ pin2 ] & & gpio_get ( busvoodoo_io_ports [ pin2 ] , busvoodoo_io_pins [ pin2 ] ) ) {
2017-12-15 19:10:56 +01:00
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
2017-12-12 13:56:28 +01:00
# if DEBUG
2017-12-15 19:10:56 +01:00
while ( true ) ;
2017-12-12 13:56:28 +01:00
# else
2017-12-15 19:10:56 +01:00
goto error ;
2017-12-12 13:56:28 +01:00
# endif
}
}
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
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) ; pin + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_PULL_UPDOWN , busvoodoo_io_pins [ pin ] ) ; // set pin to input
gpio_set ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ; // pull up to ensure it is not low by accident
}
for ( uint8_t pin1 = 0 ; pin1 < LENGTH ( busvoodoo_io_ports ) & & pin1 < LENGTH ( busvoodoo_io_pins ) & & pin1 < LENGTH ( busvoodoo_io_groups ) & & pin1 < LENGTH ( busvoodoo_io_names ) ; pin1 + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin1 ] , GPIO_MODE_OUTPUT_2_MHZ , GPIO_CNF_OUTPUT_PUSHPULL , busvoodoo_io_pins [ pin1 ] ) ; // set button pin to output
gpio_clear ( busvoodoo_io_ports [ pin1 ] , busvoodoo_io_pins [ pin1 ] ) ; // set pin low
for ( uint8_t pin2 = 0 ; pin2 < LENGTH ( busvoodoo_io_ports ) & & pin2 < LENGTH ( busvoodoo_io_pins ) & & pin2 < LENGTH ( busvoodoo_io_groups ) & & pin2 < LENGTH ( busvoodoo_io_names ) ; pin2 + + ) {
if ( busvoodoo_io_groups [ pin1 ] = = busvoodoo_io_groups [ pin2 ] & & gpio_get ( busvoodoo_io_ports [ pin2 ] , busvoodoo_io_pins [ pin2 ] ) ) {
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
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( busvoodoo_io_groups [ pin1 ] ! = busvoodoo_io_groups [ pin2 ] & & ! gpio_get ( busvoodoo_io_ports [ pin2 ] , busvoodoo_io_pins [ pin2 ] ) ) {
2017-12-15 19:10:56 +01:00
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
2017-12-12 13:56:28 +01:00
# if DEBUG
2017-12-15 19:10:56 +01:00
while ( true ) ;
2017-12-12 13:56:28 +01:00
# else
2017-12-15 19:10:56 +01:00
goto error ;
2017-12-12 13:56:28 +01:00
# endif
}
}
gpio_set_mode ( busvoodoo_io_ports [ pin1 ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_PULL_UPDOWN , busvoodoo_io_pins [ pin1 ] ) ; // set pin back to input
2017-12-15 19:10:56 +01:00
gpio_set ( busvoodoo_io_ports [ pin1 ] , busvoodoo_io_pins [ pin1 ] ) ; // pull pin back up
2017-12-12 13:56:28 +01:00
}
// test 5V pull-up
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) ; pin + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_PULL_UPDOWN , busvoodoo_io_pins [ pin ] ) ; // set pin to input
gpio_clear ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ; // pull down to ensure it is not high by accident
}
gpio_clear ( GPIO ( BUSVOODOO_5VPULLUP_PORT ) , GPIO ( BUSVOODOO_5VPULLUP_PIN ) ) ; // enable 5V pull-up
2017-12-15 19:10:56 +01:00
gpio_clear ( GPIO ( BUSVOODOO_OEPULLUP_PORT ) , GPIO ( BUSVOODOO_OEPULLUP_PIN ) ) ; // switch on embedded pull-ups
2017-12-12 13:56:28 +01:00
sleep_ms ( 1 ) ; // wait a bit for voltage to settle
voltage = rail_voltage ( BUSVOODOO_5V_CHANNEL ) ; // get 5V power rail voltage
if ( voltage < 4.0 ) {
2017-12-22 17:25:05 +01:00
printf ( " 5V power rail voltage is too low when used to pull up: %.2fV \n " , voltage ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( voltage > 5.5 ) {
2017-12-22 17:25:05 +01:00
printf ( " 5V power rail voltage is too high when used to pull up: %.2fV \n " , voltage ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) & & pin < LENGTH ( busvoodoo_io_names ) ; pin + + ) {
if ( ! gpio_get ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ) { // ensure it really is high
2017-12-22 17:25:05 +01:00
printf ( " signal %s is low although it is pulled up by 5V (embedded) \n " , busvoodoo_io_names [ pin ] ) ; // warn user about the error
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
}
gpio_set ( GPIO ( BUSVOODOO_5VPULLUP_PORT ) , GPIO ( BUSVOODOO_5VPULLUP_PIN ) ) ; // disable 5V pull-up
2017-12-15 19:10:56 +01:00
gpio_set ( GPIO ( BUSVOODOO_OEPULLUP_PORT ) , GPIO ( BUSVOODOO_OEPULLUP_PIN ) ) ; // switch off embedded pull-up
2017-12-12 13:56:28 +01:00
// test xV pull-up set to 3.3V
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) ; pin + + ) {
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_PULL_UPDOWN , busvoodoo_io_pins [ pin ] ) ; // set pin to input
gpio_clear ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ; // pull down to ensure it is not high by accident
}
gpio_set ( GPIO ( BUSVOODOO_XVEN_PORT ) , GPIO ( BUSVOODOO_XVEN_PIN ) ) ; // enable xV voltage regulator
2017-12-15 19:10:56 +01:00
gpio_clear ( GPIO ( BUSVOODOO_OEPULLUP_PORT ) , GPIO ( BUSVOODOO_OEPULLUP_PIN ) ) ; // switch in embedded pull-up
2017-12-22 17:25:05 +01:00
sleep_ms ( 5 ) ; // let the voltage regulator start and voltage settle
2017-12-12 13:56:28 +01:00
voltage = rail_voltage ( BUSVOODOO_XV_CHANNEL ) ; // get xV voltage (without being driven it should be around 3.2V)
if ( voltage < BUSVOODOO_XV_DEFAULT - 0.2 ) {
2017-12-22 17:25:05 +01:00
printf ( " xV voltage is lower (%.2fV) than expected (%.2fV) when used to pull up \n " , voltage , BUSVOODOO_XV_DEFAULT ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
} else if ( voltage > BUSVOODOO_XV_DEFAULT + 0.2 ) {
2017-12-22 17:25:05 +01:00
printf ( " xV voltage is higher (%.2fV) than expected (%.2fV) when used to pull up \n " , voltage , BUSVOODOO_XV_DEFAULT ) ;
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
for ( uint8_t pin = 0 ; pin < LENGTH ( busvoodoo_io_ports ) & & pin < LENGTH ( busvoodoo_io_pins ) & & pin < LENGTH ( busvoodoo_io_names ) ; pin + + ) {
if ( ! gpio_get ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ) { // ensure it really is high
2017-12-22 17:25:05 +01:00
printf ( " signal %s is low although it is pulled up by xV (embedded) \n " , busvoodoo_io_names [ pin ] ) ; // warn user about the error
2017-12-12 13:56:28 +01:00
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
}
2017-12-15 19:10:56 +01:00
gpio_set ( GPIO ( BUSVOODOO_OEPULLUP_PORT ) , GPIO ( BUSVOODOO_OEPULLUP_PIN ) ) ; // switch off embedded pull-up
2017-12-12 13:56:28 +01:00
gpio_clear ( GPIO ( BUSVOODOO_XVEN_PORT ) , GPIO ( BUSVOODOO_XVEN_PIN ) ) ; // disable xV voltage regulator
to_return = true ; // all tests are successful
error :
safe_state ( ) ; // set back to safe state
if ( ! to_return ) {
2017-12-22 17:25:05 +01:00
printf ( " the test procedure has been aborted for safety reasons \n " ) ;
2017-12-12 13:56:28 +01:00
}
return to_return ;
}
2017-12-22 17:25:05 +01:00
/** test if signals are soldered correctly to the connector pins */
static bool test_pins ( void )
2017-12-12 13:56:28 +01:00
{
2017-12-22 17:25:05 +01:00
bool to_return = false ; // test result to return
2017-12-12 13:56:28 +01:00
safe_state ( ) ; // start from safe state with all outputs switched off
2017-12-22 17:25:05 +01:00
const char * xv_to = " connect I/O pin 4 to " ; // most outputs will be tested using xV ADC
const char * xv_high = " pin 4 is high while it should be low, other pin might be defective \n " ; // error message if expect low output is high
printf ( " test will proceed automatically once the connection is detected \n " ) ;
// test GND on pin 1 by shorting xV_CTL to ground (through 40k resistor) and measure short
gpio_set ( GPIO ( BUSVOODOO_XVCTL_PORT ) , GPIO ( BUSVOODOO_XVCTL_PIN ) ) ; // set pin high
gpio_set_mode ( GPIO ( BUSVOODOO_XVCTL_PORT ) , GPIO_MODE_OUTPUT_2_MHZ , GPIO_CNF_OUTPUT_PUSHPULL , GPIO ( BUSVOODOO_XVCTL_PIN ) ) ; // set xV control pin as output
printf ( " %sI/O pin 1 \n " , xv_to ) ;
while ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) > 0.2 ) { // wait until pin is shorted to ground
sleep_ms ( 200 ) ; // wait for user to make connection
2017-12-12 13:56:28 +01:00
}
2017-12-22 17:25:05 +01:00
gpio_clear ( GPIO ( BUSVOODOO_XVCTL_PORT ) , GPIO ( BUSVOODOO_XVCTL_PIN ) ) ; // set pin low
gpio_set_mode ( GPIO ( BUSVOODOO_XVCTL_PORT ) , GPIO_MODE_OUTPUT_2_MHZ , GPIO_CNF_OUTPUT_PUSHPULL , GPIO ( BUSVOODOO_XVCTL_PIN ) ) ; // set xV control pin as output
led_toggle ( ) ; // notify user test is almost almost
sleep_ms ( 200 ) ; // wait for voltage to settle an debounce
if ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) > 0.2 ) {
printf ( xv_high ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
gpio_set_mode ( GPIO ( BUSVOODOO_XVCTL_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_ANALOG , GPIO ( BUSVOODOO_XVCTL_PIN ) ) ; // set xV control pin back to analog input for DAC
led_toggle ( ) ; // notify user test is complete
// test 5V output on pin 2
2017-12-12 13:56:28 +01:00
gpio_clear ( GPIO ( BUSVOODOO_VOUTEN_PORT ) , GPIO ( BUSVOODOO_VOUTEN_PIN ) ) ; // enable Vout
2017-12-22 17:25:05 +01:00
printf ( " %sI/O pin 2 \n " , xv_to ) ;
while ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) < 0.2 ) { // wait until pin is connected
sleep_ms ( 200 ) ; // wait for user to make connection
2017-12-12 13:56:28 +01:00
}
gpio_set ( GPIO ( BUSVOODOO_VOUTEN_PORT ) , GPIO ( BUSVOODOO_VOUTEN_PIN ) ) ; // disable Vout
2017-12-22 17:25:05 +01:00
led_toggle ( ) ; // notify user test is almost complete
sleep_ms ( 200 ) ; // wait for voltage to settle and debounce
if ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) > 0.2 ) {
printf ( xv_high ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
led_toggle ( ) ; // notify user test is complete
2017-12-12 13:56:28 +01:00
// test 3.3V output on pin 3
gpio_clear ( GPIO ( BUSVOODOO_VOUTEN_PORT ) , GPIO ( BUSVOODOO_VOUTEN_PIN ) ) ; // enable Vout
2017-12-22 17:25:05 +01:00
printf ( " %sI/O pin 3 \n " , xv_to ) ;
while ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) < 0.2 | | rail_voltage ( BUSVOODOO_XV_CHANNEL ) > 3.5 ) { // wait until pin is connected
sleep_ms ( 200 ) ; // wait for user to make connection
2017-12-12 13:56:28 +01:00
}
gpio_set ( GPIO ( BUSVOODOO_VOUTEN_PORT ) , GPIO ( BUSVOODOO_VOUTEN_PIN ) ) ; // disable Vout
2017-12-22 17:25:05 +01:00
led_toggle ( ) ; // notify user test is almost complete
sleep_ms ( 200 ) ; // wait for voltage to settle and debounce
if ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) > 0.2 ) {
printf ( xv_high ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
2017-12-12 13:56:28 +01:00
}
2017-12-22 17:25:05 +01:00
led_toggle ( ) ; // notify user test is complete
2017-12-12 13:56:28 +01:00
// test I/O pins
for ( uint8_t io = 1 ; io < = 6 ; io + + ) { // test each I/O pin
for ( uint8_t pin = 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 ) {
2017-12-22 17:25:05 +01:00
gpio_set ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ; // set pin high
2017-12-12 13:56:28 +01:00
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_OUTPUT_2_MHZ , GPIO_CNF_OUTPUT_PUSHPULL , busvoodoo_io_pins [ pin ] ) ; // set pin to output
2017-12-22 17:25:05 +01:00
printf ( " %sI/O pin %u \n " , xv_to , io + 4 ) ;
while ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) < 0.2 ) { // wait until pin is connected
sleep_ms ( 200 ) ; // wait for user to make connection
2017-12-12 13:56:28 +01:00
}
2017-12-22 17:25:05 +01:00
gpio_clear ( busvoodoo_io_ports [ pin ] , busvoodoo_io_pins [ pin ] ) ; // set pin low
led_toggle ( ) ; // notify user test is almost complete
sleep_ms ( 200 ) ; // wait for voltage to settle and debounce
if ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) > 0.2 ) {
printf ( xv_high ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
2017-12-12 13:56:28 +01:00
}
gpio_set_mode ( busvoodoo_io_ports [ pin ] , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , busvoodoo_io_pins [ pin ] ) ; // set pin back to input
2017-12-22 17:25:05 +01:00
led_toggle ( ) ; // notify user test is complete
2017-12-12 13:56:28 +01:00
break ; // stop looking for pin
}
}
}
2017-12-22 17:25:05 +01:00
if ( busvoodoo_full ) {
// test 12V output on RS/CAN pin 1
double voltage = rail_voltage ( BUSVOODOO_3V3_CHANNEL ) ; // get reference voltage
uint16_t dac_set = BUSVOODOO_12V_SET ( 5.0 ) / voltage * 4095 ; // DAC value corresponding to the voltage
dac_load_data_buffer_single ( dac_set , RIGHT12 , BUSVOODOO_12VCTL_CHANNEL ) ; // set output so the voltage regulator is set to desired output voltage
dac_software_trigger ( BUSVOODOO_12VCTL_CHANNEL ) ; // transfer the value to the DAC
dac_enable ( BUSVOODOO_12VCTL_CHANNEL ) ; // enable DAC
gpio_clear ( GPIO ( BUSVOODOO_12VEN_PORT ) , GPIO ( BUSVOODOO_12VEN_PIN ) ) ; // enable 12V voltage regulator
printf ( " %sRS/CAN pin 1 \n " , xv_to ) ;
while ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) < 0.2 ) { // wait until pin is connected
sleep_ms ( 200 ) ; // wait for user to make connection
}
gpio_set ( GPIO ( BUSVOODOO_12VEN_PORT ) , GPIO ( BUSVOODOO_12VEN_PIN ) ) ; // disable 12V voltage regulator
dac_disable ( BUSVOODOO_12VCTL_CHANNEL ) ; // disable 12V control
led_toggle ( ) ; // notify user test is almost complete
sleep_ms ( 200 ) ; // wait for voltage to settle (and debounce)
if ( rail_voltage ( BUSVOODOO_XV_CHANNEL ) > 0.2 ) {
printf ( xv_high ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
led_toggle ( ) ; // notify user test is complete
// test RS-232 port (with itself)
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 " ) ;
while ( gpio_get ( GPIO ( BUSVOODOO_RS232_RX_PORT ) , GPIO ( BUSVOODOO_RS232_RX_PIN ) ) ) { // wait until pin is connected
sleep_ms ( 200 ) ; // wait for user to make connection
}
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
led_toggle ( ) ; // notify user test is almost complete
sleep_ms ( 200 ) ; // 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 ( " CAN/RS pin 2 is high while it should be set low by pin 3 \n " ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
gpio_set_mode ( GPIO ( BUSVOODOO_RS232_TX_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_RS232_TX_PIN ) ) ; // free pin
gpio_set_mode ( GPIO ( BUSVOODOO_RS232_RX_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_RS232_RX_PIN ) ) ; // free pin
led_toggle ( ) ; // notify user test is complete
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 " ) ;
while ( gpio_get ( GPIO ( BUSVOODOO_RS232_CTS_PORT ) , GPIO ( BUSVOODOO_RS232_CTS_PIN ) ) ) { // wait until pin is connected
sleep_ms ( 200 ) ; // wait for user to make connection
}
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
led_toggle ( ) ; // notify user test is almost complete
sleep_ms ( 200 ) ; // 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 ( " CAN/RS pin 5 is high while it should be set low by pin 4 \n " ) ;
# if DEBUG
while ( true ) ;
# else
goto error ;
# endif
}
gpio_set_mode ( GPIO ( BUSVOODOO_RS232_RTS_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_RS232_RTS_PIN ) ) ; // free pin
gpio_set_mode ( GPIO ( BUSVOODOO_RS232_CTS_PORT ) , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO ( BUSVOODOO_RS232_CTS_PIN ) ) ; // free pin
led_toggle ( ) ; // notify user test is complete
gpio_set ( GPIO ( BUSVOODOO_RS232_EN_PORT ) , GPIO ( BUSVOODOO_RS232_EN_PIN ) ) ; // set high to disable receiver
gpio_clear ( GPIO ( BUSVOODOO_RS232_SHDN_PORT ) , GPIO ( BUSVOODOO_RS232_SHDN_PIN ) ) ; // set low to disable transmitter
2017-12-15 19:10:56 +01:00
}
2017-12-22 17:25:05 +01:00
to_return = true ; // all tests passed
# if DEBUG
# else
error :
# endif
safe_state ( ) ; // go back to safe state
if ( ! to_return ) {
printf ( " the test procedure has been aborted for safety reasons \n " ) ;
2017-12-15 19:10:56 +01:00
}
2017-12-22 17:25:05 +01:00
return to_return ;
2017-12-12 13:56:28 +01:00
}
2016-08-14 21:02:38 +02:00
/** process user command
* @ param [ in ] str user command string ( \ 0 ended )
*/
static void process_command ( char * str )
2016-01-17 14:54:54 +01:00
{
2018-01-14 13:49:16 +01:00
// don't handle empty lines
if ( ! str | | 0 = = strlen ( str ) ) {
return ;
}
2016-08-14 21:02:38 +02:00
// split command
const char * delimiter = " " ;
char * word = strtok ( str , delimiter ) ;
if ( ! word ) {
goto error ;
}
// parse command
2017-04-19 16:24:07 +02:00
if ( 0 = = strcmp ( word , " h " ) | | 0 = = strcmp ( word , " help " ) | | 0 = = strcmp ( word , " ? " ) ) {
2016-08-14 21:02:38 +02:00
printf ( " available commands: \n " ) ;
printf ( " led [on|off|toggle] \n " ) ;
2017-04-19 16:24:07 +02:00
} else if ( 0 = = strcmp ( word , " l " ) | | 0 = = strcmp ( word , " led " ) ) {
2016-08-14 21:02:38 +02:00
word = strtok ( NULL , delimiter ) ;
if ( ! word ) {
2017-04-19 16:24:07 +02:00
printf ( " LED is " ) ;
if ( gpio_get ( GPIO ( LED_PORT ) , GPIO ( LED_PIN ) ) ) {
printf ( " on \n " ) ;
} else {
printf ( " off \n " ) ;
}
2016-08-14 21:02:38 +02:00
} else if ( 0 = = strcmp ( word , " on " ) ) {
led_on ( ) ; // switch LED on
printf ( " LED switched on \n " ) ; // notify user
} else if ( 0 = = strcmp ( word , " off " ) ) {
led_off ( ) ; // switch LED off
printf ( " LED switched off \n " ) ; // notify user
} else if ( 0 = = strcmp ( word , " toggle " ) ) {
led_toggle ( ) ; // toggle LED
printf ( " LED toggled \n " ) ; // notify user
} else {
goto error ;
}
} else {
goto error ;
}
return ; // command successfully processed
error :
printf ( " command not recognized. enter help to list commands \n " ) ;
2016-10-23 17:42:27 +02:00
return ;
2016-01-17 14:54:54 +01:00
}
2016-08-14 21:02:38 +02:00
/** program entry point
* this is the firmware function started by the micro - controller
*/
2016-10-23 17:42:27 +02:00
void main ( void ) ;
void main ( void )
2016-01-17 15:03:10 +01:00
{
2016-01-29 00:24:49 +01:00
rcc_clock_setup_in_hse_8mhz_out_72mhz ( ) ; // use 8 MHz high speed external clock to generate 72 MHz internal clock
2016-08-14 21:02:38 +02:00
2016-10-23 17:42:27 +02:00
# if DEBUG
2017-01-30 09:44:51 +01:00
// enable functionalities for easier debug
2016-10-23 17:42:27 +02:00
DBGMCU_CR | = DBGMCU_CR_IWDG_STOP ; // stop independent watchdog counter when code is halted
DBGMCU_CR | = DBGMCU_CR_WWDG_STOP ; // stop window watchdog counter when code is halted
DBGMCU_CR | = DBGMCU_CR_STANDBY ; // allow debug also in standby mode (keep digital part and clock powered)
DBGMCU_CR | = DBGMCU_CR_STOP ; // allow debug also in stop mode (keep clock powered)
DBGMCU_CR | = DBGMCU_CR_SLEEP ; // allow debug also in sleep mode (keep clock powered)
2017-02-06 17:40:28 +01:00
# else
2017-01-30 09:44:51 +01:00
// setup watchdog to reset in case we get stuck (i.e. when an error occurred)
iwdg_set_period_ms ( WATCHDOG_PERIOD ) ; // set independent watchdog period
iwdg_start ( ) ; // start independent watchdog
2016-10-23 17:42:27 +02:00
# endif
2017-04-03 13:32:45 +02:00
board_setup ( ) ; // setup board
2017-12-16 13:37:35 +01:00
uart_setup ( ) ; // setup USART (for printing)
2017-04-19 16:26:40 +02:00
usb_cdcacm_setup ( ) ; // setup USB CDC ACM (for printing)
2017-12-12 13:56:28 +01:00
led_blink ( 0 , 1 ) ; // switch blue LED on to show firmware is working
2016-01-29 00:24:49 +01:00
2017-12-22 17:25:05 +01:00
/*
2017-01-30 09:44:51 +01:00
# if !(DEBUG)
// show watchdog information
printf ( " watchdog set to (%.2fs) \n " , WATCHDOG_PERIOD / 1000.0 ) ;
if ( FLASH_OBR & FLASH_OBR_OPTERR ) {
printf ( " option bytes not set in flash: software wachtdog used (not started at reset) \n " ) ;
} else if ( FLASH_OBR & FLASH_OBR_WDG_SW ) {
printf ( " software wachtdog used (not started at reset) \n " ) ;
} else {
printf ( " hardware wachtdog used (started at reset) \n " ) ;
}
# endif
2017-12-22 17:25:05 +01:00
*/
2017-01-30 09:44:51 +01:00
2017-12-12 13:56:28 +01:00
// enable all GPIO domains since we use pins on all ports
rcc_periph_clock_enable ( RCC_GPIOA ) ; // enable clock for all GPIO domains
rcc_periph_clock_enable ( RCC_GPIOB ) ; // enable clock for all GPIO domains
rcc_periph_clock_enable ( RCC_GPIOC ) ; // enable clock for all GPIO domains
rcc_periph_clock_enable ( RCC_GPIOD ) ; // enable clock for all GPIO domains
safe_state ( ) ; // switch off all outputs
2017-12-15 19:10:56 +01:00
2017-12-22 17:25:05 +01:00
printf ( " \n welcome to BusVoodoo ( " ) ; // print welcome message
// check if this BusVoodoo is a full version
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 ;
printf ( " light " ) ;
} else {
busvoodoo_full = true ;
printf ( " full " ) ;
}
printf ( " version) \n " ) ;
2017-12-12 13:56:28 +01:00
// 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_t channels [ ] = { 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_reset_calibration ( ADC1 ) ; // remove previous non-calibration
adc_calibration ( ADC1 ) ; // calibrate ADC for less accuracy errors
// setup DAC to control xV and 12V voltage outputs
2017-12-22 17:25:05 +01:00
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)
2017-12-12 13:56:28 +01:00
rcc_periph_clock_enable ( RCC_DAC ) ; // enable clock for DAC domain
2017-12-22 17:25:05 +01:00
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)
}
2017-12-12 13:56:28 +01:00
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
2018-01-04 14:33:35 +01:00
/*
printf ( " testing OLED screen \n " ) ;
i2c_master_setup ( false ) ;
const uint8_t oled_init [ ] = {
0x00 , // control byte: continuous (multiple byes), command
0xae , // Set Display ON/OFF: OFF
// hardware configuration
0xa8 , 0x3f , // Set Multiplex Ratio: 64
0xd3 , 0x00 , // Set Display Offset: 0
0xa1 , // Set Segment Re-map: column address 0 is mapped to SEG127
0xc8 , // Set COM Output Scan Direction: normal mode (RESET) Scan from COM[N-1] to COM[0]
0xda , 0x12 , // Set COM Pins Hardware Configuration: Alternative COM pin configuration, Disable COM Left/Right remap
0x40 , // Set Display Start Line: start line register from 0
// fundamental commands
0x81 , 0xff , // Set Contrast Control: 256
0xa6 , // Set Normal/Inverse Display: Normal display (RESET)
// Timing & Driving Scheme Setting
0xd5 , 0xf0 , // Set Display Clock Divide Ratio/Oscillator Frequency: Divide ratio=129, F_OSC=1
0xd9 , 0x22 , // Set Pre-charge Period: Phase 1=2 DCLK, Phase 2=2DCLK
0xdb , 0x20 , // Set V_COMH Deselect Level: ~0.77xV_CC
// Charge Pump
0x8d , 0x14 , // Charge Pump Setting: Enable Charge Pump
// Addressing Setting
0x20 , 0x00 // Set Memory Addressing Mode: Horizontal Addressing Mode
} ;
i2c_master_write ( 0x3c , oled_init , LENGTH ( oled_init ) , NULL , 0 ) ;
const uint8_t oled_entire_display_on [ ] = {
0x80 , // control byte: no continuation, command
0xa5 // Entire Display ON: Entire display ON Output ignores RAM content
} ;
i2c_master_write ( 0x3c , oled_entire_display_on , LENGTH ( oled_entire_display_on ) , NULL , 0 ) ;
const uint8_t oled_display_on [ ] = {
0x80 , // control byte: no continuation, command
0xaf , // Set Display ON/OFF: ON
} ;
i2c_master_write ( 0x3c , oled_display_on , LENGTH ( oled_display_on ) , NULL , 0 ) ;
sleep_ms ( 200 ) ;
const uint8_t oled_entire_display_ram [ ] = {
0x80 , // control byte: no continuation, command
0xa4 // Entire Display ON: Resume to RAM content display
} ;
i2c_master_write ( 0x3c , oled_entire_display_ram , LENGTH ( oled_entire_display_ram ) , NULL , 0 ) ;
const uint8_t oled_start_page [ ] = {
0x00 , // control byte: continuous (multiple byes), command
0xb0 , // Set Page Start Address for Page Addressing Mode: PAGE0
0x00 , // Set Lower Column Start Address for Page Addressing Mode: 0
0x10 // Set Higher Column Start Address for Page Addressing Mode: 0
} ;
i2c_master_write ( 0x3c , oled_start_page , LENGTH ( oled_start_page ) , NULL , 0 ) ;
const uint8_t oled_data [ ] = { 0x40 , 0 , 254 , 254 , 0 , 0 , 0 , 0 , 0 , 0 , 254 , 254 , 0 , 0 , 224 , 240 , 56 , 28 , 14 , 14 , 28 , 56 , 240 , 224 , 0 , 0 , 254 , 254 , 134 , 134 , 134 , 134 , 134 , 206 , 252 , 120 , 0 , 0 , 6 , 6 , 6 , 6 , 254 , 254 , 6 , 6 , 6 , 6 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 6 , 6 , 6 , 6 , 254 , 254 , 6 , 6 , 6 , 6 , 0 , 0 , 30 , 62 , 112 , 224 , 192 , 192 , 224 , 112 , 62 , 30 , 0 , 0 , 254 , 254 , 134 , 134 , 134 , 134 , 134 , 206 , 252 , 120 , 0 , 0 , 30 , 62 , 112 , 224 , 192 , 192 , 224 , 112 , 62 , 30 , 0 , 0 , 31 , 63 , 112 , 96 , 96 , 96 , 96 , 112 , 63 , 31 , 0 , 0 , 127 , 127 , 6 , 6 , 6 , 6 , 6 , 6 , 127 , 127 , 0 , 0 , 127 , 127 , 1 , 3 , 7 , 15 , 29 , 57 , 112 , 96 , 0 , 0 , 0 , 0 , 0 , 0 , 127 , 127 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 127 , 127 , 0 , 0 , 0 , 0 , 0 , 0 , 120 , 124 , 14 , 7 , 3 , 3 , 7 , 14 , 124 , 120 , 0 , 0 , 127 , 127 , 1 , 3 , 7 , 15 , 29 , 57 , 112 , 96 , 0 , 0 , 120 , 124 , 14 , 7 , 3 , 3 , 7 , 14 , 124 , 120 , 0 , 255 , 255 , 3 , 3 , 3 , 3 , 11 , 19 , 35 , 67 , 131 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 131 , 67 , 35 , 19 , 11 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 255 , 255 , 255 , 255 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 132 , 72 , 48 , 48 , 72 , 132 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 17 , 17 , 49 , 209 , 14 , 0 , 0 , 1 , 1 , 1 , 255 , 1 , 1 , 1 , 0 , 142 , 17 , 17 , 33 , 33 , 198 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 17 , 17 , 49 , 209 , 14 , 0 , 0 , 3 , 204 , 48 , 48 , 204 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 134 , 1 , 17 , 17 , 17 , 238 , 0 , 0 , 7 , 56 , 192 , 0 , 192 , 56 , 7 , 0 , 134 , 1 , 17 , 17 , 17 , 238 , 0 , 0 , 254 , 1 , 1 , 33 , 33 , 230 , 0 , 0 , 255 , 6 , 24 , 96 , 128 , 255 , 0 , 0 , 255 , 1 , 1 , 1 , 2 , 252 , 0 , 0 , 0 , 255 , 255 , 255 , 255 , 0 , 0 , 0 , 0 , 64 , 32 , 16 , 8 , 4 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 4 , 8 , 16 , 32 , 64 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 1 , 2 , 2 , 2 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 2 , 2 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 1 , 2 , 2 , 2 , 2 , 1 , 0 , 0 , 1 , 2 , 2 , 2 , 1 , 3 , 0 , 0 , 3 , 0 , 0 , 0 , 1 , 3 , 0 , 0 , 3 , 2 , 2 , 2 , 1 , 0 , 0 , 0 , 0 , 255 , 255 , 255 , 255 , 0 , 0 , 0 , 0 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 0 , 0 , 0 , 0 , 0 , 0 , 128 , 64 , 32 , 16 , 8 , 4 , 2 , 0 , 0 , 0 , 128 , 64 , 64 , 64 , 64 , 128 , 0 , 0 , 64 , 64 , 64 , 192 , 64 , 64 , 64 , 0 , 128 , 64 , 64 , 64 , 64 , 128 , 0 , 0 , 0 , 0 , 0 , 0 , 64 , 64 , 64 , 192 , 64 , 64 , 64 , 0 , 192 , 0 , 0 , 0 , 0 , 192 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 192 , 0 , 0 , 0 , 0 , 0 , 192 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 192 , 64 , 64 , 64 , 64 , 64 , 0 , 0 , 192 , 0 , 0 , 0 , 0 , 0 , 192 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 255 , 255 , 255 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 128 , 64 , 33 , 18 , 12 , 12 , 18 , 33 , 64 , 128 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 127 , 128 , 128 , 128 , 128 , 97 , 0 , 0 , 0 , 0 , 0 , 255 , 0 , 0 , 0 , 0 , 99 , 132 , 132 , 136 , 136 , 113 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 0 , 0 , 0 , 0 , 192 , 51 , 12 , 12 , 51 , 192 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 195 , 36 , 24 , 24 , 36 , 195 , 0 , 0 , 1 , 14 , 48 , 192 , 48 , 14 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 71 , 132 , 132 , 132 , 132 , 120 , 0 , 0 , 1 , 14 , 48 , 192 , 48 , 14 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 255 , 255 , 255 , 192 , 192 , 192 , 192 , 208 , 200 , 196 , 194 , 193 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 193 , 194 , 196 , 200 , 208 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 192 , 255 , 255 } ;
i2c_master_write ( 0x3c , oled_data , LENGTH ( oled_data ) , NULL , 0 ) ;
*/
2018-01-14 13:49:16 +01:00
if ( false ) {
2017-12-12 13:56:28 +01:00
// perform tests
2017-12-22 17:25:05 +01:00
printf ( " performing self-test, please follow instructions \n " ) ;
2017-12-12 13:56:28 +01:00
if ( ! test_self ( ) ) { // perform self-test
led_blink ( 0.5 , 0.5 ) ; // show error on LEDs
} else {
2017-12-22 17:25:05 +01:00
led_blink ( 0 , 1.0 ) ; // show blue OK LED
2017-12-12 13:56:28 +01:00
printf ( " self-test succeeded \n " ) ; // notify user
}
2017-12-22 17:25:05 +01:00
printf ( " performing pin test, please follow instructions \n " ) ;
if ( ! test_pins ( ) ) { // perform external test
led_blink ( 0.5 , 0.5 ) ; // show error on LEDs
} else {
led_blink ( 0 , 1.0 ) ; // show blue OK LED
printf ( " pin test succeeded \n " ) ; // notify user
}
2018-01-14 13:49:16 +01:00
}
2017-12-22 17:25:05 +01:00
2017-12-15 19:10:56 +01:00
/*
printf ( " testing RS-485 port \n " ) ;
rs485_setup ( ) ;
*/
2017-12-12 13:56:28 +01:00
2017-12-15 19:10:56 +01:00
/*
printf ( " testing RS-232 port \n " ) ;
rs232_setup ( ) ;
*/
2017-12-22 17:25:05 +01:00
/*
// test CAN
gpio_clear ( GPIOC , GPIO13 ) ;
gpio_set_mode ( GPIOC , GPIO_MODE_OUTPUT_2_MHZ , GPIO_CNF_OUTPUT_OPENDRAIN , GPIO13 ) ;
gpio_set ( GPIOB , GPIO9 ) ;
gpio_set_mode ( GPIOB , GPIO_MODE_OUTPUT_2_MHZ , GPIO_CNF_OUTPUT_OPENDRAIN , GPIO9 ) ; // CAN TX
gpio_set_mode ( GPIOB , GPIO_MODE_INPUT , GPIO_CNF_INPUT_FLOAT , GPIO8 ) ; // CAN RX
gpio_clear ( GPIOC , GPIO7 ) ;
gpio_set_mode ( GPIOC , GPIO_MODE_OUTPUT_2_MHZ , GPIO_CNF_OUTPUT_OPENDRAIN , GPIO7 ) ; // CAN EN
while ( true ) {
gpio_toggle ( GPIOB , GPIO9 ) ;
sleep_ms ( 100 ) ;
}
wait_space ( ) ;
*/
2016-08-14 21:02:38 +02:00
// main loop
printf ( " command input: ready \n " ) ;
2018-01-14 13:49:16 +01:00
terminal_prefix = " BV: " ; // set terminal prefix
terminal_process = & process_command ;
terminal_setup ( ) ; // start terminal
2016-02-18 10:39:08 +01:00
bool action = false ; // if an action has been performed don't go to sleep
button_flag = false ; // reset button flag
2016-10-23 17:42:27 +02:00
char c = ' \0 ' ; // to store received character
2016-08-14 21:02:38 +02:00
bool char_flag = false ; // a new character has been received
2016-01-29 00:24:49 +01:00
while ( true ) { // infinite loop
2016-10-23 17:42:27 +02:00
iwdg_reset ( ) ; // kick the dog
2017-12-16 13:37:35 +01:00
while ( uart_received ) { // data received over UART
2016-02-18 10:39:08 +01:00
action = true ; // action has been performed
2016-01-29 00:24:49 +01:00
led_toggle ( ) ; // toggle LED
2017-12-16 13:37:35 +01:00
c = uart_getchar ( ) ; // store receive character
2016-08-14 21:02:38 +02:00
char_flag = true ; // notify character has been received
2016-01-17 15:03:10 +01:00
}
2017-04-19 16:24:07 +02:00
while ( usb_cdcacm_received ) { // data received over USB
2016-02-18 10:39:08 +01:00
action = true ; // action has been performed
2016-01-29 00:24:49 +01:00
led_toggle ( ) ; // toggle LED
2017-04-19 16:24:07 +02:00
c = usb_cdcacm_getchar ( ) ; // store receive character
2016-08-14 21:02:38 +02:00
char_flag = true ; // notify character has been received
2016-01-18 16:23:35 +01:00
}
2016-08-14 21:02:38 +02:00
while ( char_flag ) { // user data received
char_flag = false ; // reset flag
2016-02-18 10:39:08 +01:00
action = true ; // action has been performed
2018-01-14 13:49:16 +01:00
// printf("%02x\n", c);
terminal_send ( c ) ; // send received character to terminal
2016-08-14 21:02:38 +02:00
}
while ( button_flag ) { // user pressed button
action = true ; // action has been performed
printf ( " button pressed \n " ) ;
2016-02-18 10:39:08 +01:00
led_toggle ( ) ; // toggle LED
2016-08-14 21:02:38 +02:00
for ( uint32_t i = 0 ; i < 1000000 ; i + + ) { // wait a bit to remove noise and double trigger
__asm__ ( " nop " ) ;
}
button_flag = false ; // reset flag
2016-02-18 10:39:08 +01:00
}
2016-08-14 21:02:38 +02:00
if ( action ) { // go to sleep if nothing had to be done, else recheck for activity
2016-02-18 10:39:08 +01:00
action = false ;
} else {
__WFI ( ) ; // go to sleep
}
2016-10-23 17:42:27 +02:00
} // main loop
2016-01-17 14:54:54 +01:00
}