Commit 22a17230 authored by Paul Molloy's avatar 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)
This diff is collapsed.
This diff is collapsed.
......@@ -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