stm32/mboot: Add support for H7 MCUs, with H743 flash layout.
This commit is contained in:
parent
ae1e18a346
commit
fd13ce5e60
|
@ -48,6 +48,7 @@ CFLAGS_CORTEX_M = -mthumb
|
|||
# Options for particular MCU series
|
||||
CFLAGS_MCU_f4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
|
||||
CFLAGS_MCU_f7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7
|
||||
CFLAGS_MCU_h7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7
|
||||
CFLAGS_MCU_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
|
||||
|
||||
CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_EXTRA)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017-2018 Damien P. George
|
||||
* Copyright (c) 2017-2019 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -38,7 +38,7 @@
|
|||
// This DFU code with polling runs in about 70% of the time of the ST bootloader
|
||||
#define USE_USB_POLLING (1)
|
||||
|
||||
// Using cache probably won't make it faster because we run at 48MHz, and best
|
||||
// Using cache probably won't make it faster because we run at a low frequency, and best
|
||||
// to keep the MCU config as minimal as possible.
|
||||
#define USE_CACHE (0)
|
||||
|
||||
|
@ -46,18 +46,25 @@
|
|||
#define IRQ_PRI_SYSTICK (NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 0, 0))
|
||||
#define IRQ_PRI_I2C (NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 1, 0))
|
||||
|
||||
// Configure PLL to give a 48MHz CPU freq
|
||||
// Configure PLL to give the desired CPU freq
|
||||
#undef MICROPY_HW_FLASH_LATENCY
|
||||
#if defined(STM32H7)
|
||||
#define CORE_PLL_FREQ (96000000)
|
||||
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_2
|
||||
#else
|
||||
#define CORE_PLL_FREQ (48000000)
|
||||
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_1
|
||||
#endif
|
||||
#undef MICROPY_HW_CLK_PLLM
|
||||
#undef MICROPY_HW_CLK_PLLN
|
||||
#undef MICROPY_HW_CLK_PLLP
|
||||
#undef MICROPY_HW_CLK_PLLQ
|
||||
#undef MICROPY_HW_FLASH_LATENCY
|
||||
#undef MICROPY_HW_CLK_PLLR
|
||||
#define MICROPY_HW_CLK_PLLM (HSE_VALUE / 1000000)
|
||||
#define MICROPY_HW_CLK_PLLN (192)
|
||||
#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV4)
|
||||
#define MICROPY_HW_CLK_PLLP (MICROPY_HW_CLK_PLLN / (CORE_PLL_FREQ / 1000000))
|
||||
#define MICROPY_HW_CLK_PLLQ (4)
|
||||
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_1
|
||||
#define MICROPY_HW_CLK_PLLR (2)
|
||||
|
||||
// Work out which USB device to use for the USB DFU interface
|
||||
#if !defined(MICROPY_HW_USB_MAIN_DEV)
|
||||
|
@ -137,11 +144,25 @@ static void __fatal_error(const char *msg) {
|
|||
#define CONFIG_RCC_CR_2ND (RCC_CR_HSEON || RCC_CR_CSSON || RCC_CR_PLLON)
|
||||
#define CONFIG_RCC_PLLCFGR (0x24003010)
|
||||
|
||||
#elif defined(STM32H7)
|
||||
|
||||
#define CONFIG_RCC_CR_1ST (RCC_CR_HSION)
|
||||
#define CONFIG_RCC_CR_2ND (RCC_CR_PLL3ON | RCC_CR_PLL2ON | RCC_CR_PLL1ON | RCC_CR_CSSHSEON \
|
||||
| RCC_CR_HSEON | RCC_CR_HSI48ON | RCC_CR_CSIKERON | RCC_CR_CSION)
|
||||
#define CONFIG_RCC_PLLCFGR (0x00000000)
|
||||
|
||||
#else
|
||||
#error Unknown processor
|
||||
#endif
|
||||
|
||||
void SystemInit(void) {
|
||||
#if defined(STM32H7)
|
||||
// Configure write-once power options, and wait for voltage levels to be ready
|
||||
PWR->CR3 = PWR_CR3_LDOEN;
|
||||
while (!(PWR->CSR1 & PWR_CSR1_ACTVOSRDY)) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set HSION bit
|
||||
RCC->CR |= CONFIG_RCC_CR_1ST;
|
||||
|
||||
|
@ -154,11 +175,27 @@ void SystemInit(void) {
|
|||
// Reset PLLCFGR register
|
||||
RCC->PLLCFGR = CONFIG_RCC_PLLCFGR;
|
||||
|
||||
#if defined(STM32H7)
|
||||
// Reset PLL and clock configuration registers
|
||||
RCC->D1CFGR = 0x00000000;
|
||||
RCC->D2CFGR = 0x00000000;
|
||||
RCC->D3CFGR = 0x00000000;
|
||||
RCC->PLLCKSELR = 0x00000000;
|
||||
RCC->D1CCIPR = 0x00000000;
|
||||
RCC->D2CCIP1R = 0x00000000;
|
||||
RCC->D2CCIP2R = 0x00000000;
|
||||
RCC->D3CCIPR = 0x00000000;
|
||||
#endif
|
||||
|
||||
// Reset HSEBYP bit
|
||||
RCC->CR &= (uint32_t)0xFFFBFFFF;
|
||||
|
||||
// Disable all interrupts
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
RCC->CIR = 0x00000000;
|
||||
#elif defined(STM32H7)
|
||||
RCC->CIER = 0x00000000;
|
||||
#endif
|
||||
|
||||
// Set location of vector table
|
||||
SCB->VTOR = FLASH_BASE;
|
||||
|
@ -173,6 +210,8 @@ void systick_init(void) {
|
|||
NVIC_SetPriority(SysTick_IRQn, IRQ_PRI_SYSTICK);
|
||||
}
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
|
||||
void SystemClock_Config(void) {
|
||||
// This function assumes that HSI is used as the system clock (see RCC->CFGR, SWS bits)
|
||||
|
||||
|
@ -243,6 +282,87 @@ void SystemClock_Config(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#elif defined(STM32H7)
|
||||
|
||||
void SystemClock_Config(void) {
|
||||
// This function assumes that HSI is used as the system clock (see RCC->CFGR, SWS bits)
|
||||
|
||||
// Select VOS level as high voltage to give reliable operation
|
||||
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) == RESET) {
|
||||
}
|
||||
|
||||
// Turn HSE on
|
||||
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
|
||||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) {
|
||||
}
|
||||
|
||||
// Disable PLL1
|
||||
__HAL_RCC_PLL_DISABLE();
|
||||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) {
|
||||
}
|
||||
|
||||
// Configure PLL1 factors and source
|
||||
RCC->PLLCKSELR =
|
||||
MICROPY_HW_CLK_PLLM << RCC_PLLCKSELR_DIVM1_Pos
|
||||
| 2 << RCC_PLLCKSELR_PLLSRC_Pos; // HSE selected as PLL source
|
||||
RCC->PLL1DIVR =
|
||||
(MICROPY_HW_CLK_PLLN - 1) << RCC_PLL1DIVR_N1_Pos
|
||||
| (MICROPY_HW_CLK_PLLP - 1) << RCC_PLL1DIVR_P1_Pos // only even P allowed
|
||||
| (MICROPY_HW_CLK_PLLQ - 1) << RCC_PLL1DIVR_Q1_Pos
|
||||
| (MICROPY_HW_CLK_PLLR - 1) << RCC_PLL1DIVR_R1_Pos;
|
||||
|
||||
// Enable PLL1 outputs for SYSCLK and USB
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_DIVP1EN | RCC_PLLCFGR_DIVQ1EN;
|
||||
|
||||
// Select PLL1-Q for USB clock source
|
||||
RCC->D2CCIP2R |= 1 << RCC_D2CCIP2R_USBSEL_Pos;
|
||||
|
||||
// Enable PLL1
|
||||
__HAL_RCC_PLL_ENABLE();
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) {
|
||||
}
|
||||
|
||||
// Increase latency before changing SYSCLK
|
||||
if (MICROPY_HW_FLASH_LATENCY > (FLASH->ACR & FLASH_ACR_LATENCY)) {
|
||||
__HAL_FLASH_SET_LATENCY(MICROPY_HW_FLASH_LATENCY);
|
||||
}
|
||||
|
||||
// Configure AHB divider
|
||||
RCC->D1CFGR =
|
||||
0 << RCC_D1CFGR_D1CPRE_Pos // SYSCLK prescaler of 1
|
||||
| 8 << RCC_D1CFGR_HPRE_Pos // AHB prescaler of 2
|
||||
;
|
||||
|
||||
// Configure SYSCLK source from PLL
|
||||
__HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_PLLCLK);
|
||||
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL1) {
|
||||
}
|
||||
|
||||
// Decrease latency after changing clock
|
||||
if (MICROPY_HW_FLASH_LATENCY < (FLASH->ACR & FLASH_ACR_LATENCY)) {
|
||||
__HAL_FLASH_SET_LATENCY(MICROPY_HW_FLASH_LATENCY);
|
||||
}
|
||||
|
||||
// Set APB clock dividers
|
||||
RCC->D1CFGR |=
|
||||
4 << RCC_D1CFGR_D1PPRE_Pos // APB3 prescaler of 2
|
||||
;
|
||||
RCC->D2CFGR =
|
||||
4 << RCC_D2CFGR_D2PPRE2_Pos // APB2 prescaler of 2
|
||||
| 4 << RCC_D2CFGR_D2PPRE1_Pos // APB1 prescaler of 2
|
||||
;
|
||||
RCC->D3CFGR =
|
||||
4 << RCC_D3CFGR_D3PPRE_Pos // APB4 prescaler of 2
|
||||
;
|
||||
|
||||
// Update clock value and reconfigure systick now that the frequency changed
|
||||
SystemCoreClock = CORE_PLL_FREQ;
|
||||
systick_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Needed by HAL_PCD_IRQHandler
|
||||
uint32_t HAL_RCC_GetHCLKFreq(void) {
|
||||
return SystemCoreClock;
|
||||
|
@ -251,13 +371,21 @@ uint32_t HAL_RCC_GetHCLKFreq(void) {
|
|||
/******************************************************************************/
|
||||
// GPIO
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#define AHBxENR AHB1ENR
|
||||
#define AHBxENR_GPIOAEN_Pos RCC_AHB1ENR_GPIOAEN_Pos
|
||||
#elif defined(STM32H7)
|
||||
#define AHBxENR AHB4ENR
|
||||
#define AHBxENR_GPIOAEN_Pos RCC_AHB4ENR_GPIOAEN_Pos
|
||||
#endif
|
||||
|
||||
void mp_hal_pin_config(mp_hal_pin_obj_t port_pin, uint32_t mode, uint32_t pull, uint32_t alt) {
|
||||
GPIO_TypeDef *gpio = (GPIO_TypeDef*)(port_pin & ~0xf);
|
||||
|
||||
// Enable the GPIO peripheral clock
|
||||
uint32_t en_bit = RCC_AHB1ENR_GPIOAEN_Pos + ((uintptr_t)gpio - GPIOA_BASE) / (GPIOB_BASE - GPIOA_BASE);
|
||||
RCC->AHB1ENR |= 1 << en_bit;
|
||||
volatile uint32_t tmp = RCC->AHB1ENR; // Delay after enabling clock
|
||||
uint32_t gpio_idx = ((uintptr_t)gpio - GPIOA_BASE) / (GPIOB_BASE - GPIOA_BASE);
|
||||
RCC->AHBxENR |= 1 << (AHBxENR_GPIOAEN_Pos + gpio_idx);
|
||||
volatile uint32_t tmp = RCC->AHBxENR; // Delay after enabling clock
|
||||
(void)tmp;
|
||||
|
||||
// Configure the pin
|
||||
|
@ -381,6 +509,14 @@ static const flash_layout_t flash_layout[] = {
|
|||
{ 0x08040000, 0x40000, 7 },
|
||||
};
|
||||
|
||||
#elif defined(STM32H743xx)
|
||||
|
||||
#define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/16*128Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT
|
||||
|
||||
static const flash_layout_t flash_layout[] = {
|
||||
{ 0x08000000, 0x20000, 16 },
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static uint32_t flash_get_sector_index(uint32_t addr, uint32_t *sector_size) {
|
||||
|
@ -401,6 +537,27 @@ static uint32_t flash_get_sector_index(uint32_t addr, uint32_t *sector_size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(STM32H7)
|
||||
// get the bank of a given flash address
|
||||
static uint32_t get_bank(uint32_t addr) {
|
||||
if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_SWAP_BANK) == 0) {
|
||||
// no bank swap
|
||||
if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
|
||||
return FLASH_BANK_1;
|
||||
} else {
|
||||
return FLASH_BANK_2;
|
||||
}
|
||||
} else {
|
||||
// bank swap
|
||||
if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
|
||||
return FLASH_BANK_2;
|
||||
} else {
|
||||
return FLASH_BANK_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int flash_mass_erase(void) {
|
||||
// TODO
|
||||
return -1;
|
||||
|
@ -419,13 +576,20 @@ static int flash_page_erase(uint32_t addr, uint32_t *next_addr) {
|
|||
HAL_FLASH_Unlock();
|
||||
|
||||
// Clear pending flags (if any)
|
||||
#if defined(STM32H7)
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2);
|
||||
#else
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
|
||||
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
|
||||
#endif
|
||||
|
||||
// erase the sector(s)
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
|
||||
EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
|
||||
#if defined(STM32H7)
|
||||
EraseInitStruct.Banks = get_bank(addr);
|
||||
#endif
|
||||
EraseInitStruct.Sector = sector;
|
||||
EraseInitStruct.NbSectors = 1;
|
||||
|
||||
|
@ -454,6 +618,20 @@ static int flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
|
|||
const uint32_t *src = (const uint32_t*)src8;
|
||||
size_t num_word32 = (len + 3) / 4;
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
#if defined(STM32H7)
|
||||
|
||||
// program the flash 256 bits at a time
|
||||
for (int i = 0; i < num_word32 / 8; ++i) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, addr, (uint64_t)(uint32_t)src) != HAL_OK) {
|
||||
return - 1;
|
||||
}
|
||||
addr += 32;
|
||||
src += 8;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// program the flash word by word
|
||||
for (size_t i = 0; i < num_word32; i++) {
|
||||
if (HAL_FLASH_Program(TYPEPROGRAM_WORD, addr, *src) != HAL_OK) {
|
||||
|
@ -463,6 +641,8 @@ static int flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
|
|||
src += 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// TODO verify data
|
||||
|
||||
return 0;
|
||||
|
@ -1130,6 +1310,11 @@ static void pyb_usbdd_init(pyb_usbdd_obj_t *self, int phy_id) {
|
|||
|
||||
static void pyb_usbdd_start(pyb_usbdd_obj_t *self) {
|
||||
if (!self->started) {
|
||||
#if defined(STM32H7)
|
||||
PWR->CR3 |= PWR_CR3_USB33DEN;
|
||||
while (!(PWR->CR3 & PWR_CR3_USB33RDY)) {
|
||||
}
|
||||
#endif
|
||||
USBD_LL_Init(&self->hUSBDDevice, 0);
|
||||
USBD_LL_Start(&self->hUSBDDevice);
|
||||
self->started = true;
|
||||
|
@ -1249,8 +1434,8 @@ void stm32_main(int initial_r0) {
|
|||
goto enter_bootloader;
|
||||
}
|
||||
|
||||
// MCU starts up with 16MHz HSI
|
||||
SystemCoreClock = 16000000;
|
||||
// MCU starts up with HSI
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
|
||||
int reset_mode = get_reset_mode();
|
||||
uint32_t msp = *(volatile uint32_t*)APPLICATION_ADDR;
|
||||
|
|
|
@ -48,8 +48,13 @@
|
|||
#define mp_hal_pin_input(p) mp_hal_pin_config((p), MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0)
|
||||
#define mp_hal_pin_output(p) mp_hal_pin_config((p), MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0)
|
||||
#define mp_hal_pin_open_drain(p) mp_hal_pin_config((p), MP_HAL_PIN_MODE_OPEN_DRAIN, MP_HAL_PIN_PULL_NONE, 0)
|
||||
#if defined(STM32H7)
|
||||
#define mp_hal_pin_low(p) (((GPIO_TypeDef*)((p) & ~0xf))->BSRRH = 1 << ((p) & 0xf))
|
||||
#define mp_hal_pin_high(p) (((GPIO_TypeDef*)((p) & ~0xf))->BSRRL = 1 << ((p) & 0xf))
|
||||
#else
|
||||
#define mp_hal_pin_low(p) (((GPIO_TypeDef*)((p) & ~0xf))->BSRR = 0x10000 << ((p) & 0xf))
|
||||
#define mp_hal_pin_high(p) (((GPIO_TypeDef*)((p) & ~0xf))->BSRR = 1 << ((p) & 0xf))
|
||||
#endif
|
||||
#define mp_hal_pin_od_low(p) mp_hal_pin_low(p)
|
||||
#define mp_hal_pin_od_high(p) mp_hal_pin_high(p)
|
||||
#define mp_hal_pin_read(p) ((((GPIO_TypeDef*)((p) & ~0xf))->IDR >> ((p) & 0xf)) & 1)
|
||||
|
|
Loading…
Reference in New Issue