uint8_t car_harness_status = 0U ;
# define HARNESS_STATUS_NC 0U
# define HARNESS_STATUS_NORMAL 1U
# define HARNESS_STATUS_FLIPPED 2U
// Threshold voltage (mV) for either of the SBUs to be below before deciding harness is connected
# define HARNESS_CONNECTED_THRESHOLD 2500U
struct harness_configuration {
const bool has_harness ;
GPIO_TypeDef * GPIO_SBU1 ;
GPIO_TypeDef * GPIO_SBU2 ;
GPIO_TypeDef * GPIO_relay_normal ;
GPIO_TypeDef * GPIO_relay_flipped ;
uint8_t pin_SBU1 ;
uint8_t pin_SBU2 ;
uint8_t pin_relay_normal ;
uint8_t pin_relay_flipped ;
uint8_t adc_channel_SBU1 ;
uint8_t adc_channel_SBU2 ;
} ;
// this function will be the API for tici
void set_intercept_relay ( bool intercept ) {
if ( car_harness_status ! = HARNESS_STATUS_NC ) {
if ( intercept ) {
puts ( " switching harness to intercept (relay on) \n " ) ;
} else {
puts ( " switching harness to passthrough (relay off) \n " ) ;
}
if ( car_harness_status = = HARNESS_STATUS_NORMAL ) {
set_gpio_output ( current_board - > harness_config - > GPIO_relay_normal , current_board - > harness_config - > pin_relay_normal , ! intercept ) ;
} else {
set_gpio_output ( current_board - > harness_config - > GPIO_relay_flipped , current_board - > harness_config - > pin_relay_flipped , ! intercept ) ;
}
}
}
bool harness_check_ignition ( void ) {
bool ret = false ;
switch ( car_harness_status ) {
case HARNESS_STATUS_NORMAL :
ret = ! get_gpio_input ( current_board - > harness_config - > GPIO_SBU2 , current_board - > harness_config - > pin_SBU2 ) ;
break ;
case HARNESS_STATUS_FLIPPED :
ret = ! get_gpio_input ( current_board - > harness_config - > GPIO_SBU1 , current_board - > harness_config - > pin_SBU1 ) ;
break ;
default :
break ;
}
return ret ;
}
uint8_t harness_detect_orientation ( void ) {
uint8_t ret = HARNESS_STATUS_NC ;
# ifndef BOOTSTUB
uint32_t sbu1_voltage = adc_get ( current_board - > harness_config - > adc_channel_SBU1 ) ;
uint32_t sbu2_voltage = adc_get ( current_board - > harness_config - > adc_channel_SBU2 ) ;
// Detect connection and orientation
if ( ( sbu1_voltage < HARNESS_CONNECTED_THRESHOLD ) | | ( sbu2_voltage < HARNESS_CONNECTED_THRESHOLD ) ) {
if ( sbu1_voltage < sbu2_voltage ) {
// orientation normal
ret = HARNESS_STATUS_NORMAL ;
} else {
// orientation flipped
ret = HARNESS_STATUS_FLIPPED ;
}
}
# endif
return ret ;
}
void harness_init ( void ) {
// delay such that the connection is fully made before trying orientation detection
current_board - > set_led ( LED_BLUE , true ) ;
delay ( 10000000 ) ;
current_board - > set_led ( LED_BLUE , false ) ;
// try to detect orientation
uint8_t ret = harness_detect_orientation ( ) ;
if ( ret ! = HARNESS_STATUS_NC ) {
puts ( " detected car harness with orientation " ) ; puth2 ( ret ) ; puts ( " \n " ) ;
car_harness_status = ret ;
// set the SBU lines to be inputs before using the relay. The lines are not 5V tolerant in ADC mode!
set_gpio_mode ( current_board - > harness_config - > GPIO_SBU1 , current_board - > harness_config - > pin_SBU1 , MODE_INPUT ) ;
set_gpio_mode ( current_board - > harness_config - > GPIO_SBU2 , current_board - > harness_config - > pin_SBU2 , MODE_INPUT ) ;
// now we have orientation, set pin ignition detection
if ( car_harness_status = = HARNESS_STATUS_NORMAL ) {
set_gpio_mode ( current_board - > harness_config - > GPIO_SBU2 , current_board - > harness_config - > pin_SBU2 , MODE_INPUT ) ;
} else {
set_gpio_mode ( current_board - > harness_config - > GPIO_SBU1 , current_board - > harness_config - > pin_SBU1 , MODE_INPUT ) ;
}
// keep busses connected by default
set_intercept_relay ( false ) ;
} else {
puts ( " failed to detect car harness! \n " ) ;
}
}