Compile FrogPilot

This commit is contained in:
FrogAi
2024-03-10 20:59:55 -07:00
parent 69e7feaf01
commit f1acd339d7
1485 changed files with 426154 additions and 398339 deletions

View File

@@ -1,18 +0,0 @@
import os
import copy
Import('build_project', 'base_project_f4', 'base_project_h7')
build_projects = {
"panda_jungle": base_project_f4,
"panda_jungle_h7": base_project_h7,
}
for project_name, project in build_projects.items():
flags = [
"-DPANDA_JUNGLE",
]
if os.getenv("FINAL_PROVISIONING"):
flags += ["-DFINAL_PROVISIONING"]
build_project(project_name, project, flags)

View File

@@ -1,82 +0,0 @@
// ******************** Prototypes ********************
typedef void (*board_init)(void);
typedef void (*board_set_led)(uint8_t color, bool enabled);
typedef void (*board_board_tick)(void);
typedef bool (*board_get_button)(void);
typedef void (*board_set_panda_power)(bool enabled);
typedef void (*board_set_panda_individual_power)(uint8_t port_num, bool enabled);
typedef void (*board_set_ignition)(bool enabled);
typedef void (*board_set_individual_ignition)(uint8_t bitmask);
typedef void (*board_set_harness_orientation)(uint8_t orientation);
typedef void (*board_set_can_mode)(uint8_t mode);
typedef void (*board_enable_can_transciever)(uint8_t transciever, bool enabled);
typedef void (*board_enable_header_pin)(uint8_t pin_num, bool enabled);
typedef float (*board_get_channel_power)(uint8_t channel);
typedef uint16_t (*board_get_sbu_mV)(uint8_t channel, uint8_t sbu);
struct board {
const bool has_canfd;
const bool has_sbu_sense;
const uint16_t avdd_mV;
board_init init;
board_set_led set_led;
board_board_tick board_tick;
board_get_button get_button;
board_set_panda_power set_panda_power;
board_set_panda_individual_power set_panda_individual_power;
board_set_ignition set_ignition;
board_set_individual_ignition set_individual_ignition;
board_set_harness_orientation set_harness_orientation;
board_set_can_mode set_can_mode;
board_enable_can_transciever enable_can_transciever;
board_enable_header_pin enable_header_pin;
board_get_channel_power get_channel_power;
board_get_sbu_mV get_sbu_mV;
// TODO: shouldn't need these
bool has_spi;
};
// ******************* Definitions ********************
#define HW_TYPE_UNKNOWN 0U
#define HW_TYPE_V1 1U
#define HW_TYPE_V2 2U
// LED colors
#define LED_RED 0U
#define LED_GREEN 1U
#define LED_BLUE 2U
// CAN modes
#define CAN_MODE_NORMAL 0U
#define CAN_MODE_GMLAN_CAN2 1U
#define CAN_MODE_GMLAN_CAN3 2U
#define CAN_MODE_OBD_CAN2 3U
// Harness states
#define HARNESS_ORIENTATION_NONE 0U
#define HARNESS_ORIENTATION_1 1U
#define HARNESS_ORIENTATION_2 2U
#define SBU1 0U
#define SBU2 1U
// ********************* Globals **********************
uint8_t harness_orientation = HARNESS_ORIENTATION_NONE;
uint8_t can_mode = CAN_MODE_NORMAL;
uint8_t ignition = 0U;
void unused_set_individual_ignition(uint8_t bitmask) {
UNUSED(bitmask);
}
void unused_board_enable_header_pin(uint8_t pin_num, bool enabled) {
UNUSED(pin_num);
UNUSED(enabled);
}
void unused_set_panda_individual_power(uint8_t port_num, bool enabled) {
UNUSED(port_num);
UNUSED(enabled);
}

View File

