mirror of
https://github.com/andreili/katapult.git
synced 2025-08-23 19:34:06 +02:00
stm32: Add support for flashing stm32h7 boards
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
3076dd081c
commit
88e208a083
@ -36,6 +36,9 @@ set_bootup_code(uint64_t code)
|
||||
uint64_t *req_code = (void*)&_stack_end;
|
||||
*req_code = code;
|
||||
barrier();
|
||||
#if __CORTEX_M >= 7
|
||||
SCB_CleanDCache_by_Addr((void*)req_code, sizeof(*req_code));
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
@ -18,5 +18,8 @@ try_request_canboot(void)
|
||||
uint64_t *req_sig = (uint64_t *)bl_vectors[0];
|
||||
irq_disable();
|
||||
*req_sig = REQUEST_CANBOOT;
|
||||
#if __CORTEX_M >= 7
|
||||
SCB_CleanDCache_by_Addr((void*)req_sig, sizeof(*req_sig));
|
||||
#endif
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
@ -76,10 +76,10 @@ choice
|
||||
bool "STM32G431" if 0
|
||||
select MACH_STM32G4
|
||||
config MACH_STM32H723
|
||||
bool "STM32H723" if 0
|
||||
bool "STM32H723"
|
||||
select MACH_STM32H7
|
||||
config MACH_STM32H743
|
||||
bool "STM32H743" if 0
|
||||
bool "STM32H743"
|
||||
select MACH_STM32H7
|
||||
config MACH_STM32H750
|
||||
bool "STM32H750" if 0
|
||||
@ -184,6 +184,7 @@ config FLASH_BOOT_ADDRESS
|
||||
|
||||
config RAM_START
|
||||
hex
|
||||
default 0x24000000 if MACH_STM32H7 # Use "AXI SRAM" to persist reboot flag
|
||||
default 0x20000000
|
||||
|
||||
config RAM_SIZE
|
||||
@ -478,6 +479,8 @@ config FLASH_START
|
||||
|
||||
choice
|
||||
prompt "Application start offset"
|
||||
config STM32_APP_START_20000
|
||||
bool "128KiB offset" if MACH_STM32H7
|
||||
config STM32_APP_START_8000
|
||||
bool "32KiB offset" if MACH_STM32F2 || MACH_STM32F4
|
||||
config STM32_APP_START_4000
|
||||
@ -490,6 +493,7 @@ endchoice
|
||||
|
||||
config LAUNCH_APP_ADDRESS
|
||||
hex
|
||||
default 0x8020000 if STM32_APP_START_20000
|
||||
default 0x8008000 if STM32_APP_START_8000
|
||||
default 0x8004000 if STM32_APP_START_4000
|
||||
default 0x8002000 if STM32_APP_START_2000
|
||||
|
@ -9,6 +9,7 @@ dirs-$(CONFIG_MACH_STM32F1) += lib/stm32f1
|
||||
dirs-$(CONFIG_MACH_STM32F2) += lib/stm32f2
|
||||
dirs-$(CONFIG_MACH_STM32F4) += lib/stm32f4
|
||||
dirs-$(CONFIG_MACH_STM32G0) += lib/stm32g0
|
||||
dirs-$(CONFIG_MACH_STM32H7) += lib/stm32h7
|
||||
|
||||
MCU := $(shell echo $(CONFIG_MCU))
|
||||
MCU_UPPER := $(shell echo $(CONFIG_MCU) | tr a-z A-Z | tr X x)
|
||||
@ -18,6 +19,7 @@ CFLAGS-$(CONFIG_MACH_STM32F1) += -mcpu=cortex-m3 -Ilib/stm32f1/include
|
||||
CFLAGS-$(CONFIG_MACH_STM32F2) += -mcpu=cortex-m3 -Ilib/stm32f2/include
|
||||
CFLAGS-$(CONFIG_MACH_STM32F4) += -mcpu=cortex-m4 -Ilib/stm32f4/include
|
||||
CFLAGS-$(CONFIG_MACH_STM32G0) += -mcpu=cortex-m0plus -Ilib/stm32g0/include
|
||||
CFLAGS-$(CONFIG_MACH_STM32H7) += -mcpu=cortex-m7 -Ilib/stm32h7/include
|
||||
CFLAGS += $(CFLAGS-y) -D$(MCU_UPPER) -mthumb -Ilib/cmsis-core -Ilib/fast-hash
|
||||
|
||||
CFLAGS_canboot.elf += --specs=nano.specs --specs=nosys.specs
|
||||
@ -45,6 +47,10 @@ mcu-$(CONFIG_MACH_STM32F4) += stm32/gpioperiph.c
|
||||
mcu-$(CONFIG_MACH_STM32G0) += stm32/stm32f0_timer.c
|
||||
mcu-$(CONFIG_MACH_STM32G0) += stm32/stm32g0.c stm32/gpioperiph.c
|
||||
|
||||
mcu-$(CONFIG_MACH_STM32H7) += ../lib/stm32h7/system_stm32h7xx.c
|
||||
mcu-$(CONFIG_MACH_STM32H7) += stm32/stm32h7.c generic/armcm_timer.c
|
||||
mcu-$(CONFIG_MACH_STM32H7) += stm32/gpioperiph.c
|
||||
|
||||
src-y += generic/armcm_canboot.c $(mcu-y)
|
||||
usb-src-$(CONFIG_HAVE_STM32_USBFS) := stm32/usbfs.c
|
||||
usb-src-$(CONFIG_HAVE_STM32_USBOTG) := stm32/usbotg.c
|
||||
@ -52,7 +58,7 @@ src-$(CONFIG_USBSERIAL) += $(usb-src-y) stm32/chipid.c generic/usb_cdc.c
|
||||
serial-src-y := stm32/serial.c
|
||||
serial-src-$(CONFIG_MACH_STM32F0) := stm32/stm32f0_serial.c
|
||||
serial-src-$(CONFIG_MACH_STM32G0) := stm32/stm32f0_serial.c
|
||||
serial-src-$(CONFIG_MACH_STM32H7) := stm32/stm32h7_serial.c
|
||||
serial-src-$(CONFIG_MACH_STM32H7) := stm32/stm32f0_serial.c
|
||||
src-$(CONFIG_SERIAL) += $(serial-src-y) generic/serial_irq.c
|
||||
canbus-src-y := generic/canserial.c ../lib/fast-hash/fasthash.c
|
||||
canbus-src-$(CONFIG_HAVE_STM32_CANBUS) += stm32/can.c
|
||||
|
@ -34,6 +34,8 @@ flash_get_page_size(uint32_t addr)
|
||||
return *flash_size <= 64 ? 1024 : 2 * 1024;
|
||||
} else if (CONFIG_MACH_STM32G0) {
|
||||
return 2 * 1024;
|
||||
} else if (CONFIG_MACH_STM32H7) {
|
||||
return 128 * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,8 +50,13 @@ check_erased(uint32_t addr, uint32_t count)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if CONFIG_MACH_STM32G0 // stm32g0 chip has slightly different bit name
|
||||
// Some chips have slightly different register names
|
||||
#if CONFIG_MACH_STM32G0
|
||||
#define FLASH_SR_BSY (FLASH_SR_BSY1 | FLASH_SR_BSY2)
|
||||
#elif CONFIG_MACH_STM32H7
|
||||
#define CR CR1
|
||||
#define SR SR1
|
||||
#define KEYR KEYR1
|
||||
#endif
|
||||
|
||||
// Wait for flash hardware to report ready
|
||||
@ -114,6 +121,13 @@ erase_page(uint32_t page_address)
|
||||
}
|
||||
pidx = pidx > 0x3ff ? 0x3ff : pidx;
|
||||
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT | (pidx << FLASH_CR_PNB_Pos);
|
||||
#elif CONFIG_MACH_STM32H7
|
||||
uint32_t snb = (page_address - 0x08000000) / (128 * 1024);
|
||||
snb = snb > 7 ? 7 : snb;
|
||||
FLASH->CR = FLASH_CR_SER | FLASH_CR_START | (snb << FLASH_CR_SNB_Pos);
|
||||
while (FLASH->SR & FLASH_SR_QW)
|
||||
;
|
||||
SCB_InvalidateDCache_by_Addr((void*)page_address, 128*1024);
|
||||
#endif
|
||||
wait_flash();
|
||||
}
|
||||
@ -144,6 +158,23 @@ write_block(uint32_t block_address, uint32_t *data)
|
||||
writel(&page[i*2 + 1], data[i*2 + 1]);
|
||||
wait_flash();
|
||||
}
|
||||
#elif CONFIG_MACH_STM32H7
|
||||
uint32_t *page = (void*)block_address;
|
||||
FLASH->CR = FLASH_CR_PG;
|
||||
for (int i = 0; i < CONFIG_BLOCK_SIZE / 32; i++) {
|
||||
writel(&page[i*8], data[i*8]);
|
||||
writel(&page[i*8 + 1], data[i*8 + 1]);
|
||||
writel(&page[i*8 + 2], data[i*8 + 2]);
|
||||
writel(&page[i*8 + 3], data[i*8 + 3]);
|
||||
writel(&page[i*8 + 4], data[i*8 + 4]);
|
||||
writel(&page[i*8 + 5], data[i*8 + 5]);
|
||||
writel(&page[i*8 + 6], data[i*8 + 6]);
|
||||
writel(&page[i*8 + 7], data[i*8 + 7]);
|
||||
while (FLASH->SR & FLASH_SR_QW)
|
||||
;
|
||||
wait_flash();
|
||||
}
|
||||
SCB_InvalidateDCache_by_Addr((void*)block_address, CONFIG_BLOCK_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
241
src/stm32/stm32h7.c
Normal file
241
src/stm32/stm32h7.c
Normal file
@ -0,0 +1,241 @@
|
||||
// Code to setup clocks on stm32h7
|
||||
//
|
||||
// Copyright (C) 2020 Konstantin Vogel <konstantin.vogel@gmx.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
|
||||
#include "board/armcm_boot.h" // VectorTable
|
||||
#include "board/armcm_reset.h" // try_request_canboot
|
||||
#include "board/irq.h" // irq_disable
|
||||
#include "board/misc.h" // bootloader_request
|
||||
#include "command.h" // DECL_CONSTANT_STR
|
||||
#include "internal.h" // get_pclock_frequency
|
||||
#include "sched.h" // sched_main
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Clock setup
|
||||
****************************************************************/
|
||||
|
||||
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 4)
|
||||
|
||||
// Map a peripheral address to its enable bits
|
||||
struct cline
|
||||
lookup_clock_line(uint32_t periph_base)
|
||||
{
|
||||
if (periph_base >= D3_AHB1PERIPH_BASE) {
|
||||
uint32_t bit = 1 << ((periph_base - D3_AHB1PERIPH_BASE) / 0x400);
|
||||
return (struct cline){.en=&RCC->AHB4ENR, .rst=&RCC->AHB4RSTR, .bit=bit};
|
||||
} else if (periph_base >= D3_APB1PERIPH_BASE) {
|
||||
uint32_t bit = 1 << ((periph_base - D3_APB1PERIPH_BASE) / 0x400);
|
||||
return (struct cline){.en=&RCC->APB4ENR, .rst=&RCC->APB4RSTR, .bit=bit};
|
||||
} else if (periph_base >= D1_AHB1PERIPH_BASE) {
|
||||
uint32_t bit = 1 << ((periph_base - D1_AHB1PERIPH_BASE) / 0x400);
|
||||
return (struct cline){.en=&RCC->AHB3ENR, .rst=&RCC->AHB3RSTR, .bit=bit};
|
||||
} else if (periph_base >= D1_APB1PERIPH_BASE) {
|
||||
uint32_t bit = 1 << ((periph_base - D1_APB1PERIPH_BASE) / 0x400);
|
||||
return (struct cline){.en=&RCC->APB3ENR, .rst=&RCC->APB3RSTR, .bit=bit};
|
||||
} else if (periph_base >= D2_AHB2PERIPH_BASE) {
|
||||
uint32_t bit = 1 << ((periph_base - D2_AHB2PERIPH_BASE) / 0x400);
|
||||
return (struct cline){.en=&RCC->AHB2ENR, .rst=&RCC->AHB2RSTR, .bit=bit};
|
||||
} else if (periph_base >= D2_AHB1PERIPH_BASE) {
|
||||
uint32_t bit = 1 << ((periph_base - D2_AHB1PERIPH_BASE) / 0x400);
|
||||
return (struct cline){.en=&RCC->AHB1ENR, .rst=&RCC->AHB1RSTR, .bit=bit};
|
||||
} else if (periph_base >= D2_APB2PERIPH_BASE) {
|
||||
uint32_t bit = 1 << ((periph_base - D2_APB2PERIPH_BASE) / 0x400);
|
||||
return (struct cline){.en=&RCC->APB2ENR, .rst=&RCC->APB2RSTR, .bit=bit};
|
||||
} else {
|
||||
uint32_t offset = ((periph_base - D2_APB1PERIPH_BASE) / 0x400);
|
||||
if (offset < 32) {
|
||||
uint32_t bit = 1 << offset;
|
||||
return (struct cline){
|
||||
.en=&RCC->APB1LENR, .rst=&RCC->APB1LRSTR, .bit=bit};
|
||||
} else {
|
||||
uint32_t bit = 1 << (offset - 32);
|
||||
return (struct cline){
|
||||
.en=&RCC->APB1HENR, .rst=&RCC->APB1HRSTR, .bit=bit};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the frequency of the given peripheral clock
|
||||
uint32_t
|
||||
get_pclock_frequency(uint32_t periph_base)
|
||||
{
|
||||
return FREQ_PERIPH;
|
||||
}
|
||||
|
||||
// Enable a GPIO peripheral clock
|
||||
void
|
||||
gpio_clock_enable(GPIO_TypeDef *regs)
|
||||
{
|
||||
uint32_t pos = ((uint32_t)regs - D3_AHB1PERIPH_BASE) / 0x400;
|
||||
RCC->AHB4ENR |= (1<<pos);
|
||||
RCC->AHB4ENR;
|
||||
}
|
||||
|
||||
#if !CONFIG_STM32_CLOCK_REF_INTERNAL
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PH0,PH1");
|
||||
#endif
|
||||
|
||||
// Main clock and power setup called at chip startup
|
||||
static void
|
||||
clock_setup(void)
|
||||
{
|
||||
#if !CONFIG_MACH_STM32H723
|
||||
// Ensure USB OTG ULPI is not enabled
|
||||
CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_USB2OTGHSULPIEN);
|
||||
CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_USB2OTGHSULPILPEN);
|
||||
#endif
|
||||
// Set this despite correct defaults.
|
||||
// "The software has to program the supply configuration in PWR control
|
||||
// register 3" (pg. 259)
|
||||
// Only a single write is allowed (pg. 304)
|
||||
PWR->CR3 = (PWR->CR3 | PWR_CR3_LDOEN) & ~(PWR_CR3_BYPASS | PWR_CR3_SCUEN);
|
||||
while (!(PWR->CSR1 & PWR_CSR1_ACTVOSRDY))
|
||||
;
|
||||
// (HSE 25mhz) /DIVM1(5) (pll_base 5Mhz) *DIVN1(192) (pll_freq 960Mhz)
|
||||
// /DIVP1(2) (SYSCLK 480Mhz)
|
||||
uint32_t pll_base = 5000000;
|
||||
// Only even dividers (DIVP1) are allowed
|
||||
uint32_t pll_freq = CONFIG_CLOCK_FREQ * 2;
|
||||
if (!CONFIG_STM32_CLOCK_REF_INTERNAL) {
|
||||
// Configure PLL from external crystal (HSE)
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while(!(RCC->CR & RCC_CR_HSERDY))
|
||||
;
|
||||
MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_PLLSRC_Msk,
|
||||
RCC_PLLCKSELR_PLLSRC_HSE);
|
||||
MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM1_Msk,
|
||||
(CONFIG_CLOCK_REF_FREQ/pll_base) << RCC_PLLCKSELR_DIVM1_Pos);
|
||||
} else {
|
||||
// Configure PLL from internal 64Mhz oscillator (HSI)
|
||||
// HSI frequency of 64Mhz is integer divisible with 4Mhz
|
||||
pll_base = 4000000;
|
||||
MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_PLLSRC_Msk,
|
||||
RCC_PLLCKSELR_PLLSRC_HSI);
|
||||
MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM1_Msk,
|
||||
(64000000/pll_base) << RCC_PLLCKSELR_DIVM1_Pos);
|
||||
}
|
||||
// Set input frequency range of PLL1 according to pll_base
|
||||
// 3 = 8-16Mhz, 2 = 4-8Mhz
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLL1RGE_Msk, RCC_PLLCFGR_PLL1RGE_2);
|
||||
// Disable unused PLL1 outputs
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_DIVR1EN_Msk, 0);
|
||||
// Enable PLL1Q and set to 100MHz for SPI 1,2,3
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_DIVQ1EN, RCC_PLLCFGR_DIVQ1EN);
|
||||
MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_Q1,
|
||||
(pll_freq / FREQ_PERIPH - 1) << RCC_PLL1DIVR_Q1_Pos);
|
||||
// This is necessary, default is not 1!
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_DIVP1EN_Msk, RCC_PLLCFGR_DIVP1EN);
|
||||
// Set multiplier DIVN1 and post divider DIVP1
|
||||
// 001 = /2, 010 = not allowed, 0011 = /4 ...
|
||||
MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_N1_Msk,
|
||||
(pll_freq/pll_base - 1) << RCC_PLL1DIVR_N1_Pos);
|
||||
MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_P1_Msk,
|
||||
(pll_freq/CONFIG_CLOCK_FREQ - 1) << RCC_PLL1DIVR_P1_Pos);
|
||||
|
||||
// Pwr
|
||||
MODIFY_REG(PWR->D3CR, PWR_D3CR_VOS_Msk, PWR_D3CR_VOS);
|
||||
while (!(PWR->D3CR & PWR_D3CR_VOSRDY))
|
||||
;
|
||||
|
||||
// Enable VOS0 (overdrive)
|
||||
if (CONFIG_CLOCK_FREQ > 400000000) {
|
||||
RCC->APB4ENR |= RCC_APB4ENR_SYSCFGEN;
|
||||
#if !CONFIG_MACH_STM32H723
|
||||
SYSCFG->PWRCR |= SYSCFG_PWRCR_ODEN;
|
||||
#else
|
||||
PWR->CR3 |= PWR_CR3_BYPASS;
|
||||
#endif
|
||||
while (!(PWR->D3CR & PWR_D3CR_VOSRDY))
|
||||
;
|
||||
}
|
||||
|
||||
SCB_EnableICache();
|
||||
SCB_EnableDCache();
|
||||
|
||||
// Set flash latency according to clock frequency (pg.159)
|
||||
uint32_t flash_acr_latency = (CONFIG_CLOCK_FREQ > 450000000) ?
|
||||
FLASH_ACR_LATENCY_4WS : FLASH_ACR_LATENCY_2WS;
|
||||
MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY_Msk, flash_acr_latency);
|
||||
MODIFY_REG(FLASH->ACR, FLASH_ACR_WRHIGHFREQ_Msk, FLASH_ACR_WRHIGHFREQ_1);
|
||||
while (!(FLASH->ACR & flash_acr_latency))
|
||||
;
|
||||
|
||||
// Set HPRE, D1PPRE, D2PPRE, D2PPRE2, D3PPRE dividers
|
||||
// 480MHz / 2 = 240MHz rcc_hclk3
|
||||
MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_HPRE, RCC_D1CFGR_HPRE_3);
|
||||
// 240MHz / 2 = 120MHz rcc_pclk3
|
||||
MODIFY_REG(RCC->D1CFGR, RCC_D1CFGR_D1PPRE, RCC_D1CFGR_D1PPRE_DIV2);
|
||||
// 240MHz / 2 = 120MHz rcc_pclk1
|
||||
MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE1, RCC_D2CFGR_D2PPRE1_DIV2);
|
||||
// 240MHz / 2 = 120MHz rcc_pclk2
|
||||
MODIFY_REG(RCC->D2CFGR, RCC_D2CFGR_D2PPRE2, RCC_D2CFGR_D2PPRE2_DIV2);
|
||||
// 240MHz / 2 = 120MHz rcc_pclk4
|
||||
MODIFY_REG(RCC->D3CFGR, RCC_D3CFGR_D3PPRE, RCC_D3CFGR_D3PPRE_DIV2);
|
||||
|
||||
// Switch on PLL1
|
||||
RCC->CR |= RCC_CR_PLL1ON;
|
||||
while (!(RCC->CR & RCC_CR_PLL1RDY))
|
||||
;
|
||||
|
||||
// Switch system clock source (SYSCLK) to PLL1
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW_Msk, RCC_CFGR_SW_PLL1);
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL1)
|
||||
;
|
||||
|
||||
// Set the source of FDCAN clock
|
||||
MODIFY_REG(RCC->D2CCIP1R, RCC_D2CCIP1R_FDCANSEL, RCC_D2CCIP1R_FDCANSEL_0);
|
||||
|
||||
// Configure HSI48 clock for USB
|
||||
if (CONFIG_USB) {
|
||||
SET_BIT(RCC->CR, RCC_CR_HSI48ON);
|
||||
while((RCC->CR & RCC_CR_HSI48RDY) == 0);
|
||||
SET_BIT(RCC->APB1HENR, RCC_APB1HENR_CRSEN);
|
||||
SET_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_CRSRST);
|
||||
CLEAR_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_CRSRST);
|
||||
CLEAR_BIT(CRS->CFGR, CRS_CFGR_SYNCSRC);
|
||||
SET_BIT(CRS->CR, CRS_CR_CEN | CRS_CR_AUTOTRIMEN);
|
||||
CLEAR_BIT(RCC->D2CCIP2R, RCC_D2CCIP2R_USBSEL);
|
||||
SET_BIT(RCC->D2CCIP2R, RCC_D2CCIP2R_USBSEL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Bootloader
|
||||
****************************************************************/
|
||||
|
||||
// Handle reboot requests
|
||||
void
|
||||
bootloader_request(void)
|
||||
{
|
||||
try_request_canboot();
|
||||
dfu_reboot();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Startup
|
||||
****************************************************************/
|
||||
|
||||
// Main entry point - called from armcm_boot.c:ResetHandler()
|
||||
void
|
||||
armcm_main(void)
|
||||
{
|
||||
// Run SystemInit() and then restore VTOR
|
||||
SystemInit();
|
||||
RCC->D1CCIPR = 0x00000000;
|
||||
RCC->D2CCIP1R = 0x00000000;
|
||||
RCC->D2CCIP2R = 0x00000000;
|
||||
RCC->D3CCIPR = 0x00000000;
|
||||
SCB->VTOR = (uint32_t)VectorTable;
|
||||
|
||||
dfu_reboot_check();
|
||||
|
||||
clock_setup();
|
||||
|
||||
sched_main();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user