stm32f4xx: Significant rework of STM32F4 startup code.

Now it's pure C-based and unified.

Need to bring the other STM32 families up to the same level of smarts.
This commit is contained in:
Solomon Peachy 2013-12-19 15:50:51 -05:00
parent 65ac5c8bae
commit 50cdb0043a
5 changed files with 473 additions and 10 deletions

View File

@ -9,9 +9,9 @@
#define MCU_EXTSRAM_SIZE (0) #define MCU_EXTSRAM_SIZE (0)
#define MCU_EXTSRAM_BASE (0x68000000) #define MCU_EXTSRAM_BASE (0x68000000)
#define MCU_FLASH_BASE (0x08000000) #define MCU_FLASH_BASE (0x08000000)
#define MCU_FLASH_SIZE (2048*1024) #define MCU_FLASH_SIZE (1024*1024)
#define MCU_FLASH_PAGE_SIZE 2048 #define MCU_FLASH_PAGE_SIZE 2048
#define MCU_FLASH_IMAGE_SIZE (2046*1024) #define MCU_FLASH_IMAGE_SIZE (1022*1024)
#define MCU_STACK_SIZE 0x200 #define MCU_STACK_SIZE 512
#endif #endif

View File

@ -89,11 +89,15 @@ task.h is included from an application file. */
/* Assumes 8bit bytes! */ /* Assumes 8bit bytes! */
#define heapBITS_PER_BYTE ( ( size_t ) 8 ) #define heapBITS_PER_BYTE ( ( size_t ) 8 )
#ifdef INTERNAL_HEAP /* XXXX */
/* A few bytes might be lost to byte aligning the heap start address. */ /* A few bytes might be lost to byte aligning the heap start address. */
#define heapADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) #define heapADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
/* Allocate the memory for the heap. */ /* Allocate the memory for the heap. */
static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
#else
unsigned char *ucHeap;
#endif
/* Define the linked list structure. This is used to link free blocks in order /* Define the linked list structure. This is used to link free blocks in order
of their memory address. */ of their memory address. */
@ -125,15 +129,23 @@ static void prvHeapInit( void );
block must by correctly byte aligned. */ block must by correctly byte aligned. */
static const unsigned short heapSTRUCT_SIZE = ( ( sizeof ( xBlockLink ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); static const unsigned short heapSTRUCT_SIZE = ( ( sizeof ( xBlockLink ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
#ifdef INTERNAL_HEAP /* XXX */
/* Ensure the pxEnd pointer will end up on the correct byte alignment. */ /* Ensure the pxEnd pointer will end up on the correct byte alignment. */
static const size_t xTotalHeapSize = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); static const size_t xTotalHeapSize = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
#else
size_t xTotalHeapSize;
#endif
/* Create a couple of list links to mark the start and end of the list. */ /* Create a couple of list links to mark the start and end of the list. */
static xBlockLink xStart, *pxEnd = NULL; static xBlockLink xStart, *pxEnd = NULL;
/* Keeps track of the number of free bytes remaining, but says nothing about /* Keeps track of the number of free bytes remaining, but says nothing about
fragmentation. */ fragmentation. */
#ifdef INTERNAL_HEAP /* XXX */
static size_t xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); static size_t xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK );
#else
size_t xFreeBytesRemaining;
#endif
/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize /* Gets set to the top bit of an size_t type. When this bit in the xBlockSize
member of an xBlockLink structure is set then the block belongs to the member of an xBlockLink structure is set then the block belongs to the

View File

@ -3,6 +3,9 @@ ENTRY(Reset_Handler)
MEMORY { MEMORY {
SRAM (RWX) : ORIGIN = MCU_SRAM_BASE , LENGTH = MCU_SRAM_SIZE SRAM (RWX) : ORIGIN = MCU_SRAM_BASE , LENGTH = MCU_SRAM_SIZE
EXTSRAM (RWX) : ORIGIN = MCU_EXTSRAM_BASE , LENGTH = MCU_EXTSRAM_SIZE EXTSRAM (RWX) : ORIGIN = MCU_EXTSRAM_BASE , LENGTH = MCU_EXTSRAM_SIZE
#ifdef MCU_CCRAM_BASE
CCMRAM (RWX) : ORIGIN = MCU_CCRAM_BASE, LENGTH = MCU_CCRAM_SIZE
#endif
FLASH (RX) : ORIGIN = MCU_FLASH_BASE , LENGTH = MCU_FLASH_SIZE FLASH (RX) : ORIGIN = MCU_FLASH_BASE , LENGTH = MCU_FLASH_SIZE
EEMUL (RWX) : ORIGIN = MCU_FLASH_BASE + MCU_FLASH_SIZE - MCU_FLASH_PAGE_SIZE, LENGTH = MCU_FLASH_PAGE_SIZE EEMUL (RWX) : ORIGIN = MCU_FLASH_BASE + MCU_FLASH_SIZE - MCU_FLASH_PAGE_SIZE, LENGTH = MCU_FLASH_PAGE_SIZE
} }
@ -10,6 +13,7 @@ MEMORY {
_estack = ORIGIN(SRAM)+LENGTH(SRAM); /* end of the stack */ _estack = ORIGIN(SRAM)+LENGTH(SRAM); /* end of the stack */
_seemul = ORIGIN(EEMUL); /* start of the eeprom emulation area */ _seemul = ORIGIN(EEMUL); /* start of the eeprom emulation area */
_min_stack = MCU_STACK_SIZE; /* minimum stack space to reserve for the user app */ _min_stack = MCU_STACK_SIZE; /* minimum stack space to reserve for the user app */
_eheap = _estack - _min_stack; /* Heap end is beginning of stack */
/* check valid alignment for the vector table */ /* check valid alignment for the vector table */
ASSERT(ORIGIN(FLASH) == ALIGN(ORIGIN(FLASH), 0x80), "Start of memory region flash not aligned for startup vector table"); ASSERT(ORIGIN(FLASH) == ALIGN(ORIGIN(FLASH), 0x80), "Start of memory region flash not aligned for startup vector table");
@ -18,7 +22,7 @@ SECTIONS {
/* vector table and program code goes into FLASH */ /* vector table and program code goes into FLASH */
.text : { .text : {
. = ALIGN(0x80); . = ALIGN(0x80);
_isr_vectors_offs = . - 0x08000000; _isr_vectors_offs = . - MCU_FLASH_BASE;
KEEP(*(.isr_vector)) KEEP(*(.isr_vector))
. = ALIGN(4); . = ALIGN(4);
CREATE_OBJECT_SYMBOLS CREATE_OBJECT_SYMBOLS
@ -106,7 +110,9 @@ SECTIONS {
_ebss = . ; /* exported for the startup function */ _ebss = . ; /* exported for the startup function */
_end = .; _end = .;
__end = .; __end = .;
_sheap = . ; /* exported for the startup function */
} >SRAM AT>FLASH } >SRAM AT>FLASH
#if 0
/* ensure there is enough room for the user stack */ /* ensure there is enough room for the user stack */
._usrstack (NOLOAD): { ._usrstack (NOLOAD): {
. = ALIGN(4); . = ALIGN(4);
@ -115,7 +121,7 @@ SECTIONS {
. = ALIGN(4); . = ALIGN(4);
_eusrstack = . ; _eusrstack = . ;
} >SRAM } >SRAM
#endif
/* Stabs debugging sections. */ /* Stabs debugging sections. */
.stab 0 : { *(.stab) } .stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) } .stabstr 0 : { *(.stabstr) }

View File

@ -11,8 +11,8 @@ MCU_CPPFLAGS += -D"assert_param(expr)=((void)0)"
MCU_CFLAGS += -mcpu=cortex-m4 -mthumb -Wa,-mthumb MCU_CFLAGS += -mcpu=cortex-m4 -mthumb -Wa,-mthumb
# CMSIS # CMSIS
STARTUP_OBJS = $(LIBDIR)/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.o $(LIBDIR)/startup_$(MCU_SUBTYPE).o #STARTUP_OBJS = $(LIBDIR)/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.o $(LIBDIR)/startup_$(MCU_SUBTYPE).o
STARTUP_OBJS = src/startup_$(MCU).o
# Standard Peripheral Library # Standard Peripheral Library
STM32F4xx_OBJSR = misc.o stm32f4xx_dma.o stm32f4xx_rcc.o stm32f4xx_adc.o \ STM32F4xx_OBJSR = misc.o stm32f4xx_dma.o stm32f4xx_rcc.o stm32f4xx_adc.o \
@ -31,6 +31,6 @@ STM32F4xx_OBJS += $(addprefix $(LIBDIR)/STM32F4xx_StdPeriph_Driver/src/,$(STM32F
MCU_LIBS_OBJS += $(STM32F4xx_OBJS) MCU_LIBS_OBJS += $(STM32F4xx_OBJS)
# Build Rules # Build Rules
$(LIBDIR)/startup_$(MCU_SUBTYPE).o: $(LIBDIR)/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_$(MCU_SUBTYPE).s #$(LIBDIR)/startup_$(MCU_SUBTYPE).o: $(LIBDIR)/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_$(MCU_SUBTYPE).s
@$(E) " AS " $@ # @$(E) " AS " $@
$(Q)$(AS) -c -o $@ $< # $(Q)$(AS) -c -o $@ $<

445
src/startup_stm32f4xx.c Normal file
View File

@ -0,0 +1,445 @@
#include <stdint.h>
#include <sys/types.h>
#include "stm32f4xx.h"
#include "misc.h"
typedef void( *const intfunc )( void );
#define WEAK_HANDLER(__x) void __x (void) __attribute ((weak, alias("Default_Handler")));
/* All of these are exposed by the linker script */
extern unsigned long _etext;
extern unsigned long _sidata;
extern unsigned long _sdata;
extern unsigned long _edata;
extern unsigned long _sbss;
extern unsigned long _ebss;
extern unsigned long _estack;
extern unsigned long _sheap;
extern unsigned long _eheap;
extern uint32_t _isr_vectors_offs;
/* Main */
extern int main(void);
#ifdef INTERNAL_HEAP
/* Track heap */
size_t heapremain;
size_t heapsize;
void *heap_ptr;
#else
extern unsigned char *ucHeap;
extern size_t xTotalHeapSize;
extern size_t xFreeBytesRemaining;
#endif
static void __Init_Data(void) {
unsigned long *src, *dst;
/* copy the data segment into ram */
src = &_sidata;
dst = &_sdata;
if (src != dst)
while(dst < &_edata)
*(dst++) = *(src++);
/* zero the bss segment */
dst = &_sbss;
while(dst < &_ebss)
*(dst++) = 0;
#ifdef INTERNAL_HEAP
/* Initialize Heap */
heapremain = heapsize = &_eheap - &_sheap;
heap_ptr = (void*) &_sheap;
#else
ucHeap = (unsigned char *) &_sheap;
xTotalHeapSize = xFreeBytesRemaining = &_eheap - &_sheap;
#endif
}
/* Endless loop for our default handler */
void Default_Handler(void) {
while (1) {}
}
//WEAK_HANDLER(Reset_Handler);
WEAK_HANDLER(NMI_Handler);
WEAK_HANDLER(HardFault_Handler);
WEAK_HANDLER(MemManage_Handler);
WEAK_HANDLER(BusFault_Handler);
WEAK_HANDLER(UsageFault_Handler);
WEAK_HANDLER(SVC_Handler);
WEAK_HANDLER(DebugMon_Handler);
WEAK_HANDLER(PendSV_Handler);
WEAK_HANDLER(SysTick_Handler);
WEAK_HANDLER(WWDG_IRQHandler);
WEAK_HANDLER(PVD_IRQHandler);
WEAK_HANDLER(TAMP_STAMP_IRQHandler);
WEAK_HANDLER(RTC_WKUP_IRQHandler);
WEAK_HANDLER(FLASH_IRQHandler);
WEAK_HANDLER(RCC_IRQHandler);
WEAK_HANDLER(EXTI0_IRQHandler);
WEAK_HANDLER(EXTI1_IRQHandler);
WEAK_HANDLER(EXTI2_IRQHandler);
WEAK_HANDLER(EXTI3_IRQHandler);
WEAK_HANDLER(EXTI4_IRQHandler);
WEAK_HANDLER(DMA1_Stream0_IRQHandler);
WEAK_HANDLER(DMA1_Stream1_IRQHandler);
WEAK_HANDLER(DMA1_Stream2_IRQHandler);
WEAK_HANDLER(DMA1_Stream3_IRQHandler);
WEAK_HANDLER(DMA1_Stream4_IRQHandler);
WEAK_HANDLER(DMA1_Stream5_IRQHandler);
WEAK_HANDLER(DMA1_Stream6_IRQHandler);
WEAK_HANDLER(ADC1_IRQHandler);
WEAK_HANDLER(CAN1_TX_IRQHandler);
WEAK_HANDLER(CAN1_RX0_IRQHandler);
WEAK_HANDLER(CAN1_RX1_IRQHandler);
WEAK_HANDLER(CAN1_SCE_IRQHandler);
WEAK_HANDLER(EXTI9_5_IRQHandler);
WEAK_HANDLER(TIM1_BRK_TIM9_IRQHandler);
WEAK_HANDLER(TIM1_UP_TIM10_IRQHandler);
WEAK_HANDLER(TIM1_TRG_COM_TIM11_IRQHandler);
WEAK_HANDLER(TIM1_CC_IRQHandler);
WEAK_HANDLER(TIM2_IRQHandler);
WEAK_HANDLER(TIM3_IRQHandler);
WEAK_HANDLER(TIM4_IRQHandler);
WEAK_HANDLER(I2C1_EV_IRQHandler);
WEAK_HANDLER(I2C1_ER_IRQHandler);
WEAK_HANDLER(I2C2_EV_IRQHandler);
WEAK_HANDLER(I2C2_ER_IRQHandler);
WEAK_HANDLER(SPI1_IRQHandler);
WEAK_HANDLER(SPI2_IRQHandler);
WEAK_HANDLER(USART1_IRQHandler);
WEAK_HANDLER(USART2_IRQHandler);
WEAK_HANDLER(USART3_IRQHandler);
WEAK_HANDLER(EXTI15_10_IRQHandler);
WEAK_HANDLER(RTC_Alarm_IRQHandler);
WEAK_HANDLER(OTG_FS_WKUP_IRQHandler);
WEAK_HANDLER(TIM8_BRK_TIM12_IRQHandler);
WEAK_HANDLER(TIM8_UP_TIM13_IRQHandler);
WEAK_HANDLER(TIM8_TRG_COM_TIM14_IRQHandler);
WEAK_HANDLER(TIM8_CC_IRQHandler);
WEAK_HANDLER(DMA1_Stream7_IRQHandler);
WEAK_HANDLER(FSMC_IRQHandler);
WEAK_HANDLER(SDIO_IRQHandler);
WEAK_HANDLER(TIM5_IRQHandler);
WEAK_HANDLER(SPI3_IRQHandler);
WEAK_HANDLER(UART4_IRQHandler);
WEAK_HANDLER(UART5_IRQHandler);
WEAK_HANDLER(TIM6_DAC_IRQHandler);
WEAK_HANDLER(TIM7_IRQHandler);
WEAK_HANDLER(DMA2_Stream0_IRQHandler);
WEAK_HANDLER(DMA2_Stream1_IRQHandler);
WEAK_HANDLER(DMA2_Stream2_IRQHandler);
WEAK_HANDLER(DMA2_Stream3_IRQHandler);
WEAK_HANDLER(DMA2_Stream4_IRQHandler);
WEAK_HANDLER(ETH_IRQHandler);
WEAK_HANDLER(ETH_WKUP_IRQHandler);
WEAK_HANDLER(CAN2_TX_IRQHandler);
WEAK_HANDLER(CAN2_RX0_IRQHandler);
WEAK_HANDLER(CAN2_RX1_IRQHandler);
WEAK_HANDLER(CAN2_SCE_IRQHandler);
WEAK_HANDLER(OTG_FS_IRQHandler);
WEAK_HANDLER(DMA2_Stream5_IRQHandler);
WEAK_HANDLER(DMA2_Stream6_IRQHandler);
WEAK_HANDLER(DMA2_Stream7_IRQHandler);
WEAK_HANDLER(USART6_IRQHandler);
WEAK_HANDLER(I2C3_EV_IRQHandler);
WEAK_HANDLER(I2C3_ER_IRQHandler);
WEAK_HANDLER(OTG_HS_EP1_OUT_IRQHandler);
WEAK_HANDLER(OTG_HS_EP1_IN_IRQHandler);
WEAK_HANDLER(OTG_HS_WKUP_IRQHandler);
WEAK_HANDLER(OTG_HS_IRQHandler);
WEAK_HANDLER(DCMI_IRQHandler);
WEAK_HANDLER(CRYP_IRQHandler);
WEAK_HANDLER(HASH_RNG_IRQHandler);
WEAK_HANDLER(FPU_IRQHandler);
WEAK_HANDLER(USART7_IRQHandler);
WEAK_HANDLER(USART8_IRQHandler);
WEAK_HANDLER(SPI4_IRQHandler);
WEAK_HANDLER(SPI5_IRQHandler);
WEAK_HANDLER(SPI6_IRQHandler);
void Reset_Handler(void) {
/* Initialize data and bss */
__Init_Data();
/* Set up base CPU stuffs. */
SystemInit();
/* Continue with boot */
main();
while(1) {}
}
__attribute__ ((section(".isr_vectors")))
void (* const g_pfnVectors[])(void) = {
(intfunc)((unsigned long)&_estack), /* The stack pointer after relocation */
Reset_Handler, /* Reset Handler */
NMI_Handler, /* NMI Handler */
HardFault_Handler, /* Hard Fault Handler */
MemManage_Handler, /* MPU Fault Handler */
BusFault_Handler, /* Bus Fault Handler */
UsageFault_Handler, /* Usage Fault Handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
SVC_Handler, /* SVCall Handler */
DebugMon_Handler, /* Debug Monitor Handler */
0, /* Reserved */
PendSV_Handler, /* PendSV Handler */
SysTick_Handler, /* SysTick Handler */
/* External Interrupts */
WWDG_IRQHandler, /* Window Watchdog */
PVD_IRQHandler, /* PVD through EXTI Line detect */
TAMP_STAMP_IRQHandler, /* Tamper and TimeSTamps through EXTI line */
RTC_WKUP_IRQHandler, /* RTC */
FLASH_IRQHandler, /* Flash */
RCC_IRQHandler, /* RCC */
EXTI0_IRQHandler, /* EXTI Line 0 */
EXTI1_IRQHandler, /* EXTI Line 1 */
EXTI2_IRQHandler, /* EXTI Line 2 */
EXTI3_IRQHandler, /* EXTI Line 3 */
EXTI4_IRQHandler, /* EXTI Line 4 */
DMA1_Stream0_IRQHandler, /* DMA1 Stream 0 */
DMA1_Stream1_IRQHandler, /* DMA1 Stream 1 */
DMA1_Stream2_IRQHandler, /* DMA1 Stream 2 */
DMA1_Stream3_IRQHandler, /* DMA1 Stream 3 */
DMA1_Stream4_IRQHandler, /* DMA1 Stream 4 */
DMA1_Stream5_IRQHandler, /* DMA1 Stream 5 */
DMA1_Stream6_IRQHandler, /* DMA1 Stream 6 */
ADC1_IRQHandler, /* ADC1, ADC2 & ADC3 */
CAN1_TX_IRQHandler, /* CAN1 TX */
CAN1_RX0_IRQHandler, /* CAN1 RX0 */
CAN1_RX1_IRQHandler, /* CAN1 RX1 */
CAN1_SCE_IRQHandler, /* CAN1 SCE */
EXTI9_5_IRQHandler, /* EXTI Line 9..5 */
TIM1_BRK_TIM9_IRQHandler, /* TIM1 Break and TIM9 */
TIM1_UP_TIM10_IRQHandler, /* TIM1 Update and TIM10 */
TIM1_TRG_COM_TIM11_IRQHandler, /* TIM1 Trigger and Commutation and TIM11 */
TIM1_CC_IRQHandler, /* TIM1 Capture Compare */
TIM2_IRQHandler, /* TIM2 */
TIM3_IRQHandler, /* TIM3 */
TIM4_IRQHandler, /* TIM4 */
I2C1_EV_IRQHandler, /* I2C1 Event */
I2C1_ER_IRQHandler, /* I2C1 Error */
I2C2_EV_IRQHandler, /* I2C2 Event */
I2C2_ER_IRQHandler, /* I2C2 Error */
SPI1_IRQHandler, /* SPI1 */
SPI2_IRQHandler, /* SPI2 */
USART1_IRQHandler, /* USART1 */
USART2_IRQHandler, /* USART2 */
USART3_IRQHandler, /* USART3 */
EXTI15_10_IRQHandler, /* EXTI Line 15..10 */
RTC_Alarm_IRQHandler, /* RTC Alarm through EXTI Line */
OTG_FS_WKUP_IRQHandler, /* USB OTG Wakeup through EXTI Line */
TIM8_BRK_TIM12_IRQHandler,
TIM8_UP_TIM13_IRQHandler,
TIM8_TRG_COM_TIM14_IRQHandler,
TIM8_CC_IRQHandler,
DMA1_Stream7_IRQHandler,
FSMC_IRQHandler,
SDIO_IRQHandler,
TIM5_IRQHandler,
SPI3_IRQHandler, /* SPI3 */
UART4_IRQHandler,
UART5_IRQHandler,
TIM6_DAC_IRQHandler,
TIM7_IRQHandler, /* TIM7 */
DMA2_Stream0_IRQHandler,
DMA2_Stream1_IRQHandler,
DMA2_Stream2_IRQHandler,
DMA2_Stream3_IRQHandler,
DMA2_Stream4_IRQHandler,
ETH_IRQHandler,
ETH_WKUP_IRQHandler,
CAN2_TX_IRQHandler, /* CAN2 TX */
CAN2_RX0_IRQHandler, /* CAN2 RX0 */
CAN2_RX1_IRQHandler, /* CAN2 RX1 */
CAN2_SCE_IRQHandler, /* CAN2 SCE */
OTG_FS_IRQHandler,
DMA2_Stream5_IRQHandler,
DMA2_Stream6_IRQHandler,
DMA2_Stream7_IRQHandler,
USART6_IRQHandler,
I2C3_EV_IRQHandler, /* I2C3 Event */
I2C3_ER_IRQHandler, /* I2C3 Error */
OTG_HS_EP1_OUT_IRQHandler,
OTG_HS_EP1_IN_IRQHandler,
OTG_HS_WKUP_IRQHandler,
OTG_HS_IRQHandler,
DCMI_IRQHandler,
CRYP_IRQHandler,
HASH_RNG_IRQHandler,
FPU_IRQHandler,
#if (MCU_SUBTYPE == stm32f427x)
USART7_IRQHandler,
USART8_IRQHandler,
SPI4_IRQHandler, /* SPI4 */
SPI5_IRQHandler, /* SPI5 */
SPI6_IRQHandler, /* SPI6 */
#endif
};
/* ================================= */
/* Lifted from system_stm32f4xx.c */
uint32_t SystemCoreClock = 168000000;
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
#define VECT_TAB_OFFSET ((uint32_t)&_isr_vectors_offs)
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 25
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
static void SetSysClock(void) {
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do {
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET) {
HSEStatus = (uint32_t)0x01;
} else {
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01) {
/* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR |= PWR_CR_VOS;
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
/* PCLK1 = HCLK / 4*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
/* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0) { }
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL) { }
} else {
/* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
void SystemInit(void) {
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset CFGR register */
RCC->CFGR = 0x00000000;
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x24003010;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Disable all interrupts */
RCC->CIR = 0x00000000;
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
/* Configure the System clock source, PLL Multiplier and Divider factors,
AHB/APBx prescalers and Flash settings ----------------------------------*/
SetSysClock();
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}
void SystemCoreClockUpdate(void) {
uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp) {
case 0x00: /* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x04: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x08: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
SYSCLK = PLL_VCO / PLL_P
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
if (pllsource != 0) {
/* HSE used as PLL clock source */
pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
} else {
/* HSI used as PLL clock source */
pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
}
pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
SystemCoreClock = pllvco/pllp;
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
/* Compute HCLK frequency --------------------------------------------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK frequency */
SystemCoreClock >>= tmp;
}