From 5ed53adfc444f6c9857d83352182bf9e1066a98a Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Sat, 2 May 2015 13:41:05 +0200 Subject: [PATCH] Proper entry point --- boot/crt0.c | 17 ++++----- boot/stm32f429_flash.ld | 5 +++ src/blinky.c | 84 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 src/blinky.c diff --git a/boot/crt0.c b/boot/crt0.c index b230598e3..2dac663bf 100644 --- a/boot/crt0.c +++ b/boot/crt0.c @@ -1,10 +1,10 @@ -typedef long uint32_t; +typedef long uint32_t; //FIXME: Extrude this in another file, and assert it extern const void * _data_segment_start_flash; extern const void * _data_segment_start_ram; extern const void * _data_segment_end_ram; -void reset(void); +void _start(void); /* Interrupt Service Routines are void->void functions */ typedef void(*ISR)(void); @@ -21,16 +21,16 @@ ISR InitialisationVector[INITIALISATION_VECTOR_SIZE] __attribute__((section(".isr_vector_table"))) = { 0x20010000, //FIXME: This is the stack pointer! - reset, + _start, 0, 0, 0 }; -void blink(void); +void main(int argc, char * argv[]); -void reset(void) { - // This is where execution start after reset. +void _start(void) { + // This is where execution starts after reset. // Many things are not initialized yet so the code here has to pay attention. /* Copy data segment to RAM @@ -45,8 +45,5 @@ void reset(void) { *ramPointer++ = *flashPointer++; } - blink(); + main(0, 0x0); } -/* -void _start(void) { -}*/ diff --git a/boot/stm32f429_flash.ld b/boot/stm32f429_flash.ld index d05d1e685..f59b89ed1 100644 --- a/boot/stm32f429_flash.ld +++ b/boot/stm32f429_flash.ld @@ -4,6 +4,10 @@ MEMORY { CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K } +/* We want the code at symbol "reset" to be laid out at the beginning of the + * text section */ +ENTRY(_start) + SECTIONS { .isr_vector_table ORIGIN(FLASH) : { /* We're explicitly asking for the ISR vector table to be at the beginning @@ -16,6 +20,7 @@ SECTIONS { * vector should be set to indicate Thumb code */ } >FLASH + .text : { . = ALIGN(4); *(.text) diff --git a/src/blinky.c b/src/blinky.c new file mode 100644 index 000000000..dd6b57075 --- /dev/null +++ b/src/blinky.c @@ -0,0 +1,84 @@ +long DataSectionTest = 0x1234; + +void sleep(long delay); + +int main(int argc, char * argv[]) { + for (int i=0; i< DataSectionTest; i++) { + } + + // We want to blink LEDs connected to GPIO pin G13 and G14 + // (this is documented in our board's PDF) + // + // GPIO are grouped by letter, and GPIO "G" live on the "AHB1" bus + // (this is documented in the STM32F4 reference mnual, page 65) + + // More specifically, the boundary addresses for GPIOC are + // 0x4002 1800 - 0x4002 1BFF + // + + // Step 1 : Enable clock in RCC_AHBxENR + // (RCC stands for "Reset and Clock Control) + // Per doc (STM32F4 reference manual, page 266), we want to enable + // the 6th bit of RCC_AHB1ENR, which is at offset 0x30 + // The RCC register boundary address is 0x4002 3800 - 0x4002 3BFF + // (per STM32F429xx datasheet) + // In other words, we want to enable bit 6 of (0x40023830) + + long * RCCAHB1ENR = (long *)0x40023830; + *RCCAHB1ENR |= (1 << 6); // Set 6th bit of RCCAHB1ENR + + // Step 2 : Configure the GPIO pin + // Set the mode to general purpose output + // GPIOG_MODER, bit 26 and 27 = pin13 + // GPIOG_MODER, bit 28 and 29 = pin14 + // A value of 0,0 for these two bits means input (reset state) + // and 0,1 for these two bits means output (which we want) + long * GPIOG_MODER = (long *)0x40021800; // GPIOC register + + *GPIOG_MODER &= ~(1 << 27); // Clear bit 27 of GPIOG_MODER + *GPIOG_MODER |= (1 << 26); // Set bit 26 of RCCAHB1ENR + + *GPIOG_MODER &= ~(1 << 29); // Clear bit 29 of GPIOG_MODER + *GPIOG_MODER |= (1 << 28); // Set bit 28 of RCCAHB1ENR + + // Per doc, the output is push-pull by default (yay) + // And we should also set the output speed, but really + // we don't care (we're doing something super slow) + + long delay = 10000; + long * GPIOG_PUPDR = (long *)(0x40021800 + 0xC); // Per doc, ref man page 283 + long * GPIOG_ODR = (long *)(0x40021800 + 0x14); // per doc, data register of GPIO G + + while (1) { + /* + // Pull-up pin 13 + *GPIOG_PUPDR &= ~(1 << 27); + *GPIOG_PUPDR |= (1 << 26); + // Pull-up pin 14 + *GPIOG_PUPDR &= ~(1 << 29); + *GPIOG_PUPDR |= (1 << 28); + */ + *GPIOG_ODR = 0x2000; + + sleep(100000); + + *GPIOG_ODR = 0x4000; + + /* + // Pull-down pin 13 + *GPIOG_PUPDR &= ~(1 << 26); + *GPIOG_PUPDR |= (1 << 27); + // Pull-down pin 14 + *GPIOG_PUPDR &= ~(1 << 28); + *GPIOG_PUPDR |= (1 << 29); + */ + + sleep(100000); + } +} + +void sleep(long delay) { + for (long i=0; i