diff --git a/.gitignore b/.gitignore index 790d531..82bdbcb 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,7 @@ ods/src/ch??ex?? *.la *_bench misc/kf/kf +*.elf +*.bin +blue-pill/*/*.d +core diff --git a/blue-pill/draugr/Makefile b/blue-pill/draugr/Makefile index 0297f9d..15f29b6 100644 --- a/blue-pill/draugr/Makefile +++ b/blue-pill/draugr/Makefile @@ -1,5 +1,5 @@ # configurables -OBJS := +OBJS := startup.o TARGET := blink OBJS += $(TARGET).o @@ -9,18 +9,17 @@ BIN := $(TARGET).bin # toolchain setup ARMTC := arm-none-eabi -ARMCC := $(ARMTC)-gcc -ARMCXX := $(ARMTC)-g++ -CC := $(ARMCC) -CXX := $(ARMCXX) -LD := $(ARMCXX) +AS := $(ARMTC)-as +CC := $(ARMTC)-gcc +CXX := $(ARMTC)-g++ +LD := $(ARMTC)-ld ARMSIZE := $(ARMTC)-size OBJCOPY := $(ARMTC)-objcopy # compiler options CPUFLAGS := -mcpu=cortex-m3 -mthumb CFLAGS := -Wall -Wextra -Os -MD $(CPUFLAGS) -CXXFLAGS := -Wall -Wextra -Os -MD $(CPUFLAGS) -std=c++14 +CXXFLAGS := $(CFLAGS) -std=c++14 -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin LDFLAGS := $(CPUFLAGS) -nostartfiles -Wl,-T,stm32f103.ld LDLIBS := -lc -lnosys @@ -33,7 +32,7 @@ STARTMEM := 0x8000000 all: $(BIN) $(ELF): $(OBJS) - $(ARMCC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) $(ARMSIZE) -A $@ $(BIN): $(ELF) diff --git a/blue-pill/draugr/blink.cc b/blue-pill/draugr/blink.cc index c15c8a1..952e9a0 100644 --- a/blue-pill/draugr/blink.cc +++ b/blue-pill/draugr/blink.cc @@ -2,48 +2,20 @@ #define LED_PIN 13 -void reset_handler(void); - -__attribute__ ((section(".vectors"))) -struct { - unsigned int *initial_sp_value; - void (*reset)(void); - void (*nmi)(void); - void (*hard_fault)(void); - void (*memory_manage_fault)(void); - void (*bus_fault)(void); - void (*usage_fault)(void); - void (*reserved_x001c[4])(void); - void (*sv_call)(void); - void (*debug_monitor)(void); - void (*reserved_x0034)(void); - void (*pend_sv)(void); - void (*systick)(void); - void (*irq[68])(void); -} vector_table = { - initial_sp_value : (unsigned int *)0x100, - reset : reset_handler, -}; - -static inline void -delay(unsigned long ms) -{ - for (unsigned long i = 0; i < ms; ++i) __asm__("nop"); -} - // void __attribute__ ((weak, naked)) reset_handler(void) { -void reset_handler() { - *RCC |= (1 << 4); /* enable port C clock */ - GPIO_C->output_mode(LED_PIN, OUTPUT_GPP, OUTPUT_MAX_2MHZ); +int +main() { + GPIO_C->enable_clock(); + GPIO_C->pin_mode(LED_PIN, true, OUTPUT_GPP, OUTPUT_MAX_2MHZ); while(1) { - GPIO_C->clear_pin(LED_PIN); + GPIO_C->pin_clear(LED_PIN); delay(1000000); - GPIO_C->set_pin(LED_PIN); + GPIO_C->pin_set(LED_PIN); delay(100000); - GPIO_C->clear_pin(LED_PIN); + GPIO_C->pin_clear(LED_PIN); delay(100000); - GPIO_C->set_pin(LED_PIN); + GPIO_C->pin_set(LED_PIN); delay(100000); } } diff --git a/blue-pill/draugr/bluepill.h b/blue-pill/draugr/bluepill.h index 22fa314..4c8c098 100644 --- a/blue-pill/draugr/bluepill.h +++ b/blue-pill/draugr/bluepill.h @@ -4,4 +4,10 @@ #include "bluepill/gpio.h" #include "bluepill/rcc.h" +static inline void +delay(unsigned long ms) +{ + for (unsigned long i = 0; i < ms; ++i) __asm__("nop"); +} + #endif // __BLUEPILL_H__ diff --git a/blue-pill/draugr/bluepill/gpio.h b/blue-pill/draugr/bluepill/gpio.h index 5c75359..c9f3252 100644 --- a/blue-pill/draugr/bluepill/gpio.h +++ b/blue-pill/draugr/bluepill/gpio.h @@ -2,6 +2,7 @@ #define __BLUEPILL_GPIO_H__ #include +#include "rcc.h" constexpr volatile unsigned int *PORTA = reinterpret_cast(0x40010800); constexpr volatile unsigned int *PORTB = reinterpret_cast(0x40010c00); @@ -11,21 +12,33 @@ constexpr volatile unsigned int *PORTE = reinterpret_castBSRR |= ((1 << pin) << 16); } - void clear_pin(uint32_t pin) { this->BSRR |= (1 << pin); } - void output_mode(uint32_t pin, uint32_t mode, uint32_t max) { - if (pin > 7) { - pin = ((pin - 8) * 4); - this->CRH |= (max << pin); - this->CRH |= (mode << (pin + 2)); - } - else { - pin *= 4; - this->CRL |= (max << pin); - this->CRL |= (mode << (pin + 2)); + void pin_set(uint32_t pin) { this->BSRR |= ((1 << pin) << 16); } + void pin_clear(uint32_t pin) { this->BSRR |= (1 << pin); } + void pin_mode(uint32_t pin, bool output, uint32_t mode, uint32_t max) { + if (output) { + if (pin > 7) { + pin = ((pin - 8) * 4); + this->CRH |= (max << pin); + this->CRH |= (mode << (pin + 2)); + } + else { + pin *= 4; + this->CRL |= (max << pin); + this->CRL |= (mode << (pin + 2)); + } } } + uint32_t port_index(void) { + /* Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn. */ + return (((unsigned int)this) - ((unsigned int)PORTA)) >> 10; + } + + void enable_clock(void) { + *RCC |= (1 << (this->port_index() + 2)); + } + + private: uint32_t CRL; /* configuration register low */ uint32_t CRH; /* configuration register high */ diff --git a/blue-pill/draugr/startup.s b/blue-pill/draugr/startup.s new file mode 100644 index 0000000..ac22465 --- /dev/null +++ b/blue-pill/draugr/startup.s @@ -0,0 +1,27 @@ +/* + * Startup code for the STM32F103-based blue pill board. + * + * TODO: revisit stack pointer + * TODO: is the IRQv buffer actually needed right now? + */ + +.globl vectors +.align 2 +.long 0x100 /* best guess at stack pointer */ +.long reset_handler /* reset handler */ +.long 0 /* NMI handler */ +.long 0 /* hard_fault_handler */ +.long 0 /* memory management handler */ +.long 0 /* bus fault handler */ +.long 0 /* usage fault handler */ +.skip 0x20 /* reserved */ +.long 0 /* svcall handler */ +.long 0 /* debug handler */ +.skip 4 /* reserved */ +.long 0 /* pendsv handler */ +.long 0 /* systick handler */ +.skip 0x110 /* remaining / IRQ vectors */ + +.globl reset_handler +reset_handler: + bl main