8000 stm32/mboot: Add support for H7 MCUs, with H743 flash layout. · rlucia/micropython@fd13ce5 · GitHub
[go: up one dir, main page]

8000
Skip to content

Commit fd13ce5

Browse files
committed
stm32/mboot: Add support for H7 MCUs, with H743 flash layout.
1 parent ae1e18a commit fd13ce5

File tree

3 files changed

+202
-11
lines changed

3 files changed

+202
-11
lines changed

ports/stm32/mboot/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ CFLAGS_CORTEX_M = -mthumb
4848
# Options for particular MCU series
4949
CFLAGS_MCU_f4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
5050
CFLAGS_MCU_f7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7
51+
CFLAGS_MCU_h7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7
5152
CFLAGS_MCU_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
5253

5354
CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_EXTRA)

ports/stm32/mboot/main.c

Lines changed: 196 additions & 11 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2017-2018 Damien P. George
6+
* Copyright (c) 2017-2019 Damien P. George
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -38,26 +38,33 @@
3838
// This DFU code with polling runs in about 70% of the time of the ST bootloader
3939
#define USE_USB_POLLING (1)
4040

41-
// Using cache probably won't make it faster because we run at 48MHz, and best
41+
// Using cache probably won't make it faster because we run at a low frequency, and best
4242
// to keep the MCU config as minimal as possible.
4343
#define USE_CACHE (0)
4444

4545
// IRQ priorities (encoded values suitable for NVIC_SetPriority)
4646
#define IRQ_PRI_SYSTICK (NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 0, 0))
4747
#define IRQ_PRI_I2C (NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 1, 0))
4848

49-
// Configure PLL to give a 48MHz CPU freq
49+
// Configure PLL to give the desired CPU freq
50+
#undef MICROPY_HW_FLASH_LATENCY
51+
#if defined(STM32H7)
52+
#define CORE_PLL_FREQ (96000000)
53+
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_2
54+
#else
5055
#define CORE_PLL_FREQ (48000000)
56+
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_1
57+
#endif
5158
#undef MICROPY_HW_CLK_PLLM
5259
#undef MICROPY_HW_CLK_PLLN
5360
#undef MICROPY_HW_CLK_PLLP
5461
#undef MICROPY_HW_CLK_PLLQ
55-
#undef MICROPY_HW_FLASH_LATENCY
62+
#undef MICROPY_HW_CLK_PLLR
5663
#define MICROPY_HW_CLK_PLLM (HSE_VALUE / 1000000)
5764
#define MICROPY_HW_CLK_PLLN (192)
58-
#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV4)
65+
#define MICROPY_HW_CLK_PLLP (MICROPY_HW_CLK_PLLN / (CORE_PLL_FREQ / 1000000))
5966
#define MICROPY_HW_CLK_PLLQ (4)
60-
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_1
67+
#define MICROPY_HW_CLK_PLLR (2)
6168

6269
// Work out which USB device to use for the USB DFU interface
6370
#if !defined(MICROPY_HW_USB_MAIN_DEV)
@@ -137,11 +144,25 @@ static void __fatal_error(const char *msg) {
137144
#define CONFIG_RCC_CR_2ND (RCC_CR_HSEON || RCC_CR_CSSON || RCC_CR_PLLON)
138145
#define CONFIG_RCC_PLLCFGR (0x24003010)
139146

147+
#elif defined(STM32H7)
148+
149+
#define CONFIG_RCC_CR_1ST (RCC_CR_HSION)
150+
#define CONFIG_RCC_CR_2ND (RCC_CR_PLL3ON | RCC_CR_PLL2ON | RCC_CR_PLL1ON | RCC_CR_CSSHSEON \
151+
| RCC_CR_HSEON | RCC_CR_HSI48ON | RCC_CR_CSIKERON | RCC_CR_CSION)
152+
#define CONFIG_RCC_PLLCFGR (0x00000000)
153+
140154
#else
141155
#error Unknown processor
142156
#endif
143157

