From b70ba5ecde9c734ba3880804c0488ef4b120d11b Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Fri, 2 Aug 2024 20:26:16 +0200 Subject: [PATCH] Detect H723 in firmware (#1988) * determine H723 based on package type * wrong way round * misra... * enable SYSCFG clock before reading * whitelist certain package types --- board/SConscript | 3 --- board/stm32h7/board.h | 37 +++++++++++++++++------------------- board/stm32h7/clock.h | 44 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/board/SConscript b/board/SConscript index 93fd47b07e..3ff77648ba 100644 --- a/board/SConscript +++ b/board/SConscript @@ -15,7 +15,4 @@ for project_name, project in build_projects.items(): if ("ENABLE_SPI" in os.environ or "h7" in project_name): flags.append('-DENABLE_SPI') - if "H723" in os.environ: - flags.append('-DSTM32H723') - build_project(project_name, project, flags) diff --git a/board/stm32h7/board.h b/board/stm32h7/board.h index f5a8e55aa8..e8ea23b252 100644 --- a/board/stm32h7/board.h +++ b/board/stm32h7/board.h @@ -18,36 +18,33 @@ #include "boards/cuatro.h" -uint8_t get_board_id(void) { - return detect_with_pull(GPIOF, 7, PULL_UP) | - (detect_with_pull(GPIOF, 8, PULL_UP) << 1U) | - (detect_with_pull(GPIOF, 9, PULL_UP) << 2U) | - (detect_with_pull(GPIOF, 10, PULL_UP) << 3U); -} - void detect_board_type(void) { - const uint8_t board_id = get_board_id(); + // On STM32H7 pandas, we use two different sets of pins. + const uint8_t id1 = detect_with_pull(GPIOF, 7, PULL_UP) | + (detect_with_pull(GPIOF, 8, PULL_UP) << 1U) | + (detect_with_pull(GPIOF, 9, PULL_UP) << 2U) | + (detect_with_pull(GPIOF, 10, PULL_UP) << 3U); - if (board_id == 0U) { + const uint8_t id2 = detect_with_pull(GPIOD, 4, PULL_UP) | + (detect_with_pull(GPIOD, 5, PULL_UP) << 1U) | + (detect_with_pull(GPIOD, 6, PULL_UP) << 2U) | + (detect_with_pull(GPIOD, 7, PULL_UP) << 3U); + + if (id2 == 3U) { + hw_type = HW_TYPE_CUATRO; + current_board = &board_cuatro; + } else if (id1 == 0U) { hw_type = HW_TYPE_RED_PANDA; current_board = &board_red; - } else if (board_id == 1U) { + } else if (id1 == 1U) { // deprecated //hw_type = HW_TYPE_RED_PANDA_V2; - } else if (board_id == 2U) { + hw_type = HW_TYPE_UNKNOWN; + } else if (id1 == 2U) { hw_type = HW_TYPE_TRES; current_board = &board_tres; - } else if (board_id == 3U) { - hw_type = HW_TYPE_CUATRO; - 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_CUATRO; - current_board = &board_cuatro; -#endif } diff --git a/board/stm32h7/clock.h b/board/stm32h7/clock.h index 1ff9421981..b68fcc1c26 100644 --- a/board/stm32h7/clock.h +++ b/board/stm32h7/clock.h @@ -17,6 +17,34 @@ APB4 per: 60MHz PCLK1: 60MHz (for USART2,3,4,5,7,8) */ +typedef enum { + PACKAGE_UNKNOWN = 0, + PACKAGE_WITH_SMPS = 1, + PACKAGE_WITHOUT_SMPS = 2, +} PackageSMPSType; + +// TODO: find a better way to distinguish between H725 (using SMPS) and H723 (lacking SMPS) +// The package will do for now, since we have only used TFBGA100 for H723 +PackageSMPSType get_package_smps_type(void) { + PackageSMPSType ret; + RCC->APB4ENR |= RCC_APB4ENR_SYSCFGEN; // make sure SYSCFG clock is enabled. does seem to read fine without too though + + switch(SYSCFG->PKGR & 0xFU) { + case 0b0001U: // TFBGA100 Legacy + case 0b0011U: // TFBGA100 + ret = PACKAGE_WITHOUT_SMPS; + break; + case 0b0101U: // LQFP144 Legacy + case 0b0111U: // LQFP144 Industrial + case 0b1000U: // UFBGA169 + ret = PACKAGE_WITH_SMPS; + break; + default: + ret = PACKAGE_UNKNOWN; + } + return ret; +} + void clock_init(void) { /* WARNING: PWR->CR3's lower byte can only be written once @@ -28,12 +56,16 @@ void clock_init(void) { In a normal bootup, the bootstub will be the first to write this. The app section calls clock_init again, but the CR3 write will silently fail. This is fine for most cases, but caution should be taken that the bootstub and app always write the same config. */ - // 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 -#else - register_set(&(PWR->CR3), PWR_CR3_LDOEN, 0xFU); -#endif + // Set power mode to direct SMPS power supply (depends on the board layout) + PackageSMPSType package_smps = get_package_smps_type(); + if (package_smps == PACKAGE_WITHOUT_SMPS) { + register_set(&(PWR->CR3), PWR_CR3_LDOEN, 0xFU); // no SMPS, so powered by LDO + } else if (package_smps == PACKAGE_WITH_SMPS) { + register_set(&(PWR->CR3), PWR_CR3_SMPSEN, 0xFU); // powered only by SMPS + } else { + while(true); // unknown package, let's hang here + } + // 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) == 0U);