This commit is contained in:
Your Name
2024-04-27 03:19:19 -05:00
parent df418b503f
commit 03af7b6107
306 changed files with 108529 additions and 119 deletions

View File

@@ -0,0 +1,82 @@
// ******************** 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

@@ -0,0 +1,178 @@
// ///////////////////////// //
// 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

@@ -0,0 +1,328 @@
// ///////////////////////// //
// 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,
};