144158
void SystemInit(void) {
159+
#if defined(STM32H7)
160+
// Configure write-once power options, and wait for voltage levels to be ready
161+
PWR->CR3 = PWR_CR3_LDOEN;
162+
while (!(PWR->CSR1 & PWR_CSR1_ACTVOSRDY)) {
163+
}
164+
#endif
165+
145166
// Set HSION bit
146167
RCC->CR |= CONFIG_RCC_CR_1ST;
147168

@@ -154,11 +175,27 @@ void SystemInit(void) {
154175
// Reset PLLCFGR register
155176
RCC->PLLCFGR = CONFIG_RCC_PLLCFGR;
156177

178+
#if defined(STM32H7)
179+
// Reset PLL and clock configuration registers
180+
RCC->D1CFGR = 0x00000000;
181+
RCC->D2CFGR = 0x00000000;
182+
RCC->D3CFGR = 0x00000000;
183+
RCC->PLLCKSELR = 0x00000000;
184+
RCC->D1CCIPR = 0x00000000;
185+
RCC->D2CCIP1R = 0x00000000;
186+
RCC->D2CCIP2R = 0x00000000;
187+
RCC->D3CCIPR = 0x00000000;
188+
#endif
189+
157190
// Reset HSEBYP bit
158191
RCC->CR &= (uint32_t)0xFFFBFFFF;
159192

160193
// Disable all interrupts
194+
#if defined(STM32F4) || defined(STM32F7)
161195
RCC->CIR = 0x00000000;
196+
#elif defined(STM32H7)
197+
RCC->CIER = 0x00000000;
198+
#endif
162199

163200
// Set location of vector table
164201
SCB->VTOR = FLASH_BASE;
@@ -173,6 +210,8 @@ void systick_init(void) {
173210
NVIC_SetPriority(SysTick_IRQn, IRQ_PRI_SYSTICK);
174211
}
175212

213+
#if defined(STM32F4) || defined(STM32F7)
214+
176215
void SystemClock_Config(void) {
177216
// This function assumes that HSI is used as the system clock (see RCC->CFGR, SWS bits)
178217

@@ -243,6 +282,87 @@ void SystemClock_Config(void) {
243282
#endif
244283
}
245284

285+
#elif defined(STM32H7)
286+
287+
void SystemClock_Config(void) {
288+
// This function assumes that HSI is used as the system clock (see RCC->CFGR, SWS bits)
289+
290+
// Select VOS level as high voltage to give reliable operation
291+
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
292+
while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) == RESET) {
293+
}
294+
295+
// Turn HSE on
296+
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
297+
while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) {
298+
}
299+
300+
// Disable PLL1
301+
__HAL_RCC_PLL_DISABLE();
302+
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) {
303+
}
304+
305+
// Configure PLL1 factors and source
306+
RCC->PLLCKSELR =
307+
MICROPY_HW_CLK_PLLM << RCC_PLLCKSELR_DIVM1_Pos
308+
| 2 << RCC_PLLCKSELR_PLLSRC_Pos; // HSE selected as PLL source
309+
RCC->PLL1DIVR =
310+
(MICROPY_HW_CLK_PLLN - 1) << RCC_PLL1DIVR_N1_Pos
311+
| (MICROPY_HW_CLK_PLLP - 1) << RCC_PLL1DIVR_P1_Pos // only even P allowed
312+
| (MICROPY_HW_CLK_PLLQ - 1) << RCC_PLL1DIVR_Q1_Pos
313+
| (MICROPY_HW_CLK_PLLR - 1) << RCC_PLL1DIVR_R1_Pos;
314+
315+
// Enable PLL1 outputs for SYSCLK and USB
316+
RCC->PLLCFGR = RCC_PLLCFGR_DIVP1EN | RCC_PLLCFGR_DIVQ1EN;
317+
318+
// Select PLL1-Q for USB clock source
319+
RCC->D2CCIP2R |= 1 << RCC_D2CCIP2R_USBSEL_Pos;
320+
321+
// Enable PLL1
322+
__HAL_RCC_PLL_ENABLE();
323+
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) {
324+
}
325+
326+
// Increase latency before changing SYSCLK
327+
if (MICROPY_HW_FLASH_LATENCY > (FLASH->ACR & FLASH_ACR_LATENCY)) {
328+
__HAL_FLASH_SET_LATENCY(MICROPY_HW_FLASH_LATENCY);
329+
}
330+
331+
// Configure AHB divider
332+
RCC->D1CFGR =
333+
0 << RCC_D1CFGR_D1CPRE_Pos // SYSCLK prescaler of 1
334+
| 8 << RCC_D1CFGR_HPRE_Pos // AHB prescaler of 2
335+
;
336+
337+
// Configure SYSCLK source from PLL
338+
__HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_PLLCLK);
339+
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL1) {
340+
}
341+
342+
// Decrease latency after changing clock
343+
if (MICROPY_HW_FLASH_LATENCY < (FLASH->ACR & FLASH_ACR_LATENCY)) {
344+
__HAL_FLASH_SET_LATENCY(MICROPY_HW_FLASH_LATENCY);
345+
}
346+
347+
// Set APB clock dividers
348+
RCC->D1CFGR |=
349+
4 << RCC_D1CFGR_D1PPRE_Pos // APB3 prescaler of 2
350+
;
351+
RCC->D2CFGR =
352+
4 << RCC_D2CFGR_D2PPRE2_Pos // APB2 prescaler of 2
353+
| 4 << RCC_D2CFGR_D2PPRE1_Pos // APB1 prescaler of 2
354+
;
355+
RCC->D3CF F987 GR =
356+
4 << RCC_D3CFGR_D3PPRE_Pos // APB4 prescaler of 2
357+
;
358+
359+
// Update clock value and reconfigure systick now that the frequency changed
360+
SystemCoreClock = CORE_PLL_FREQ;
361+
systick_init();
362+
}
363+
364+
#endif
365+
246366
// Needed by HAL_PCD_IRQHandler
247367
uint32_t HAL_RCC_GetHCLKFreq(void) {
248368
return SystemCoreClock;
@@ -251,13 +371,21 @@ uint32_t HAL_RCC_GetHCLKFreq(void) {
251371
/******************************************************************************/
252372
// GPIO
253373

374+
#if defined(STM32F4) || defined(STM32F7)
375+
#define AHBxENR AHB1ENR
376+
#define AHBxENR_GPIOAEN_Pos RCC_AHB1ENR_GPIOAEN_Pos
377+
#elif defined(STM32H7)
378+
#define AHBxENR AHB4ENR
379+
#define AHBxENR_GPIOAEN_Pos RCC_AHB4ENR_GPIOAEN_Pos
380+
#endif
381+
254382
void mp_hal_pin_config(mp_hal_pin_obj_t port_pin, uint32_t mode, uint32_t pull, uint32_t alt) {
255383
GPIO_TypeDef *gpio = (GPIO_TypeDef*)(port_pin & ~0xf);
256384

257385
// Enable the GPIO peripheral clock
258-
uint32_t en_bit = RCC_AHB1ENR_GPIOAEN_Pos + ((uintptr_t)gpio - GPIOA_BASE) / (GPIOB_BASE - GPIOA_BASE);
259-
RCC->AHB1ENR |= 1 << en_bit;
260-
volatile uint32_t tmp = RCC->AHB1ENR; // Delay after enabling clock
386+
uint32_t gpio_idx = ((uintptr_t)gpio - GPIOA_BASE) / (GPIOB_BASE - GPIOA_BASE);
387+
RCC->AHBxENR |= 1 << (AHBxENR_GPIOAEN_Pos + gpio_idx);
388+
volatile uint32_t tmp = RCC->AHBxENR; // Delay after enabling clock
261389
(void)tmp;
262390

263391
// Configure the pin
@@ -381,6 +509,14 @@ static const flash_layout_t flash_layout[] = {
381509
{ 0x08040000, 0x40000, 7 },
382510
};
383511

512+
#elif defined(STM32H743xx)
513+
514+
#define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/16*128Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT
515+
516+
static const flash_layout_t flash_layout[] = {
517+
{ 0x08000000, 0x20000, 16 },
518+
};
519+
384520
#endif
385521

386522
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) {
401537
return 0;
402538
}
403539

540+
#if defined(STM32H7)
541+
// get the bank of a given flash address
542+
static uint32_t get_bank(uint32_t addr) {
543+
if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_SWAP_BANK) == 0) {
544+
// no bank swap
545+
if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
546+
return FLASH_BANK_1;
547+
} else {
548+
return FLASH_BANK_2;
549+
}
550+
} else {
551+
// bank swap
552+
if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
553+
return FLASH_BANK_2;
554+
} else {
555+
return FLASH_BANK_1;
556+
}
557+
}
558+
}
559+
#endif
560+
404561
static int flash_mass_erase(void) {
405562
// TODO
406563
return -1;
@@ -419,13 +576,20 @@ static int flash_page_erase(uint32_t addr, uint32_t *next_addr) {
419576
HAL_FLASH_Unlock();
420577

421578
// Clear pending flags (if any)
579+
#if defined(STM32H7)
580+
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2);
581+
#else
422582
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
423583
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
584+
#endif
424585

425586
// erase the sector(s)
426587
FLASH_EraseInitTypeDef EraseInitStruct;
427588
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
428589
EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
590+
#if defined(STM32H7)
591+
EraseInitStruct.Banks = get_bank(addr);
592+
#endif
429593
EraseInitStruct.Sector = sector;
430594
EraseInitStruct.NbSectors = 1;
431595

@@ -454,6 +618,20 @@ static int flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
454618
const uint32_t *src = (const uint32_t*)src8;
455619
size_t num_word32 = (len + 3) / 4;
456620
HAL_FLASH_Unlock();
621+
622+
#if defined(STM32H7)
623+
624+
// program the flash 256 bits at a time
625+
for (int i = 0; i < num_word32 / 8; ++i) {
626+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, addr, (uint64_t)(uint32_t)src) != HAL_OK) {
627+
return - 1;
628+
}
629+
addr += 32;
630+
src += 8;
631+
}
632+
633+
#else
634+
457635
// program the flash word by word
458636
for (size_t i = 0; i < num_word32; i++) {
459637
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) {
463641
src += 1;
464642
}
465643