@@ -1,178 +0,0 @@
// ///////////////////////// //
// Jungle board v1 (STM32F4) //
// ///////////////////////// //
void board_v1_set_led(uint8_t color, bool enabled) {
switch (color) {
case LED_RED:
set_gpio_output(GPIOC, 9, !enabled);
break;
case LED_GREEN:
set_gpio_output(GPIOC, 7, !enabled);
break;
case LED_BLUE:
set_gpio_output(GPIOC, 6, !enabled);
break;
default:
break;
}
}
void board_v1_enable_can_transciever(uint8_t transciever, bool enabled) {
switch (transciever) {
case 1U:
set_gpio_output(GPIOC, 1, !enabled);
break;
case 2U:
set_gpio_output(GPIOC, 13, !enabled);
break;
case 3U:
set_gpio_output(GPIOA, 0, !enabled);
break;
case 4U:
set_gpio_output(GPIOB, 10, !enabled);
break;
default:
print("Invalid CAN transciever ("); puth(transciever); print("): enabling failed\n");
break;
}
}
void board_v1_set_can_mode(uint8_t mode) {
board_v1_enable_can_transciever(2U, false);
board_v1_enable_can_transciever(4U, false);
switch (mode) {
case CAN_MODE_NORMAL:
print("Setting normal CAN mode\n");
// B12,B13: disable OBD mode
set_gpio_mode(GPIOB, 12, MODE_INPUT);
set_gpio_mode(GPIOB, 13, MODE_INPUT);
// B5,B6: normal CAN2 mode
set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2);
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
can_mode = CAN_MODE_NORMAL;
board_v1_enable_can_transciever(2U, true);
break;
case CAN_MODE_OBD_CAN2:
print("Setting OBD CAN mode\n");
// B5,B6: disable normal CAN2 mode
set_gpio_mode(GPIOB, 5, MODE_INPUT);
set_gpio_mode(GPIOB, 6, MODE_INPUT);
// B12,B13: OBD mode
set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2);
set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2);
can_mode = CAN_MODE_OBD_CAN2;
board_v1_enable_can_transciever(4U, true);
break;
default:
print("Tried to set unsupported CAN mode: "); puth(mode); print("\n");
break;
}
}
void board_v1_set_harness_orientation(uint8_t orientation) {
switch (orientation) {
case HARNESS_ORIENTATION_NONE:
set_gpio_output(GPIOA, 2, false);
set_gpio_output(GPIOA, 3, false);
set_gpio_output(GPIOA, 4, false);
set_gpio_output(GPIOA, 5, false);
harness_orientation = orientation;
break;
case HARNESS_ORIENTATION_1:
set_gpio_output(GPIOA, 2, false);
set_gpio_output(GPIOA, 3, (ignition != 0U));
set_gpio_output(GPIOA, 4, true);
set_gpio_output(GPIOA, 5, false);
harness_orientation = orientation;
break;
case HARNESS_ORIENTATION_2:
set_gpio_output(GPIOA, 2, (ignition != 0U));
set_gpio_output(GPIOA, 3, false);
set_gpio_output(GPIOA, 4, false);
set_gpio_output(GPIOA, 5, true);
harness_orientation = orientation;
break;
default:
print("Tried to set an unsupported harness orientation: "); puth(orientation); print("\n");
break;
}
}
bool panda_power = false;
void board_v1_set_panda_power(bool enable) {
panda_power = enable;
set_gpio_output(GPIOB, 14, enable);
}
bool board_v1_get_button(void) {
return get_gpio_input(GPIOC, 8);
}
void board_v1_set_ignition(bool enabled) {
ignition = enabled ? 0xFFU : 0U;
board_v1_set_harness_orientation(harness_orientation);
}
float board_v1_get_channel_power(uint8_t channel) {
UNUSED(channel);
return 0.0f;
}
uint16_t board_v1_get_sbu_mV(uint8_t channel, uint8_t sbu) {
UNUSED(channel); UNUSED(sbu);
return 0U;
}
void board_v1_init(void) {
common_init_gpio();
// A8,A15: normal CAN3 mode
set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3);
set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3);
board_v1_set_can_mode(CAN_MODE_NORMAL);
// Enable CAN transcievers
for(uint8_t i = 1; i <= 4; i++) {
board_v1_enable_can_transciever(i, true);
}
// Disable LEDs
board_v1_set_led(LED_RED, false);
board_v1_set_led(LED_GREEN, false);
board_v1_set_led(LED_BLUE, false);
// Set normal CAN mode
board_v1_set_can_mode(CAN_MODE_NORMAL);
// Set to no harness orientation
board_v1_set_harness_orientation(HARNESS_ORIENTATION_NONE);
// Enable panda power by default
board_v1_set_panda_power(true);
}
void board_v1_tick(void) {}
const board board_v1 = {
.has_canfd = false,
.has_sbu_sense = false,
.avdd_mV = 3300U,
.init = &board_v1_init,
.set_led = &board_v1_set_led,
.board_tick = &board_v1_tick,
.get_button = &board_v1_get_button,
.set_panda_power = &board_v1_set_panda_power,
.set_panda_individual_power = &unused_set_panda_individual_power,
.set_ignition = &board_v1_set_ignition,
.set_individual_ignition = &unused_set_individual_ignition,
.set_harness_orientation = &board_v1_set_harness_orientation,
.set_can_mode = &board_v1_set_can_mode,
.enable_can_transciever = &board_v1_enable_can_transciever,
.enable_header_pin = &unused_board_enable_header_pin,
.get_channel_power = &board_v1_get_channel_power,
.get_sbu_mV = &board_v1_get_sbu_mV,
};

