Skip to content

Commit

Permalink
Detect H723 in firmware (commaai#1988)
Browse files Browse the repository at this point in the history
* determine H723 based on package type

* wrong way round

* misra...

* enable SYSCFG clock before reading

* whitelist certain package types
  • Loading branch information
robbederks authored Aug 2, 2024
1 parent ee7b385 commit b70ba5e
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 29 deletions.
3 changes: 0 additions & 3 deletions board/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -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)
37 changes: 17 additions & 20 deletions board/stm32h7/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
44 changes: 38 additions & 6 deletions board/stm32h7/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down

0 comments on commit b70ba5e

Please sign in to comment.