644+
#endif
645+
466646
// TODO verify data
467647

468648
return 0;
@@ -1130,6 +1310,11 @@ static void pyb_usbdd_init(pyb_usbdd_obj_t *self, int phy_id) {
11301310

11311311
static void pyb_usbdd_start(pyb_usbdd_obj_t *self) {
11321312
if (!self->started) {
1313+
#if defined(STM32H7)
1314+
PWR->CR3 |= PWR_CR3_USB33DEN;
1315+
while (!(PWR->CR3 & PWR_CR3_USB33RDY)) {
1316+
}
1317+
#endif
11331318
USBD_LL_Init(&self->hUSBDDevice, 0);
11341319
USBD_LL_Start(&self->hUSBDDevice);
11351320
self->started = true;
@@ -1249,8 +1434,8 @@ void stm32_main(int initial_r0) {
12491434
goto enter_bootloader;
12501435
}
12511436

1252-
// MCU starts up with 16MHz HSI
1253-
SystemCoreClock = 16000000;
1437+
// MCU starts up with HSI
1438+
SystemCoreClock = HSI_VALUE;
12541439

12551440
int reset_mode = get_reset_mode();
12561441
uint32_t msp = *(volatile uint32_t*)APPLICATION_ADDR;

ports/stm32/mboot/mphalport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,13 @@
4848
#define mp_hal_pin_input(p) mp_hal_pin_config((p), MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0)
4949
#define mp_hal_pin_output(p) mp_hal_pin_config((p), MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0)
5050
#define mp_hal_pin_open_drain(p) mp_hal_pin_config((p), MP_HAL_PIN_MODE_OPEN_DRAIN, MP_HAL_PIN_PULL_NONE, 0)
51+
#if defined(STM32H7)
52+
#define mp_hal_pin_low(p) (((GPIO_TypeDef*)((p) & ~0xf))->BSRRH = 1 << ((p) & 0xf))
53+
#define mp_hal_pin_high(p) (((GPIO_TypeDef*)((p) & ~0xf))->BSRRL = 1 << ((p) & 0xf))
54+
#else
5155
#define mp_hal_pin_low(p) (((GPIO_TypeDef*)((p) & ~0xf))->BSRR = 0x10000 << ((p) & 0xf))
5256
#define mp_hal_pin_high(p) (((GPIO_TypeDef*)((p) & ~0xf))->BSRR = 1 << ((p) & 0xf))
57+
#endif
5358
#define mp_hal_pin_od_low(p) mp_hal_pin_low(p)
5459
#define mp_hal_pin_od_high(p) mp_hal_pin_high(p)
5560
#define mp_hal_pin_read(p) ((((GPIO_TypeDef*)((p) & ~0xf))->IDR >> ((p) & 0xf)) & 1)

0 commit comments

Comments
 (0)
0