View File

@@ -1,328 +0,0 @@
// ///////////////////////// //
// Jungle board v2 (STM32H7) //
// ///////////////////////// //
const gpio_t power_pins[] = {
{.bank = GPIOA, .pin = 0},
{.bank = GPIOA, .pin = 1},
{.bank = GPIOF, .pin = 12},
{.bank = GPIOA, .pin = 5},
{.bank = GPIOC, .pin = 5},
{.bank = GPIOB, .pin = 2},
};
const gpio_t sbu1_ignition_pins[] = {
{.bank = GPIOD, .pin = 0},
{.bank = GPIOD, .pin = 5},
{.bank = GPIOD, .pin = 12},
{.bank = GPIOD, .pin = 14},
{.bank = GPIOE, .pin = 5},
{.bank = GPIOE, .pin = 9},
};
const gpio_t sbu1_relay_pins[] = {
{.bank = GPIOD, .pin = 1},
{.bank = GPIOD, .pin = 6},
{.bank = GPIOD, .pin = 11},
{.bank = GPIOD, .pin = 15},
{.bank = GPIOE, .pin = 6},
{.bank = GPIOE, .pin = 10},
};
const gpio_t sbu2_ignition_pins[] = {
{.bank = GPIOD, .pin = 3},
{.bank = GPIOD, .pin = 8},
{.bank = GPIOD, .pin = 9},
{.bank = GPIOE, .pin = 0},
{.bank = GPIOE, .pin = 7},
{.bank = GPIOE, .pin = 11},
};
const gpio_t sbu2_relay_pins[] = {
{.bank = GPIOD, .pin = 4},
{.bank = GPIOD, .pin = 10},
{.bank = GPIOD, .pin = 13},
{.bank = GPIOE, .pin = 1},
{.bank = GPIOE, .pin = 8},
{.bank = GPIOE, .pin = 12},
};
const adc_channel_t sbu1_channels[] = {
{.adc = ADC3, .channel = 12},
{.adc = ADC3, .channel = 2},
{.adc = ADC3, .channel = 4},
{.adc = ADC3, .channel = 6},
{.adc = ADC3, .channel = 8},
{.adc = ADC3, .channel = 10},
};
const adc_channel_t sbu2_channels[] = {
{.adc = ADC1, .channel = 13},
{.adc = ADC3, .channel = 3},
{.adc = ADC3, .channel = 5},
{.adc = ADC3, .channel = 7},
{.adc = ADC3, .channel = 9},
{.adc = ADC3, .channel = 11},
};
void board_v2_set_led(uint8_t color, bool enabled) {
switch (color) {
case LED_RED:
set_gpio_output(GPIOE, 4, !enabled);
break;
case LED_GREEN:
set_gpio_output(GPIOE, 3, !enabled);
break;
case LED_BLUE:
set_gpio_output(GPIOE, 2, !enabled);
break;
default:
break;
}
}
void board_v2_set_harness_orientation(uint8_t orientation) {
switch (orientation) {
case HARNESS_ORIENTATION_NONE:
gpio_set_all_output(sbu1_ignition_pins, sizeof(sbu1_ignition_pins) / sizeof(gpio_t), false);
gpio_set_all_output(sbu1_relay_pins, sizeof(sbu1_relay_pins) / sizeof(gpio_t), false);
gpio_set_all_output(sbu2_ignition_pins, sizeof(sbu2_ignition_pins) / sizeof(gpio_t), false);
gpio_set_all_output(sbu2_relay_pins, sizeof(sbu2_relay_pins) / sizeof(gpio_t), false);
harness_orientation = orientation;
break;
case HARNESS_ORIENTATION_1:
gpio_set_all_output(sbu1_ignition_pins, sizeof(sbu1_ignition_pins) / sizeof(gpio_t), false);
gpio_set_all_output(sbu1_relay_pins, sizeof(sbu1_relay_pins) / sizeof(gpio_t), true);
gpio_set_bitmask(sbu2_ignition_pins, sizeof(sbu2_ignition_pins) / sizeof(gpio_t), ignition);
gpio_set_all_output(sbu2_relay_pins, sizeof(sbu2_relay_pins) / sizeof(gpio_t), false);
harness_orientation = orientation;
break;
case HARNESS_ORIENTATION_2:
gpio_set_bitmask(sbu1_ignition_pins, sizeof(sbu1_ignition_pins) / sizeof(gpio_t), ignition);
gpio_set_all_output(sbu1_relay_pins, sizeof(sbu1_relay_pins) / sizeof(gpio_t), false);
gpio_set_all_output(sbu2_ignition_pins, sizeof(sbu2_ignition_pins) / sizeof(gpio_t), false);
gpio_set_all_output(sbu2_relay_pins, sizeof(sbu2_relay_pins) / sizeof(gpio_t), true);
harness_orientation = orientation;
break;
default:
print("Tried to set an unsupported harness orientation: "); puth(orientation); print("\n");
break;
}
}
void board_v2_enable_can_transciever(uint8_t transciever, bool enabled) {
switch (transciever) {
case 1U:
set_gpio_output(GPIOG, 11, !enabled);
break;
case 2U:
set_gpio_output(GPIOB, 3, !enabled);
break;
case 3U:
set_gpio_output(GPIOD, 7, !enabled);
break;
case 4U:
set_gpio_output(GPIOB, 4, !enabled);
break;
default:
print("Invalid CAN transciever ("); puth(transciever); print("): enabling failed\n");
break;
}
}
void board_v2_enable_header_pin(uint8_t pin_num, bool enabled) {
if (pin_num < 8U) {
set_gpio_output(GPIOG, pin_num, enabled);
} else {
print("Invalid pin number ("); puth(pin_num); print("): enabling failed\n");
}
}
void board_v2_set_can_mode(uint8_t mode) {
board_v2_enable_can_transciever(2U, false);
board_v2_enable_can_transciever(4U, false);
switch (mode) {
case CAN_MODE_NORMAL:
// B12,B13: disable normal mode
set_gpio_pullup(GPIOB, 12, PULL_NONE);
set_gpio_mode(GPIOB, 12, MODE_ANALOG);
set_gpio_pullup(GPIOB, 13, PULL_NONE);
set_gpio_mode(GPIOB, 13, MODE_ANALOG);
// B5,B6: FDCAN2 mode
set_gpio_pullup(GPIOB, 5, PULL_NONE);
set_gpio_alternate(GPIOB, 5, GPIO_AF9_FDCAN2);
set_gpio_pullup(GPIOB, 6, PULL_NONE);
set_gpio_alternate(GPIOB, 6, GPIO_AF9_FDCAN2);
can_mode = CAN_MODE_NORMAL;
board_v2_enable_can_transciever(2U, true);
break;
case CAN_MODE_OBD_CAN2:
// B5,B6: disable normal mode
set_gpio_pullup(GPIOB, 5, PULL_NONE);
set_gpio_mode(GPIOB, 5, MODE_ANALOG);
set_gpio_pullup(GPIOB, 6, PULL_NONE);
set_gpio_mode(GPIOB, 6, MODE_ANALOG);
// B12,B13: FDCAN2 mode
set_gpio_pullup(GPIOB, 12, PULL_NONE);
set_gpio_alternate(GPIOB, 12, GPIO_AF9_FDCAN2);
set_gpio_pullup(GPIOB, 13, PULL_NONE);
set_gpio_alternate(GPIOB, 13, GPIO_AF9_FDCAN2);
can_mode = CAN_MODE_OBD_CAN2;
board_v2_enable_can_transciever(4U, true);
break;
default:
break;
}
}
bool panda_power = false;
uint8_t panda_power_bitmask = 0U;
void board_v2_set_panda_power(bool enable) {
panda_power = enable;
gpio_set_all_output(power_pins, sizeof(power_pins) / sizeof(gpio_t), enable);
if (enable) {
panda_power_bitmask = 0xFFU;
} else {
panda_power_bitmask = 0U;
}
}
void board_v2_set_panda_individual_power(uint8_t port_num, bool enable) {
port_num -= 1U;
if (port_num < 6U) {
panda_power_bitmask &= ~(1U << port_num);
panda_power_bitmask |= (enable ? 1U : 0U) << port_num;
} else {
print("Invalid port number ("); puth(port_num); print("): enabling failed\n");
}
gpio_set_bitmask(power_pins, sizeof(power_pins) / sizeof(gpio_t), (uint32_t)panda_power_bitmask);
}
bool board_v2_get_button(void) {
return get_gpio_input(GPIOG, 15);
}
void board_v2_set_ignition(bool enabled) {
ignition = enabled ? 0xFFU : 0U;
board_v2_set_harness_orientation(harness_orientation);
}
void board_v2_set_individual_ignition(uint8_t bitmask) {
ignition = bitmask;
board_v2_set_harness_orientation(harness_orientation);
}
float board_v2_get_channel_power(uint8_t channel) {
float ret = 0.0f;
if ((channel >= 1U) && (channel <= 6U)) {
uint16_t readout = adc_get_mV(ADC1, channel - 1U); // these are mapped nicely in hardware
ret = (((float) readout / 33e6) - 0.8e-6) / 52e-6 * 12.0f;
} else {
print("Invalid channel ("); puth(channel); print(")\n");
}
return ret;
}
uint16_t board_v2_get_sbu_mV(uint8_t channel, uint8_t sbu) {
uint16_t ret = 0U;
if ((channel >= 1U) && (channel <= 6U)) {
switch(sbu){
case SBU1:
ret = adc_get_mV(sbu1_channels[channel - 1U].adc, sbu1_channels[channel - 1U].channel);
break;
case SBU2:
ret = adc_get_mV(sbu2_channels[channel - 1U].adc, sbu2_channels[channel - 1U].channel);
break;
default:
print("Invalid SBU ("); puth(sbu); print(")\n");
break;
}
} else {
print("Invalid channel ("); puth(channel); print(")\n");
}
return ret;
}
void board_v2_init(void) {
common_init_gpio();
// Disable LEDs
board_v2_set_led(LED_RED, false);
board_v2_set_led(LED_GREEN, false);
board_v2_set_led(LED_BLUE, false);
// Normal CAN mode
board_v2_set_can_mode(CAN_MODE_NORMAL);
// Enable CAN transcievers
for(uint8_t i = 1; i <= 4; i++) {
board_v2_enable_can_transciever(i, true);
}
// Set to no harness orientation
board_v2_set_harness_orientation(HARNESS_ORIENTATION_NONE);
// Enable panda power by default
board_v2_set_panda_power(true);
// Current monitor channels
adc_init(ADC1);
register_set_bits(&SYSCFG->PMCR, SYSCFG_PMCR_PA0SO | SYSCFG_PMCR_PA1SO); // open up analog switches for PA0_C and PA1_C
set_gpio_mode(GPIOF, 11, MODE_ANALOG);
set_gpio_mode(GPIOA, 6, MODE_ANALOG);
set_gpio_mode(GPIOC, 4, MODE_ANALOG);
set_gpio_mode(GPIOB, 1, MODE_ANALOG);
// SBU channels
adc_init(ADC3);
set_gpio_mode(GPIOC, 2, MODE_ANALOG);
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
set_gpio_mode(GPIOF, 9, MODE_ANALOG);
set_gpio_mode(GPIOF, 7, MODE_ANALOG);
set_gpio_mode(GPIOF, 5, MODE_ANALOG);
set_gpio_mode(GPIOF, 3, MODE_ANALOG);
set_gpio_mode(GPIOF, 10, MODE_ANALOG);
set_gpio_mode(GPIOF, 8, MODE_ANALOG);
set_gpio_mode(GPIOF, 6, MODE_ANALOG);
set_gpio_mode(GPIOF, 4, MODE_ANALOG);
set_gpio_mode(GPIOC, 0, MODE_ANALOG);
set_gpio_mode(GPIOC, 1, MODE_ANALOG);
// Header pins
set_gpio_mode(GPIOG, 0, MODE_OUTPUT);
set_gpio_mode(GPIOG, 1, MODE_OUTPUT);
set_gpio_mode(GPIOG, 2, MODE_OUTPUT);
set_gpio_mode(GPIOG, 3, MODE_OUTPUT);
set_gpio_mode(GPIOG, 4, MODE_OUTPUT);
set_gpio_mode(GPIOG, 5, MODE_OUTPUT);
set_gpio_mode(GPIOG, 6, MODE_OUTPUT);
set_gpio_mode(GPIOG, 7, MODE_OUTPUT);
}
void board_v2_tick(void) {}
const board board_v2 = {
.has_canfd = true,
.has_sbu_sense = true,
.avdd_mV = 3300U,
.init = &board_v2_init,
.set_led = &board_v2_set_led,
.board_tick = &board_v2_tick,
.get_button = &board_v2_get_button,
.set_panda_power = &board_v2_set_panda_power,
.set_panda_individual_power = &board_v2_set_panda_individual_power,
.set_ignition = &board_v2_set_ignition,
.set_individual_ignition = &board_v2_set_individual_ignition,
.set_harness_orientation = &board_v2_set_harness_orientation,
.set_can_mode = &board_v2_set_can_mode,
.enable_can_transciever = &board_v2_enable_can_transciever,
.enable_header_pin = &board_v2_enable_header_pin,
.get_channel_power = &board_v2_get_channel_power,
.get_sbu_mV = &board_v2_get_sbu_mV,
};

