mirror of
https://github.com/rfivet/stm32bringup.git
synced 2024-12-18 06:46:23 -05:00
Entry at reset, C startup, user LED driven by System Tick on STM32F030F4.
This commit is contained in:
parent
847cb54c5f
commit
ef77ec527d
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,6 +12,7 @@
|
|||||||
*.ilk
|
*.ilk
|
||||||
*.map
|
*.map
|
||||||
*.exp
|
*.exp
|
||||||
|
*.lst
|
||||||
|
|
||||||
# Precompiled Headers
|
# Precompiled Headers
|
||||||
*.gch
|
*.gch
|
||||||
@ -36,6 +37,7 @@
|
|||||||
*.i*86
|
*.i*86
|
||||||
*.x86_64
|
*.x86_64
|
||||||
*.hex
|
*.hex
|
||||||
|
*.bin
|
||||||
|
|
||||||
# Debug files
|
# Debug files
|
||||||
*.dSYM/
|
*.dSYM/
|
||||||
|
63
Makefile
Normal file
63
Makefile
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# Makefile -- stm32bringup
|
||||||
|
# Copyright (c) 2020 Renaud Fivet
|
||||||
|
|
||||||
|
### Build environment selection
|
||||||
|
|
||||||
|
ifeq (linux, $(findstring linux, $(MAKE_HOST)))
|
||||||
|
#GCCDIR = ~/Packages/gcc-arm-none-eabi-9-2019-q4-major
|
||||||
|
GCCDIR = ~/Packages/gcc-arm-none-eabi-9-2020-q2-update
|
||||||
|
else
|
||||||
|
#GCCDIR = "D:/Program Files (x86)/GNU Tools ARM Embedded/9 2019-q4-major"
|
||||||
|
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/9 2020-q2-update"
|
||||||
|
endif
|
||||||
|
|
||||||
|
BINPFX = @$(GCCDIR)/bin/arm-none-eabi-
|
||||||
|
CC = $(BINPFX)gcc
|
||||||
|
LD = $(BINPFX)ld
|
||||||
|
OBJCOPY = $(BINPFX)objcopy
|
||||||
|
OBJDUMP = $(BINPFX)objdump
|
||||||
|
SIZE = $(BINPFX)size
|
||||||
|
|
||||||
|
### STM32F030F4P6 based board
|
||||||
|
|
||||||
|
PROJECT = f030f4
|
||||||
|
#SRCS = boot.c
|
||||||
|
#SRCS = ledon.c
|
||||||
|
#SRCS = blink.c
|
||||||
|
#SRCS = ledtick.c
|
||||||
|
#SRCS = cstartup.c
|
||||||
|
SRCS = startup.c init.c success.c
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
CPU = -mthumb -mcpu=cortex-m0
|
||||||
|
CFLAGS = $(CPU) -g -Wall -Wextra -Os
|
||||||
|
LD_SCRIPT = $(PROJECT).ld
|
||||||
|
|
||||||
|
### Build rules
|
||||||
|
|
||||||
|
.PHONY: clean all
|
||||||
|
|
||||||
|
all: $(PROJECT).hex $(PROJECT).bin
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo CLEAN
|
||||||
|
@rm -f *.o *.elf *.map *.lst *.bin *.hex
|
||||||
|
|
||||||
|
$(PROJECT).elf: $(OBJS)
|
||||||
|
@echo $@
|
||||||
|
$(LD) -T$(LD_SCRIPT) -Map=$(PROJECT).map -cref -o $@ $(OBJS)
|
||||||
|
$(SIZE) $@
|
||||||
|
$(OBJDUMP) -hS $@ > $(PROJECT).lst
|
||||||
|
|
||||||
|
%.elf: %.o
|
||||||
|
@echo $@
|
||||||
|
$(LD) -T$(LD_SCRIPT) -Map=$*.map -cref -o $@ $<
|
||||||
|
$(SIZE) $@
|
||||||
|
$(OBJDUMP) -hS $@ > $*.lst
|
||||||
|
|
||||||
|
%.bin: %.elf
|
||||||
|
@echo $@
|
||||||
|
$(OBJCOPY) -O binary $< $@
|
||||||
|
|
||||||
|
%.hex: %.elf
|
||||||
|
@echo $@
|
||||||
|
$(OBJCOPY) -O ihex $< $@
|
45
blink.c
Normal file
45
blink.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* blink.c -- user LED blink
|
||||||
|
** Copyright (c) 2020 Renaud Fivet
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory locations defined by linker script */
|
||||||
|
extern long __StackTop ; /* &__StackTop points after end of stack */
|
||||||
|
void Reset_Handler( void) ; /* Entry point for execution */
|
||||||
|
|
||||||
|
/* Interrupt vector table:
|
||||||
|
* 1 Stack Pointer reset value
|
||||||
|
* 15 System Exceptions
|
||||||
|
* NN Device specific Interrupts
|
||||||
|
*/
|
||||||
|
typedef void (*isr_p)( void) ;
|
||||||
|
isr_p const isr_vector[ 2] __attribute__((section(".isr_vector"))) = {
|
||||||
|
(isr_p) &__StackTop,
|
||||||
|
/* System Exceptions */
|
||||||
|
Reset_Handler
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#define RCC ((volatile long *) 0x40021000)
|
||||||
|
#define RCC_AHBENR RCC[ 5]
|
||||||
|
#define RCC_AHBENR_IOPBEN 0x00040000 /* 18: I/O port B clock enable */
|
||||||
|
|
||||||
|
#define GPIOB ((volatile long *) 0x48000400)
|
||||||
|
#define GPIOB_MODER GPIOB[ 0]
|
||||||
|
#define GPIOB_ODR GPIOB[ 5]
|
||||||
|
|
||||||
|
void Reset_Handler( void) {
|
||||||
|
int delay ;
|
||||||
|
|
||||||
|
/* User LED ON */
|
||||||
|
RCC_AHBENR |= RCC_AHBENR_IOPBEN ; /* Enable IOPB periph */
|
||||||
|
GPIOB_MODER |= 1 << (1 * 2) ; /* PB1 Output [01], over default 00 */
|
||||||
|
/* OTYPER Push-Pull by default */
|
||||||
|
/* PB1 output default LOW at reset */
|
||||||
|
|
||||||
|
/* User LED blink */
|
||||||
|
for( ;;) {
|
||||||
|
for( delay = 1000000 ; delay ; delay--) ; /* delay between toggling */
|
||||||
|
GPIOB_ODR ^= 1 << 1 ; /* toggle PB1 (User LED) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of blink.c */
|
25
boot.c
Normal file
25
boot.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* boot.c -- entry point at reset
|
||||||
|
** Copyright (c) 2020 Renaud Fivet
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory locations defined by linker script */
|
||||||
|
extern long __StackTop ; /* &__StackTop points after end of stack */
|
||||||
|
void Reset_Handler( void) ; /* Entry point for execution */
|
||||||
|
|
||||||
|
/* Interrupt vector table:
|
||||||
|
* 1 Stack Pointer reset value
|
||||||
|
* 15 System Exceptions
|
||||||
|
* NN Device specific Interrupts
|
||||||
|
*/
|
||||||
|
typedef void (*isr_p)( void) ;
|
||||||
|
isr_p const isr_vector[ 2] __attribute__((section(".isr_vector"))) = {
|
||||||
|
(isr_p) &__StackTop,
|
||||||
|
/* System Exceptions */
|
||||||
|
Reset_Handler
|
||||||
|
} ;
|
||||||
|
|
||||||
|
void Reset_Handler( void) {
|
||||||
|
for( ;;) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of boot.c */
|
61
cstartup.c
Normal file
61
cstartup.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* cstartup.c -- data and bss RAM memory initialization
|
||||||
|
** Copyright (c) 2020 Renaud Fivet
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory locations defined by linker script */
|
||||||
|
extern long __StackTop ; /* &__StackTop points after end of stack */
|
||||||
|
void Reset_Handler( void) ; /* Entry point for execution */
|
||||||
|
extern const long __etext[] ; /* start of initialized data copy in flash */
|
||||||
|
extern long __data_start__[] ;
|
||||||
|
extern long __bss_start__[] ;
|
||||||
|
extern long __bss_end__ ; /* &__bss_end__ points after end of bss */
|
||||||
|
|
||||||
|
/* Interrupt vector table:
|
||||||
|
* 1 Stack Pointer reset value
|
||||||
|
* 15 System Exceptions
|
||||||
|
* NN Device specific Interrupts
|
||||||
|
*/
|
||||||
|
typedef void (*isr_p)( void) ;
|
||||||
|
isr_p const isr_vector[ 2] __attribute__((section(".isr_vector"))) = {
|
||||||
|
(isr_p) &__StackTop,
|
||||||
|
/* System Exceptions */
|
||||||
|
Reset_Handler
|
||||||
|
} ;
|
||||||
|
|
||||||
|
extern int main( void) ;
|
||||||
|
|
||||||
|
void Reset_Handler( void) {
|
||||||
|
const long *f ; /* from, source constant data from FLASH */
|
||||||
|
long *t ; /* to, destination in RAM */
|
||||||
|
|
||||||
|
/* Assume:
|
||||||
|
** __bss_start__ == __data_end__
|
||||||
|
** All sections are 4 bytes aligned
|
||||||
|
*/
|
||||||
|
f = __etext ;
|
||||||
|
for( t = __data_start__ ; t < __bss_start__ ; t += 1)
|
||||||
|
*t = *f++ ;
|
||||||
|
|
||||||
|
while( t < &__bss_end__)
|
||||||
|
*t++ = 0 ;
|
||||||
|
|
||||||
|
main() ;
|
||||||
|
for( ;;) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Test code: main.c *********************************************************/
|
||||||
|
|
||||||
|
const char hexa[] = "0123456789abcdef" ;
|
||||||
|
long first = 1 ;
|
||||||
|
long i ;
|
||||||
|
|
||||||
|
int main( void) {
|
||||||
|
static char c = 'a' ;
|
||||||
|
char *cp = &c ;
|
||||||
|
|
||||||
|
*cp += i ;
|
||||||
|
i += hexa[ 13] - c + first++ ;
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of cstartup.c */
|
196
f030f4.ld
Normal file
196
f030f4.ld
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/* Linker script to configure memory regions.
|
||||||
|
* Need modifying for a specific board.
|
||||||
|
* FLASH.ORIGIN: starting address of flash
|
||||||
|
* FLASH.LENGTH: length of flash
|
||||||
|
* RAM.ORIGIN: starting address of RAM bank 0
|
||||||
|
* RAM.LENGTH: length of RAM bank 0
|
||||||
|
*/
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Linker script to place sections and symbol values. Should be used together
|
||||||
|
* with other linker script that defines memory regions FLASH and RAM.
|
||||||
|
* It references following symbols, which must be defined in code:
|
||||||
|
* Reset_Handler : Entry of reset handler
|
||||||
|
*
|
||||||
|
* It defines following symbols, which code can use without definition:
|
||||||
|
* __exidx_start
|
||||||
|
* __exidx_end
|
||||||
|
* __copy_table_start__
|
||||||
|
* __copy_table_end__
|
||||||
|
* __zero_table_start__
|
||||||
|
* __zero_table_end__
|
||||||
|
* __etext
|
||||||
|
* __data_start__
|
||||||
|
* __preinit_array_start
|
||||||
|
* __preinit_array_end
|
||||||
|
* __init_array_start
|
||||||
|
* __init_array_end
|
||||||
|
* __fini_array_start
|
||||||
|
* __fini_array_end
|
||||||
|
* __data_end__
|
||||||
|
* __bss_start__
|
||||||
|
* __bss_end__
|
||||||
|
* __end__
|
||||||
|
* end
|
||||||
|
* __HeapLimit
|
||||||
|
* __StackLimit
|
||||||
|
* __StackTop
|
||||||
|
* __stack
|
||||||
|
*/
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.isr_vector))
|
||||||
|
*(.text*)
|
||||||
|
|
||||||
|
*(.init)
|
||||||
|
*(.fini)
|
||||||
|
|
||||||
|
/* .ctors */
|
||||||
|
*crtbegin.o(.ctors)
|
||||||
|
*crtbegin?.o(.ctors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||||
|
*(SORT(.ctors.*))
|
||||||
|
*(.ctors)
|
||||||
|
|
||||||
|
/* .dtors */
|
||||||
|
*crtbegin.o(.dtors)
|
||||||
|
*crtbegin?.o(.dtors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||||
|
*(SORT(.dtors.*))
|
||||||
|
*(.dtors)
|
||||||
|
|
||||||
|
*(.rodata*)
|
||||||
|
|
||||||
|
*(.eh_frame*)
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > FLASH
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
/* To copy multiple ROM to RAM sections,
|
||||||
|
* uncomment .copy.table section and,
|
||||||
|
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.copy.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__copy_table_start__ = .;
|
||||||
|
LONG (__etext)
|
||||||
|
LONG (__data_start__)
|
||||||
|
LONG (__data_end__ - __data_start__)
|
||||||
|
LONG (__etext2)
|
||||||
|
LONG (__data2_start__)
|
||||||
|
LONG (__data2_end__ - __data2_start__)
|
||||||
|
__copy_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* To clear multiple BSS sections,
|
||||||
|
* uncomment .zero.table section and,
|
||||||
|
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.zero.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__zero_table_start__ = .;
|
||||||
|
LONG (__bss_start__)
|
||||||
|
LONG (__bss_end__ - __bss_start__)
|
||||||
|
LONG (__bss2_start__)
|
||||||
|
LONG (__bss2_end__ - __bss2_start__)
|
||||||
|
__zero_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Location counter can end up 2byte aligned with narrow Thumb code but
|
||||||
|
__etext is assumed by startup code to be the LMA of a section in RAM
|
||||||
|
which must be 4byte aligned */
|
||||||
|
__etext = ALIGN (4);
|
||||||
|
|
||||||
|
.data : AT (__etext)
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
*(.data*)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
*(.preinit_array)
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
*(SORT(.init_array.*))
|
||||||
|
*(.init_array)
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
*(SORT(.fini_array.*))
|
||||||
|
*(.fini_array)
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
|
||||||
|
*(.jcr)
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap (COPY):
|
||||||
|
{
|
||||||
|
__end__ = .;
|
||||||
|
PROVIDE(end = .);
|
||||||
|
*(.heap*)
|
||||||
|
__HeapLimit = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||||
|
* used for linker to calculate size of stack sections, and assign
|
||||||
|
* values to stack symbols later */
|
||||||
|
.stack_dummy (COPY):
|
||||||
|
{
|
||||||
|
*(.stack*)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* Set stack top to end of RAM, and stack limit move down by
|
||||||
|
* size of stack_dummy section */
|
||||||
|
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||||
|
PROVIDE(__stack = __StackTop);
|
||||||
|
PROVIDE(__data_size = __bss_start__ - __data_start__);
|
||||||
|
PROVIDE(__bss_size = __bss_end__ - __bss_start__);
|
||||||
|
|
||||||
|
/* Check if data + heap + stack exceeds RAM limit */
|
||||||
|
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||||
|
}
|
40
init.c
Normal file
40
init.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* init.c -- middleware initialization
|
||||||
|
** Copyright (c) 2020 Renaud Fivet
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SYSTICK ((volatile long *) 0xE000E010)
|
||||||
|
#define SYSTICK_CSR SYSTICK[ 0]
|
||||||
|
#define SYSTICK_RVR SYSTICK[ 1]
|
||||||
|
#define SYSTICK_CVR SYSTICK[ 2]
|
||||||
|
|
||||||
|
#define RCC ((volatile long *) 0x40021000)
|
||||||
|
#define RCC_AHBENR RCC[ 5]
|
||||||
|
#define RCC_AHBENR_IOPBEN 0x00040000 /* 18: I/O port B clock enable */
|
||||||
|
|
||||||
|
#define GPIOB ((volatile long *) 0x48000400)
|
||||||
|
#define GPIOB_MODER GPIOB[ 0]
|
||||||
|
#define GPIOB_ODR GPIOB[ 5]
|
||||||
|
|
||||||
|
int init( void) {
|
||||||
|
/* By default SYSCLK == HSI [8MHZ] */
|
||||||
|
|
||||||
|
/* SYSTICK */
|
||||||
|
SYSTICK_RVR = 1000000 - 1 ; /* HBA / 8 */
|
||||||
|
SYSTICK_CVR = 0 ;
|
||||||
|
SYSTICK_CSR = 3 ; /* HBA / 8, Interrupt ON, Enable */
|
||||||
|
/* SysTick_Handler will execute every 1s from now on */
|
||||||
|
|
||||||
|
/* User LED ON */
|
||||||
|
RCC_AHBENR |= RCC_AHBENR_IOPBEN ; /* Enable IOPB periph */
|
||||||
|
GPIOB_MODER |= 1 << (1 * 2) ; /* PB1 Output [01], over default 00 */
|
||||||
|
/* OTYPER Push-Pull by default */
|
||||||
|
/* PB1 output default LOW at reset */
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysTick_Handler( void) {
|
||||||
|
GPIOB_ODR ^= 1 << 1 ; /* Toggle PB1 (User LED) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of init.c */
|
37
ledon.c
Normal file
37
ledon.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* ledon.c -- user LED on
|
||||||
|
** Copyright (c) 2020 Renaud Fivet
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory locations defined by linker script */
|
||||||
|
extern long __StackTop ; /* &__StackTop points after end of stack */
|
||||||
|
void Reset_Handler( void) ; /* Entry point for execution */
|
||||||
|
|
||||||
|
/* Interrupt vector table:
|
||||||
|
* 1 Stack Pointer reset value
|
||||||
|
* 15 System Exceptions
|
||||||
|
* NN Device specific Interrupts
|
||||||
|
*/
|
||||||
|
typedef void (*isr_p)( void) ;
|
||||||
|
isr_p const isr_vector[ 2] __attribute__((section(".isr_vector"))) = {
|
||||||
|
(isr_p) &__StackTop,
|
||||||
|
/* System Exceptions */
|
||||||
|
Reset_Handler
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#define RCC ((volatile long *) 0x40021000)
|
||||||
|
#define RCC_AHBENR RCC[ 5]
|
||||||
|
#define RCC_AHBENR_IOPBEN 0x00040000 /* 18: I/O port B clock enable */
|
||||||
|
|
||||||
|
#define GPIOB ((volatile long *) 0x48000400)
|
||||||
|
#define GPIOB_MODER GPIOB[ 0]
|
||||||
|
|
||||||
|
void Reset_Handler( void) {
|
||||||
|
/* User LED ON */
|
||||||
|
RCC_AHBENR |= RCC_AHBENR_IOPBEN ; /* Enable IOPB periph */
|
||||||
|
GPIOB_MODER |= 1 << (1 * 2) ; /* PB1 Output [01], over default 00 */
|
||||||
|
/* OTYPER Push-Pull by default */
|
||||||
|
/* PB1 output default LOW at reset */
|
||||||
|
for( ;;) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of ledon.c */
|
61
ledtick.c
Normal file
61
ledtick.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* ledtick.c -- System Tick driven user LED blink
|
||||||
|
** Copyright (c) 2020 Renaud Fivet
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory locations defined by linker script */
|
||||||
|
extern long __StackTop ; /* &__StackTop points after end of stack */
|
||||||
|
void Reset_Handler( void) ; /* Entry point for execution */
|
||||||
|
|
||||||
|
void SysTick_Handler( void) ;
|
||||||
|
|
||||||
|
/* Interrupt vector table:
|
||||||
|
* 1 Stack Pointer reset value
|
||||||
|
* 15 System Exceptions
|
||||||
|
* NN Device specific Interrupts
|
||||||
|
*/
|
||||||
|
typedef void (*isr_p)( void) ;
|
||||||
|
isr_p const isr_vector[ 16] __attribute__((section(".isr_vector"))) = {
|
||||||
|
(isr_p) &__StackTop,
|
||||||
|
/* System Exceptions */
|
||||||
|
Reset_Handler,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
SysTick_Handler
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#define SYSTICK ((volatile long *) 0xE000E010)
|
||||||
|
#define SYSTICK_CSR SYSTICK[ 0]
|
||||||
|
#define SYSTICK_RVR SYSTICK[ 1]
|
||||||
|
#define SYSTICK_CVR SYSTICK[ 2]
|
||||||
|
|
||||||
|
#define RCC ((volatile long *) 0x40021000)
|
||||||
|
#define RCC_AHBENR RCC[ 5]
|
||||||
|
#define RCC_AHBENR_IOPBEN 0x00040000 /* 18: I/O port B clock enable */
|
||||||
|
|
||||||
|
#define GPIOB ((volatile long *) 0x48000400)
|
||||||
|
#define GPIOB_MODER GPIOB[ 0]
|
||||||
|
#define GPIOB_ODR GPIOB[ 5]
|
||||||
|
|
||||||
|
void Reset_Handler( void) {
|
||||||
|
/* By default SYSCLK == HSI [8MHZ] */
|
||||||
|
|
||||||
|
/* SYSTICK */
|
||||||
|
SYSTICK_RVR = 1000000 - 1 ; /* HBA / 8 */
|
||||||
|
SYSTICK_CVR = 0 ;
|
||||||
|
SYSTICK_CSR = 3 ; /* HBA / 8, Interrupt ON, Enable */
|
||||||
|
/* SysTick_Handler will execute every 1s from now on */
|
||||||
|
|
||||||
|
/* User LED ON */
|
||||||
|
RCC_AHBENR |= RCC_AHBENR_IOPBEN ; /* Enable IOPB periph */
|
||||||
|
GPIOB_MODER |= 1 << (1 * 2) ; /* PB1 Output [01], over default 00 */
|
||||||
|
/* OTYPER Push-Pull by default */
|
||||||
|
/* PB1 output default LOW at reset */
|
||||||
|
|
||||||
|
for( ;;)
|
||||||
|
__asm( "WFI") ; /* Wait for interrupt */
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysTick_Handler( void) {
|
||||||
|
GPIOB_ODR ^= 1 << 1 ; /* Toggle PB1 (User LED) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of ledtick.c */
|
71
startup.c
Normal file
71
startup.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/* startup.c -- entry point at reset and C startup
|
||||||
|
** Copyright (c) 2020 Renaud Fivet
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory locations defined by linker script */
|
||||||
|
extern long __StackTop ; /* &__StackTop points after end of stack */
|
||||||
|
void Reset_Handler( void) ; /* Entry point for execution */
|
||||||
|
extern const long __etext[] ; /* start of initialized data copy in flash */
|
||||||
|
extern long __data_start__[] ;
|
||||||
|
extern long __bss_start__[] ;
|
||||||
|
extern long __bss_end__ ; /* &__bss_end__ points after end of bss */
|
||||||
|
|
||||||
|
/* Stubs for System Exception Handler */
|
||||||
|
void Default_Handler( void) ;
|
||||||
|
#define dflt_hndlr( fun) void fun##_Handler( void) \
|
||||||
|
__attribute__((weak,alias("Default_Handler")))
|
||||||
|
dflt_hndlr( NMI) ;
|
||||||
|
dflt_hndlr( HardFault) ;
|
||||||
|
dflt_hndlr( SVCall) ;
|
||||||
|
dflt_hndlr( PendSV) ;
|
||||||
|
dflt_hndlr( SysTick) ;
|
||||||
|
|
||||||
|
/* Interrupt vector table:
|
||||||
|
* 1 Stack Pointer reset value
|
||||||
|
* 15 System Exceptions
|
||||||
|
* NN Device specific Interrupts
|
||||||
|
*/
|
||||||
|
typedef void (*isr_p)( void) ;
|
||||||
|
isr_p const isr_vector[ 16] __attribute__((section(".isr_vector"))) = {
|
||||||
|
(isr_p) &__StackTop,
|
||||||
|
/* System Exceptions */
|
||||||
|
Reset_Handler,
|
||||||
|
NMI_Handler,
|
||||||
|
HardFault_Handler,
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
SVCall_Handler,
|
||||||
|
0, 0,
|
||||||
|
PendSV_Handler,
|
||||||
|
SysTick_Handler
|
||||||
|
} ;
|
||||||
|
|
||||||
|
extern int init( void) ;
|
||||||
|
extern int main( void) ;
|
||||||
|
|
||||||
|
void Reset_Handler( void) {
|
||||||
|
const long *f ; /* from, source constant data from FLASH */
|
||||||
|
long *t ; /* to, destination in RAM */
|
||||||
|
|
||||||
|
/* Assume:
|
||||||
|
** __bss_start__ == __data_end__
|
||||||
|
** All sections are 4 bytes aligned
|
||||||
|
*/
|
||||||
|
f = __etext ;
|
||||||
|
for( t = __data_start__ ; t < __bss_start__ ; t += 1)
|
||||||
|
*t = *f++ ;
|
||||||
|
|
||||||
|
while( t < &__bss_end__)
|
||||||
|
*t++ = 0 ;
|
||||||
|
|
||||||
|
if( init() == 0)
|
||||||
|
main() ;
|
||||||
|
|
||||||
|
for( ;;)
|
||||||
|
__asm( "WFI") ; /* Wait for interrupt */
|
||||||
|
}
|
||||||
|
|
||||||
|
void Default_Handler( void) {
|
||||||
|
for( ;;) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of startup.c */
|
Loading…
Reference in New Issue
Block a user