diff --git a/board/SConscript b/board/SConscript index 45fa0f41..81f1ef84 100644 --- a/board/SConscript +++ b/board/SConscript @@ -15,4 +15,7 @@ for project_name, project in build_projects.items(): if ("ENABLE_SPI" in os.environ or "h7" in project_name) and not project_name.startswith('pedal'): flags.append('-DENABLE_SPI') + if "H723" in os.environ: + flags.append('-DSTM32H723') + build_project(project_name, project, flags) diff --git a/board/boards/board_declarations.h b/board/boards/board_declarations.h index b127f192..372c597f 100644 --- a/board/boards/board_declarations.h +++ b/board/boards/board_declarations.h @@ -57,6 +57,7 @@ struct board { #define HW_TYPE_RED_PANDA 7U #define HW_TYPE_RED_PANDA_V2 8U #define HW_TYPE_TRES 9U +#define HW_TYPE_QUATRO 10U // LED colors #define LED_RED 0U diff --git a/board/boards/quatro.h b/board/boards/quatro.h new file mode 100644 index 00000000..09be4e86 --- /dev/null +++ b/board/boards/quatro.h @@ -0,0 +1,71 @@ +void quatro_set_led(uint8_t color, bool enabled) { + switch (color) { + case LED_RED: + set_gpio_output(GPIOD, 15, !enabled); + break; + case LED_GREEN: + set_gpio_output(GPIOD, 14, !enabled); + break; + case LED_BLUE: + set_gpio_output(GPIOE, 2, !enabled); + break; + default: + break; + } +} + +void quatro_init(void) { + red_chiplet_init(); + + // C2: SOM GPIO used as input (fan control at boot) + set_gpio_mode(GPIOC, 2, MODE_INPUT); + set_gpio_pullup(GPIOC, 2, PULL_DOWN); + + // SOM bootkick + reset lines + set_gpio_mode(GPIOC, 12, MODE_OUTPUT); + tres_set_bootkick(BOOT_BOOTKICK); + + // SOM debugging UART + gpio_uart7_init(); + uart_init(&uart_ring_som_debug, 115200); + + // SPI init + gpio_spi_init(); + + // fan setup + set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3); + + // Initialize IR PWM and set to 0% + set_gpio_alternate(GPIOC, 9, GPIO_AF2_TIM3); + pwm_init(TIM3, 4); + tres_set_ir_power(0U); + + // Clock source + clock_source_init(); +} + +const board board_quatro = { + .harness_config = &red_chiplet_harness_config, + .has_hw_gmlan = false, + .has_obd = true, + .has_spi = true, + .has_canfd = true, + .has_rtc_battery = true, + .fan_max_rpm = 6600U, + .avdd_mV = 1800U, + .fan_stall_recovery = false, + .fan_enable_cooldown_time = 3U, + .init = quatro_init, + .init_bootloader = unused_init_bootloader, + .enable_can_transceiver = red_chiplet_enable_can_transceiver, + .enable_can_transceivers = red_chiplet_enable_can_transceivers, + .set_led = quatro_set_led, + .set_can_mode = red_chiplet_set_can_mode, + .check_ignition = red_check_ignition, + .read_current = unused_read_current, + .set_fan_enabled = tres_set_fan_enabled, + .set_ir_power = tres_set_ir_power, + .set_siren = unused_set_siren, + .set_bootkick = tres_set_bootkick, + .read_som_gpio = tres_read_som_gpio +}; diff --git a/board/stm32h7/board.h b/board/stm32h7/board.h index 0394e3b5..d5f77443 100644 --- a/board/stm32h7/board.h +++ b/board/stm32h7/board.h @@ -17,6 +17,7 @@ #include "boards/red.h" #include "boards/red_chiplet.h" #include "boards/tres.h" +#include "boards/quatro.h" uint8_t get_board_id(void) { @@ -38,8 +39,17 @@ void detect_board_type(void) { } else if (board_id == 2U) { hw_type = HW_TYPE_TRES; current_board = &board_tres; + } else if (board_id == 3U) { + hw_type = HW_TYPE_QUATRO; + current_board = &board_tres; } else { hw_type = HW_TYPE_UNKNOWN; print("Hardware type is UNKNOWN!\n"); } + + // TODO: detect this live +#ifdef STM32H723 + hw_type = HW_TYPE_QUATRO; + current_board = &board_quatro; +#endif } diff --git a/board/stm32h7/clock.h b/board/stm32h7/clock.h index c5f93cd0..478e2aa4 100644 --- a/board/stm32h7/clock.h +++ b/board/stm32h7/clock.h @@ -18,9 +18,11 @@ PCLK1: 60MHz (for USART2,3,4,5,7,8) */ void clock_init(void) { - //Set power mode to direct SMPS power supply(depends on the board layout) + // Set power mode to direct SMPS power supply(depends on the board layout) +#ifndef STM32H723 register_set(&(PWR->CR3), PWR_CR3_SMPSEN, 0xFU); // powered only by SMPS - //Set VOS level (VOS3 to 170Mhz, VOS2 to 300Mhz, VOS1 to 400Mhz, VOS0 to 550Mhz) +#endif + // Set VOS level (VOS3 to 170Mhz, VOS2 to 300Mhz, VOS1 to 400Mhz, VOS0 to 550Mhz) register_set(&(PWR->D3CR), PWR_D3CR_VOS_1 | PWR_D3CR_VOS_0, 0xC000U); //VOS1, needed for 80Mhz CAN FD while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0); while ((PWR->CSR1 & PWR_CSR1_ACTVOS) != (PWR->D3CR & PWR_D3CR_VOS)); // check that VOS level was actually set diff --git a/python/__init__.py b/python/__init__.py index 50d9197a..92aaf026 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -166,6 +166,7 @@ class Panda: HW_TYPE_RED_PANDA = b'\x07' HW_TYPE_RED_PANDA_V2 = b'\x08' HW_TYPE_TRES = b'\x09' + HW_TYPE_QUATRO = b'\x0a' CAN_PACKET_VERSION = 4 HEALTH_PACKET_VERSION = 15 @@ -175,15 +176,16 @@ class Panda: F2_DEVICES = [HW_TYPE_PEDAL, ] F4_DEVICES = [HW_TYPE_WHITE_PANDA, HW_TYPE_GREY_PANDA, HW_TYPE_BLACK_PANDA, HW_TYPE_UNO, HW_TYPE_DOS] - H7_DEVICES = [HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES] + H7_DEVICES = [HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES, HW_TYPE_QUATRO] - INTERNAL_DEVICES = (HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_TRES) - HAS_OBD = (HW_TYPE_BLACK_PANDA, HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES) + INTERNAL_DEVICES = (HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_TRES, HW_TYPE_QUATRO) + HAS_OBD = (HW_TYPE_BLACK_PANDA, HW_TYPE_UNO, HW_TYPE_DOS, HW_TYPE_RED_PANDA, HW_TYPE_RED_PANDA_V2, HW_TYPE_TRES, HW_TYPE_QUATRO) MAX_FAN_RPMs = { HW_TYPE_UNO: 5100, HW_TYPE_DOS: 6500, HW_TYPE_TRES: 6600, + HW_TYPE_QUATRO: 6600, } HARNESS_STATUS_NC = 0