View File

@@ -1,24 +0,0 @@
// When changing these structs, python/__init__.py needs to be kept up to date!
#define JUNGLE_HEALTH_PACKET_VERSION 1
struct __attribute__((packed)) jungle_health_t {
uint32_t uptime_pkt;
float ch1_power;
float ch2_power;
float ch3_power;
float ch4_power;
float ch5_power;
float ch6_power;
uint16_t ch1_sbu1_mV;
uint16_t ch1_sbu2_mV;
uint16_t ch2_sbu1_mV;
uint16_t ch2_sbu2_mV;
uint16_t ch3_sbu1_mV;
uint16_t ch3_sbu2_mV;
uint16_t ch4_sbu1_mV;
uint16_t ch4_sbu2_mV;
uint16_t ch5_sbu1_mV;
uint16_t ch5_sbu2_mV;
uint16_t ch6_sbu1_mV;
uint16_t ch6_sbu2_mV;
};

View File

@@ -1,261 +0,0 @@
extern int _app_start[0xc000]; // Only first 3 sectors of size 0x4000 are used
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;
// **** 0xa0: Set panda power per channel by bitmask.
case 0xa3:
current_board->set_panda_individual_power(req->param1, (req->param2 > 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_transciever(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;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +0,0 @@
#include "boards/board_declarations.h"
#include "boards/board_v1.h"
void detect_board_type(void) {
hw_type = HW_TYPE_V1;
current_board = &board_v1;
}

View File

@@ -1,9 +0,0 @@
#include "boards/board_declarations.h"
#include "stm32h7/lladc.h"
#include "boards/board_v2.h"
void detect_board_type(void) {
hw_type = HW_TYPE_V2;
current_board = &board_v2;
}

View File

@@ -1,54 +0,0 @@
typedef struct {
ADC_TypeDef *adc;
uint8_t channel;
} adc_channel_t;
void adc_init(ADC_TypeDef *adc) {
adc->CR &= ~(ADC_CR_DEEPPWD); // Reset deep-power-down mode
adc->CR |= ADC_CR_ADVREGEN; // Enable ADC regulator
while(!(adc->ISR & ADC_ISR_LDORDY) && (adc != ADC3));
if (adc != ADC3) {
adc->CR &= ~(ADC_CR_ADCALDIF); // Choose single-ended calibration
adc->CR |= ADC_CR_ADCALLIN; // Lineriality calibration
}
adc->CR |= ADC_CR_ADCAL; // Start calibrtation
while((adc->CR & ADC_CR_ADCAL) != 0);
adc->ISR |= ADC_ISR_ADRDY;
adc->CR |= ADC_CR_ADEN;
while(!(adc->ISR & ADC_ISR_ADRDY));
}
uint16_t adc_get_raw(ADC_TypeDef *adc, uint8_t channel) {
adc->SQR1 &= ~(ADC_SQR1_L);
adc->SQR1 = ((uint32_t) channel << 6U);
if (channel < 10U) {
adc->SMPR1 = (0x7U << (channel * 3U));
} else {
adc->SMPR2 = (0x7U << ((channel - 10U) * 3U));
}
adc->PCSEL_RES0 = (0x1U << channel);
adc->CR |= ADC_CR_ADSTART;
while (!(adc->ISR & ADC_ISR_EOC));
uint16_t res = adc->DR;
while (!(adc->ISR & ADC_ISR_EOS));
adc->ISR |= ADC_ISR_EOS;
return res;
}
uint16_t adc_get_mV(ADC_TypeDef *adc, uint8_t channel) {
uint16_t ret = 0;
if ((adc == ADC1) || (adc == ADC2)) {
ret = (adc_get_raw(adc, channel) * current_board->avdd_mV) / 65535U;
} else if (adc == ADC3) {
ret = (adc_get_raw(adc, channel) * current_board->avdd_mV) / 4095U;
} else {}
return ret;
}