3
3
*
4
4
* The MIT License (MIT)
5
5
*
6
- * Copyright (c) 2017-2018 Damien P. George
6
+ * Copyright (c) 2017-2019 Damien P. George
7
7
*
8
8
* Permission is hereby granted, free of charge, to any person obtaining a copy
9
9
* of this software and associated documentation files (the "Software"), to deal
38
38
// This DFU code with polling runs in about 70% of the time of the ST bootloader
39
39
#define USE_USB_POLLING (1)
40
40
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
42
42
// to keep the MCU config as minimal as possible.
43
43
#define USE_CACHE (0)
44
44
45
45
// IRQ priorities (encoded values suitable for NVIC_SetPriority)
46
46
#define IRQ_PRI_SYSTICK (NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 0, 0))
47
47
#define IRQ_PRI_I2C (NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 1, 0))
48
48
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
50
55
#define CORE_PLL_FREQ (48000000)
56
+ #define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_1
57
+ #endif
51
58
#undef MICROPY_HW_CLK_PLLM
52
59
#undef MICROPY_HW_CLK_PLLN
53
60
#undef MICROPY_HW_CLK_PLLP
54
61
#undef MICROPY_HW_CLK_PLLQ
55
- #undef MICROPY_HW_FLASH_LATENCY
62
+ #undef MICROPY_HW_CLK_PLLR
56
63
#define MICROPY_HW_CLK_PLLM (HSE_VALUE / 1000000)
57
64
#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) )
59
66
#define MICROPY_HW_CLK_PLLQ (4)
60
- #define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_1
67
+ #define MICROPY_HW_CLK_PLLR (2)
61
68
62
69
// Work out which USB device to use for the USB DFU interface
63
70
#if !defined(MICROPY_HW_USB_MAIN_DEV )
@@ -137,11 +144,25 @@ static void __fatal_error(const char *msg) {
137
144
#define CONFIG_RCC_CR_2ND (RCC_CR_HSEON || RCC_CR_CSSON || RCC_CR_PLLON)
138
145
#define CONFIG_RCC_PLLCFGR (0x24003010)
139
146
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
+
140
154
#else
141
155
#error Unknown processor
142
156
#endif
143
157
144
158
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
+
145
166
// Set HSION bit
146
167
RCC -> CR |= CONFIG_RCC_CR_1ST ;
147
168
@@ -154,11 +175,27 @@ void SystemInit(void) {
154
175
// Reset PLLCFGR register
155
176
RCC -> PLLCFGR = CONFIG_RCC_PLLCFGR ;
156
177
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
+
157
190
// Reset HSEBYP bit
158
191
RCC -> CR &= (uint32_t )0xFFFBFFFF ;
159
192
160
193
// Disable all interrupts
194
+ #if defined(STM32F4 ) || defined(STM32F7 )
161
195
RCC -> CIR = 0x00000000 ;
196
+ #elif defined(STM32H7 )
197
+ RCC -> CIER = 0x00000000 ;
198
+ #endif
162
199
163
200
// Set location of vector table
164
201
SCB -> VTOR = FLASH_BASE ;
@@ -173,6 +210,8 @@ void systick_init(void) {
173
210
NVIC_SetPriority (SysTick_IRQn , IRQ_PRI_SYSTICK );
174
211
}
175
212
213
+ #if defined(STM32F4 ) || defined(STM32F7 )
214
+
176
215
void SystemClock_Config (void ) {
177
216
// This function assumes that HSI is used as the system clock (see RCC->CFGR, SWS bits)
178
217
@@ -243,6 +282,87 @@ void SystemClock_Config(void) {
243
282
#endif
244
283
}
245
284
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
10000
+ | (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
+
246
366
// Needed by HAL_PCD_IRQHandler
247
367
uint32_t HAL_RCC_GetHCLKFreq (void ) {
248
368
return SystemCoreClock ;
@@ -251,13 +371,21 @@ uint32_t HAL_RCC_GetHCLKFreq(void) {
251
371
/******************************************************************************/
252
372
// GPIO
253
373
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
+
254
382
void mp_hal_pin_config (mp_hal_pin_obj_t port_pin , uint32_t mode , uint32_t pull , uint32_t alt ) {
255
383
GPIO_TypeDef * gpio = (GPIO_TypeDef * )(port_pin & ~0xf );
256
384
257
385
// 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
261
389
(void )tmp ;
262
390
263
391
// Configure the pin
@@ -381,6 +509,14 @@ static const flash_layout_t flash_layout[] = {
381
509
{ 0x08040000 , 0x40000 , 7 },
382
510
};
383
511
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
+
384
520
#endif
385
521
386
522
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) {
401
537
return 0 ;
402
538
}
403
539
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
+
404
561
static int flash_mass_erase (void ) {
405
562
// TODO
406
563
return -1 ;
@@ -419,13 +576,20 @@ static int flash_page_erase(uint32_t addr, uint32_t *next_addr) {
419
576
HAL_FLASH_Unlock ();
420
577
421
578
// 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
422
582
__HAL_FLASH_CLEAR_FLAG (FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
423
583
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR );
584
+ #endif
424
585
425
586
// erase the sector(s)
426
587
FLASH_EraseInitTypeDef EraseInitStruct ;
427
588
EraseInitStruct .TypeErase = TYPEERASE_SECTORS ;
428
589
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
429
593
EraseInitStruct .Sector = sector ;
430
594
EraseInitStruct .NbSectors = 1 ;
431
595
@@ -454,6 +618,20 @@ static int flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
454
618
const uint32_t * src = (const uint32_t * )src8 ;
455
619
size_t num_word32 = (len + 3 ) / 4 ;
456
620
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
+
457
635
// program the flash word by word
458
636
for (size_t i = 0 ; i < num_word32 ; i ++ ) {
459
637
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) {
463
641
src += 1 ;
464
642
}
465
643
644
+ #endif
645
+
466
646
// TODO verify data
467
647
468
648
return 0 ;
@@ -1130,6 +1310,11 @@ static void pyb_usbdd_init(pyb_usbdd_obj_t *self, int phy_id) {
1130
1310
1131
1311
static void pyb_usbdd_start (pyb_usbdd_obj_t * self ) {
10000
tr>1132
1312
if (!self -> started ) {
1313
+ #if defined(STM32H7 )
1314
+ PWR -> CR3 |= PWR_CR3_USB33DEN ;
1315
+ while (!(PWR -> CR3 & PWR_CR3_USB33RDY )) {
1316
+ }
1317
+ #endif
1133
1318
USBD_LL_Init (& self -> hUSBDDevice , 0 );
1134
1319
USBD_LL_Start (& self -> hUSBDDevice );
1135
1320
self -> started = true;
@@ -1249,8 +1434,8 @@ void stm32_main(int initial_r0) {
1249
1434
goto enter_bootloader ;
1250
1435
}
1251
1436
1252
- // MCU starts up with 16MHz HSI
1253
- SystemCoreClock = 16000000 ;
1437
+ // MCU starts up with HSI
1438
+ SystemCoreClock = HSI_VALUE ;
1254
1439
1255
1440
int reset_mode = get_reset_mode ();
1256
1441
uint32_t msp = * (volatile uint32_t * )APPLICATION_ADDR ;
0 commit comments