extern int _app_start [ 0xc000 ] ; // Only first 3 sectors of size 0x4000 are used
bool generated_can_traffic = false ;
int get_jungle_health_pkt ( void * dat ) {
COMPILE_TIME_ASSERT ( sizeof ( struct jungle_health_t ) < = USBPACKET_MAX_SIZE ) ;
struct jungle_health_t * health = ( struct jungle_health_t * ) dat ;
health - > uptime_pkt = uptime_cnt ;
health - > ch1_power = current_board - > get_channel_power ( 1U ) ;
health - > ch2_power = current_board - > get_channel_power ( 2U ) ;
health - > ch3_power = current_board - > get_channel_power ( 3U ) ;
health - > ch4_power = current_board - > get_channel_power ( 4U ) ;
health - > ch5_power = current_board - > get_channel_power ( 5U ) ;
health - > ch6_power = current_board - > get_channel_power ( 6U ) ;
health - > ch1_sbu1_mV = current_board - > get_sbu_mV ( 1U , SBU1 ) ;
health - > ch1_sbu2_mV = current_board - > get_sbu_mV ( 1U , SBU2 ) ;
health - > ch2_sbu1_mV = current_board - > get_sbu_mV ( 2U , SBU1 ) ;
health - > ch2_sbu2_mV = current_board - > get_sbu_mV ( 2U , SBU2 ) ;
health - > ch3_sbu1_mV = current_board - > get_sbu_mV ( 3U , SBU1 ) ;
health - > ch3_sbu2_mV = current_board - > get_sbu_mV ( 3U , SBU2 ) ;
health - > ch4_sbu1_mV = current_board - > get_sbu_mV ( 4U , SBU1 ) ;
health - > ch4_sbu2_mV = current_board - > get_sbu_mV ( 4U , SBU2 ) ;
health - > ch5_sbu1_mV = current_board - > get_sbu_mV ( 5U , SBU1 ) ;
health - > ch5_sbu2_mV = current_board - > get_sbu_mV ( 5U , SBU2 ) ;
health - > ch6_sbu1_mV = current_board - > get_sbu_mV ( 6U , SBU1 ) ;
health - > ch6_sbu2_mV = current_board - > get_sbu_mV ( 6U , SBU2 ) ;
return sizeof ( * health ) ;
}
// send on serial, first byte to select the ring
void comms_endpoint2_write ( const uint8_t * data , uint32_t len ) {
UNUSED ( data ) ;
UNUSED ( len ) ;
}
int comms_control_handler ( ControlPacket_t * req , uint8_t * resp ) {
unsigned int resp_len = 0 ;
uint32_t time ;
# ifdef DEBUG_COMMS
print ( " raw control request: " ) ; hexdump ( req , sizeof ( ControlPacket_t ) ) ; print ( " \n " ) ;
print ( " - request " ) ; puth ( req - > request ) ; print ( " \n " ) ;
print ( " - param1 " ) ; puth ( req - > param1 ) ; print ( " \n " ) ;
print ( " - param2 " ) ; puth ( req - > param2 ) ; print ( " \n " ) ;
# endif
switch ( req - > request ) {
// **** 0xa0: Set panda power.
case 0xa0 :
current_board - > set_panda_power ( ( req - > param1 = = 1U ) ) ;
break ;
// **** 0xa1: Set harness orientation.
case 0xa1 :
current_board - > set_harness_orientation ( req - > param1 ) ;
break ;
// **** 0xa2: Set ignition.
case 0xa2 :
current_board - > set_ignition ( ( req - > param1 = = 1U ) ) ;
break ;
// **** 0xa3: Set panda power per channel by bitmask.
case 0xa3 :
current_board - > set_panda_individual_power ( req - > param1 , ( req - > param2 > 0U ) ) ;
break ;
// **** 0xa4: Enable generated CAN traffic.
case 0xa4 :
generated_can_traffic = ( req - > param1 > 0U ) ;
break ;
// **** 0xa8: get microsecond timer
case 0xa8 :
time = microsecond_timer_get ( ) ;
resp [ 0 ] = ( time & 0x000000FFU ) ;
resp [ 1 ] = ( ( time & 0x0000FF00U ) > > 8U ) ;
resp [ 2 ] = ( ( time & 0x00FF0000U ) > > 16U ) ;
resp [ 3 ] = ( ( time & 0xFF000000U ) > > 24U ) ;
resp_len = 4U ;
break ;
// **** 0xc0: reset communications
case 0xc0 :
comms_can_reset ( ) ;
break ;
// **** 0xc1: get hardware type
case 0xc1 :
resp [ 0 ] = hw_type ;
resp_len = 1 ;
break ;
// **** 0xc2: CAN health stats
case 0xc2 :
COMPILE_TIME_ASSERT ( sizeof ( can_health_t ) < = USBPACKET_MAX_SIZE ) ;
if ( req - > param1 < 3U ) {
update_can_health_pkt ( req - > param1 , 0U ) ;
can_health [ req - > param1 ] . can_speed = ( bus_config [ req - > param1 ] . can_speed / 10U ) ;
can_health [ req - > param1 ] . can_data_speed = ( bus_config [ req - > param1 ] . can_data_speed / 10U ) ;
can_health [ req - > param1 ] . canfd_enabled = bus_config [ req - > param1 ] . canfd_enabled ;
can_health [ req - > param1 ] . brs_enabled = bus_config [ req - > param1 ] . brs_enabled ;
can_health [ req - > param1 ] . canfd_non_iso = bus_config [ req - > param1 ] . canfd_non_iso ;
resp_len = sizeof ( can_health [ req - > param1 ] ) ;
( void ) memcpy ( resp , & can_health [ req - > param1 ] , resp_len ) ;
}
break ;
// **** 0xc3: fetch MCU UID
case 0xc3 :
( void ) memcpy ( resp , ( ( uint8_t * ) UID_BASE ) , 12 ) ;
resp_len = 12 ;
break ;
// **** 0xd0: fetch serial (aka the provisioned dongle ID)
case 0xd0 :
// addresses are OTP
if ( req - > param1 = = 1U ) {
( void ) memcpy ( resp , ( uint8_t * ) DEVICE_SERIAL_NUMBER_ADDRESS , 0x10 ) ;
resp_len = 0x10 ;
} else {
get_provision_chunk ( resp ) ;
resp_len = PROVISION_CHUNK_LEN ;
}
break ;
// **** 0xd1: enter bootloader mode
case 0xd1 :
// this allows reflashing of the bootstub
switch ( req - > param1 ) {
case 0 :
// only allow bootloader entry on debug builds
# ifdef ALLOW_DEBUG
print ( " -> entering bootloader \n " ) ;
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC ;
NVIC_SystemReset ( ) ;
# endif
break ;
case 1 :
print ( " -> entering softloader \n " ) ;
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC ;
NVIC_SystemReset ( ) ;
break ;
default :
print ( " Bootloader mode invalid \n " ) ;
break ;
}
break ;
// **** 0xd2: get health packet
case 0xd2 :
resp_len = get_jungle_health_pkt ( resp ) ;
break ;
// **** 0xd3: get first 64 bytes of signature
case 0xd3 :
{
resp_len = 64 ;
char * code = ( char * ) _app_start ;
int code_len = _app_start [ 0 ] ;
( void ) memcpy ( resp , & code [ code_len ] , resp_len ) ;
}
break ;
// **** 0xd4: get second 64 bytes of signature
case 0xd4 :
{
resp_len = 64 ;
char * code = ( char * ) _app_start ;
int code_len = _app_start [ 0 ] ;
( void ) memcpy ( resp , & code [ code_len + 64 ] , resp_len ) ;
}
break ;
// **** 0xd6: get version
case 0xd6 :
COMPILE_TIME_ASSERT ( sizeof ( gitversion ) < = USBPACKET_MAX_SIZE ) ;
( void ) memcpy ( resp , gitversion , sizeof ( gitversion ) ) ;
resp_len = sizeof ( gitversion ) - 1U ;
break ;
// **** 0xd8: reset ST
case 0xd8 :
NVIC_SystemReset ( ) ;
break ;
// **** 0xdb: set OBD CAN multiplexing mode
case 0xdb :
if ( req - > param1 = = 1U ) {
// Enable OBD CAN
current_board - > set_can_mode ( CAN_MODE_OBD_CAN2 ) ;
} else {
// Disable OBD CAN
current_board - > set_can_mode ( CAN_MODE_NORMAL ) ;
}
break ;
// **** 0xdd: get healthpacket and CANPacket versions
case 0xdd :
resp [ 0 ] = JUNGLE_HEALTH_PACKET_VERSION ;
resp [ 1 ] = CAN_PACKET_VERSION ;
resp [ 2 ] = CAN_HEALTH_PACKET_VERSION ;
resp_len = 3 ;
break ;
// **** 0xde: set can bitrate
case 0xde :
if ( ( req - > param1 < PANDA_BUS_CNT ) & & is_speed_valid ( req - > param2 , speeds , sizeof ( speeds ) / sizeof ( speeds [ 0 ] ) ) ) {
bus_config [ req - > param1 ] . can_speed = req - > param2 ;
bool ret = can_init ( CAN_NUM_FROM_BUS_NUM ( req - > param1 ) ) ;
UNUSED ( ret ) ;
}
break ;
// **** 0xe0: debug read
case 0xe0 :
// read
while ( ( resp_len < MIN ( req - > length , USBPACKET_MAX_SIZE ) ) & & get_char ( get_ring_by_number ( 0 ) , ( char * ) & resp [ resp_len ] ) ) {
+ + resp_len ;
}
break ;
// **** 0xe5: set CAN loopback (for testing)
case 0xe5 :
can_loopback = ( req - > param1 > 0U ) ;
can_init_all ( ) ;
break ;
// **** 0xf1: Clear CAN ring buffer.
case 0xf1 :
if ( req - > param1 = = 0xFFFFU ) {
print ( " Clearing CAN Rx queue \n " ) ;
can_clear ( & can_rx_q ) ;
} else if ( req - > param1 < PANDA_BUS_CNT ) {
print ( " Clearing CAN Tx queue \n " ) ;
can_clear ( can_queues [ req - > param1 ] ) ;
} else {
print ( " Clearing CAN CAN ring buffer failed: wrong bus number \n " ) ;
}
break ;
// **** 0xf2: Clear debug ring buffer.
case 0xf2 :
print ( " Clearing debug queue. \n " ) ;
clear_uart_buff ( get_ring_by_number ( 0 ) ) ;
break ;
// **** 0xf4: Set CAN transceiver enable pin
case 0xf4 :
current_board - > enable_can_transceiver ( req - > param1 , req - > param2 > 0U ) ;
break ;
// **** 0xf5: Set CAN silent mode
case 0xf5 :
can_silent = ( req - > param1 > 0U ) ? ALL_CAN_SILENT : ALL_CAN_LIVE ;
can_init_all ( ) ;
break ;
// **** 0xf7: enable/disable header pin by number
case 0xf7 :
current_board - > enable_header_pin ( req - > param1 , req - > param2 > 0U ) ;
break ;
// **** 0xf9: set CAN FD data bitrate
case 0xf9 :
if ( ( req - > param1 < PANDA_CAN_CNT ) & &
current_board - > has_canfd & &
is_speed_valid ( req - > param2 , data_speeds , sizeof ( data_speeds ) / sizeof ( data_speeds [ 0 ] ) ) ) {
bus_config [ req - > param1 ] . can_data_speed = req - > param2 ;
bus_config [ req - > param1 ] . canfd_enabled = ( req - > param2 > = bus_config [ req - > param1 ] . can_speed ) ;
bus_config [ req - > param1 ] . brs_enabled = ( req - > param2 > bus_config [ req - > param1 ] . can_speed ) ;
bool ret = can_init ( CAN_NUM_FROM_BUS_NUM ( req - > param1 ) ) ;
UNUSED ( ret ) ;
}
break ;
// **** 0xfc: set CAN FD non-ISO mode
case 0xfc :
if ( ( req - > param1 < PANDA_CAN_CNT ) & & current_board - > has_canfd ) {
bus_config [ req - > param1 ] . canfd_non_iso = ( req - > param2 ! = 0U ) ;
bool ret = can_init ( CAN_NUM_FROM_BUS_NUM ( req - > param1 ) ) ;
UNUSED ( ret ) ;
}
break ;
default :
print ( " NO HANDLER " ) ;
puth ( req - > request ) ;
print ( " \n " ) ;
break ;
}
return resp_len ;
}