Commit 22a17230 by Paul Molloy

Have things finally working with switch input and LED outputs.

Issue was due to messed up SRAM define in linker script.  IDK what
datasheet I was reading..  But I had the location and size completely
wrong.  That caused any access of SRAM to cause a hardfault of course.
First happening when popping anything to the stack.  Which also explains
why I couldn't look at the stack to figure out the last called instruciton
to point to where the issue was...

copied stm32f0xx_*.h files over from STM32F0xx_StdPeriph_Driver/inc dir
parent 7254f4b5
......@@ -34,7 +34,7 @@ ARCH_FLAGS=-mthumb -mcpu=cortex-m$(CORTEX_M)
# -Os -flto -ffunction-sections -fdata-sections to compile for code size
CFLAGS=$(ARCH_FLAGS) $(STARTUP_DEFS) -Os -flto -ffunction-sections -fdata-sections
CFLAGS=$(ARCH_FLAGS) $(STARTUP_DEFS) -Os -flto -ffunction-sections -fdata-sections -g
# Link for code size
......@@ -43,7 +43,7 @@ GC=-Wl,--gc-sections
# Create map file
LDSCRIPTS=-L. -L$(BASE)/ldscripts -T nokeep.ld
......@@ -57,8 +57,8 @@ CFLAGS+= $(DEFINE) $(INCLUDE)
SOURCES=$(wildcard source/**/*.c source/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
all: dir $(BUILD)/$(PROJ).axf $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
#all: dir $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
#all: dir $(BUILD)/$(PROJ).axf $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
all: dir $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
#build axf file output (basically elf with DWARF debug info)
# $@ is shortcut for the target, $^ is shortcut for prereqs
......@@ -81,6 +81,9 @@ dir:
size: $(BUILD)/$(PROJ).elf
$(SIZE) -t $^
arm-none-eabi-objdump build\baremetal.elf -d -g
rm -rf $(BUILD)
rm -f $(OBJECTS)
......@@ -7,10 +7,24 @@
/*Flash always located at $08000000 */
/* $00000000 can be Flash, system mem, or SRAM depending on boot config */
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x20000 /* 128K */
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x10000 /* 64K */
/* STM32F07x */
/* $0000 0000 128KB of flash/sram depending on BOOT */
/* $0002 0000 ~128MB of system reserved */
/* $0800 0000 always 128KB of flash */
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K /* 0x20000 128K */
/* $0802 0000 ~384MB of system reserved */
/* $1FFF C800 12KB of system memory (bootloader and etc) */
/* $1FFF F800 2KB of option bytes */
/* $2000 0000 16KB of SRAM */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K /* 0x04000 16K */
/* $2000 4000 ~512MB of system reserved */
/* $4000 0000 128KB of APB perif regs & reserved */
/* $4002 0000 17KB of AHB1 perif regs & reserved */
/* $4002 4400 ~128MB system reserved */
/* $4800 0000 6KB AHB2 GPIO perif refs */
/* $4800 1800 ~384MB system reserved */
/* $E000 0000 1MB Cortex M0 internal peripherals */
/* $E010 0000 511MB system reserved */
/* Linker script to place sections and symbol values. Should be used together
void HardFault_Handler(void)
//TODO test out this function
//should retrieve PC of the instruction that follows whatever caused the hardfault
//This didn't work for me earlier bc the stack itself was broke
// asm(
// "movs r0, #4 \n"
// "movs r1, lr \n"
// "tst r0, r1 \n"
// "beq _MSP \n"
// "mrs r0, psp \n"
// "b _HALT \n"
// "_MSP: \n"
// " mrs r0, msp \n"
// "_HALT: \n"
// " ldr r1, [r0,#20] \n"
// //" bkpt #0 \n"
// );
while (1) {
#ifndef __NO_SYSTEM_INIT
//option to create your own C library system initialization
//Currently define __STARTUP_CLEAR_BSS when building to use
//Currently define __STARTUP_CLEAR_BSS when building to only use
//initialization provided by startup_ARMCM0.S that zero's the BSS section
//To get this called in between reset routine and main function,
//remove definition from makefile
void SystemInit()
// TODO Some processor initializations might be a in good order.
// currently just sticking with default main stack pointer (MSP)
// process SP is unused..
//include target chip port definition library files
#include <stm32f0xx.h>
#include <stm32f0xx_rcc.h>
#include <stm32f0xx_gpio.h>
//include target board library files
#include <stm32f072b_discovery.h>
//this is junk... #include <stm32f072b_discovery.h>
//Here's where the LEDs and switch are located
//PA0 user switch
#define SWITCH (0U)
#define RED (6U)
#define BLUE (7U)
#define YELLOW (8U)
#define GREEN (9U)
//RCC->AHBENR AHB clock enable register
//set bit to enable clock
#define DMAEN (0U) //DMA clock
#define DMA2EN (1U) //DMA2 clock
#define SRAMEN (2U) //SRAM interface during sleep
#define FLITFEN (4U) //Flash interface during sleep
#define CRCEN (6U) //CRC clock
#define IOPAEN (17U) //IO port A
#define IOPBEN (18U) //IO port B
#define IOPCEN (19U) //IO port C
#define IOPDEN (20U) //IO port D
#define IOPEEN (21U) //IO port E
#define IOPFEN (22U) //IO port F
#define TSCEN (24U) //touch sensing controller
//only one bit per pin so no extra shift needed
void init_io()
//Need to supply clock to i/o port before anything can be done
RCC->AHBENR |= ((1<<IOPAEN) | (1<<IOPCEN));
//after reset most io registers are reset with exception of SWDIO/SWCLK for debugger
//This makes all other pins Input, Pushpull (no effect till set as output), Slow, no pullup/down, output reg set low.
//post reset, you only need to set the bits needed to set to desired config
//SET LEDs as outputs Mode register is 2bits per pin, start as off
//0b01 is output 2 bits per pin, 16 pins per port, fills entire 32bit MODER register
//need to enable pins 9-6
GPIOC->MODER |= ((GPIO_Mode_OUT<<(RED*2)) | (GPIO_Mode_OUT<<(BLUE*2)) | (GPIO_Mode_OUT<<(YELLOW*2)) | (GPIO_Mode_OUT<<(GREEN*2)));
GPIOC->MODER &= ~((GPIO_Mode_OUT<<(RED*2)) & (GPIO_Mode_OUT<<(BLUE*2)) & (GPIO_Mode_OUT<<(YELLOW*2)) & (GPIO_Mode_OUT<<(GREEN*2)));
//GPIOC->ODR |= (0x1U<<RED);
//fuck it, output them all HIGH!
//GPIOC->ODR = 0x0000AAAA; //blue green
//GPIOC->ODR = 0x00005555; //red orange
//Switch already set to input, just enable the pullup
void main()
......@@ -25,9 +112,51 @@ void main()
//Initialize WDT, core features, etc
//Initialize io, periphery, etc
//setup LED's as outputs and turn them on
//setup user switch as input
//Initialize board/system
uint32_t i = 0;
//main infinite loop
for (;;);
while(1) {
//to start i is zero and doesn't satisfy any checks below so all LEDs are off
//once i reaches > 2M set output data register to i
//This will make all LEDs turn on but not full brightness
//they "flicker" as i iterates
if ( i > 2000000 ) {
//mask out all but the GPIO bits
//a bit unfinished as we're writing to the entire GPIO register...
GPIOC->ODR = (i & 0x0000FFFF);
//once i > 4M set some LEDs on solid
if ( i > 4000000 ) {
i = 0;
//GPIOC->ODR = 0x0000AAAA; //blue green
GPIOC->ODR = 0x00005555; //red orange
//once i > 8M reset back to 2M
if ( i > 8000000 ) {
i = 2000000;
//read in user switch
if ( GPIOA->IDR & (1<<SWITCH) ) {
//button pressed
i = 0; //reset the "counter"
GPIOC->ODR = 0x00000000; //all off
} else {
//button not pressed
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment