From 2180a02e2f79b8ee77780ea11be188c0faaa8866 Mon Sep 17 00:00:00 2001 From: chrysn Date: Sat, 25 Feb 2012 18:57:11 +0100 Subject: [PATCH] first attempt at porting libopencm3 to energymicro unless sources are explicitly given, the linker scripts and make files were copied over from the stm32/f1 port. --- examples/efm32/tinygecko/Makefile.include | 96 +++++++++++++++++++ .../efm32-tg-stk3300/Makefile.include | 25 +++++ .../efm32/tinygecko/efm32-tg-stk3300/README | 9 ++ .../efm32-tg-stk3300/miniblink/Makefile | 23 +++++ .../efm32-tg-stk3300/miniblink/README | 9 ++ .../efm32-tg-stk3300/miniblink/miniblink.c | 72 ++++++++++++++ .../efm32/tinygecko/devicerevision.h | 26 +++++ include/libopencm3/efm32/tinygecko/vector.h | 11 +++ include/libopencm3/efm32/vector.h | 34 +++++++ lib/efm32/tinygecko/EFM32TG840F32.ld | 15 +++ lib/efm32/tinygecko/Makefile | 59 ++++++++++++ lib/efm32/tinygecko/devicerevision.c | 10 ++ lib/efm32/tinygecko/tinygecko.ld | 78 +++++++++++++++ lib/efm32/tinygecko/vector.c | 92 ++++++++++++++++++ 14 files changed, 559 insertions(+) create mode 100644 examples/efm32/tinygecko/Makefile.include create mode 100644 examples/efm32/tinygecko/efm32-tg-stk3300/Makefile.include create mode 100644 examples/efm32/tinygecko/efm32-tg-stk3300/README create mode 100644 examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/Makefile create mode 100644 examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/README create mode 100644 examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c create mode 100644 include/libopencm3/efm32/tinygecko/devicerevision.h create mode 100644 include/libopencm3/efm32/tinygecko/vector.h create mode 100644 include/libopencm3/efm32/vector.h create mode 100644 lib/efm32/tinygecko/EFM32TG840F32.ld create mode 100644 lib/efm32/tinygecko/Makefile create mode 100644 lib/efm32/tinygecko/devicerevision.c create mode 100644 lib/efm32/tinygecko/tinygecko.ld create mode 100644 lib/efm32/tinygecko/vector.c diff --git a/examples/efm32/tinygecko/Makefile.include b/examples/efm32/tinygecko/Makefile.include new file mode 100644 index 00000000..1ee8d49a --- /dev/null +++ b/examples/efm32/tinygecko/Makefile.include @@ -0,0 +1,96 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2010 Piotr Esden-Tempski +## Copyright (C) 2012 chrysn +## +## This program is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . +## + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +LD = $(PREFIX)-gcc +OBJCOPY = $(PREFIX)-objcopy +OBJDUMP = $(PREFIX)-objdump +GDB = $(PREFIX)-gdb +# Uncomment this line if you want to use the installed (not local) library. +#TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +TOOLCHAIN_DIR = ../../../../.. +CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ + -fno-common -mcpu=cortex-m3 -mthumb -msoft-float -MD -DSTM32F1 +LDSCRIPT ?= ${TOOLCHAIN_DIR}/lib/efm32/tinygecko/$(MCU).ld +LDFLAGS += -lc -lnosys -L$(TOOLCHAIN_DIR)/lib/efm32/tinygecko \ + -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \ + -mthumb -march=armv7 -mfix-cortex-m3-ldrd -msoft-float +OBJS += $(BINARY).o + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +NULL := 2>/dev/null +else +LDFLAGS += -Wl,--print-gc-sections +endif + +.SUFFIXES: .elf .bin .hex .srec .list .images +.SECONDEXPANSION: +.SECONDARY: + +all: images + +images: $(BINARY).images +flash: $(BINARY).flash + +%.images: %.bin %.hex %.srec %.list + @#echo "*** $* images generated ***" + +%.bin: %.elf + @#printf " OBJCOPY $(*).bin\n" + $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin + +%.hex: %.elf + @#printf " OBJCOPY $(*).hex\n" + $(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex + +%.srec: %.elf + @#printf " OBJCOPY $(*).srec\n" + $(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec + +%.list: %.elf + @#printf " OBJDUMP $(*).list\n" + $(Q)$(OBJDUMP) -S $(*).elf > $(*).list + +%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/efm32/tinygecko/libopencm3_efm32tinygecko.a + @#printf " LD $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_efm32tinygecko $(LDFLAGS) + +%.o: %.c Makefile + @#printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) -o $@ -c $< + +clean: + $(Q)rm -f *.o + $(Q)rm -f *.d + $(Q)rm -f *.elf + $(Q)rm -f *.bin + $(Q)rm -f *.hex + $(Q)rm -f *.srec + $(Q)rm -f *.list + +.PHONY: images clean + +-include $(OBJS:.o=.d) + diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/Makefile.include b/examples/efm32/tinygecko/efm32-tg-stk3300/Makefile.include new file mode 100644 index 00000000..e707b652 --- /dev/null +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/Makefile.include @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2012 chrysn +## +## This program is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . +## + +MCU = EFM32TG840F32 + +# Linker scripts are always relative to the current directory. This file is +# intended for inclusion from example subdirectories, so the Makefile.include +# meant here would be called ../Makefile.include relative to here. +include ../../Makefile.include diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/README b/examples/efm32/tinygecko/efm32-tg-stk3300/README new file mode 100644 index 00000000..ffa3b595 --- /dev/null +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/README @@ -0,0 +1,9 @@ +========================= +EFM32-TG-STK3300 Examples +========================= + +Examples in this directory are designed to be run on the Energy Micro EFM32 +Tiny Gecko Starter Kit, which is based on the EFM32TG840F32 MCU, has an onboard +USB debug and power management interface, and a bunch of peripherials built in +that demonstrate the chip's low power capabilities (LED, LCD display, light +sensor, touch slider, LC sensor, push buttons). diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/Makefile b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/Makefile new file mode 100644 index 00000000..a2e44dc0 --- /dev/null +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/Makefile @@ -0,0 +1,23 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## 2012 chrysn +## +## This program is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . +## + +BINARY = miniblink + +include ../Makefile.include diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/README b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/README new file mode 100644 index 00000000..d19e4fee --- /dev/null +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/README @@ -0,0 +1,9 @@ +========================================== +EFM32-TG-STK3300 Examples miniblink README +========================================== + +This is the smallest-possible example program using libopencm3. + +It's intended for the EFM32-TG-STK3300 eval board. It should blink +the user LED on the board. + diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c new file mode 100644 index 00000000..e19ba8fe --- /dev/null +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c @@ -0,0 +1,72 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * 2012 chrysn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +// +//void gpio_setup(void) +//{ +// /* Enable GPIOC clock. */ +// /* Manually: */ +// // RCC_APB2ENR |= RCC_APB2ENR_IOPCEN; +// /* Using API functions: */ +// rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); +// +// /* Set GPIO8 (in GPIO port C) to 'output push-pull'. */ +// /* Manually: */ +// // GPIOC_CRH = (GPIO_CNF_OUTPUT_PUSHPULL << (((8 - 8) * 4) + 2)); +// // GPIOC_CRH |= (GPIO_MODE_OUTPUT_2_MHZ << ((8 - 8) * 4)); +// /* Using API functions: */ +// gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, +// GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); +//} + +int main(void) +{ +// int i; +// +// gpio_setup(); +// +// /* Blink the LED (PC8) on the board. */ +// while (1) { +// /* Manually: */ +// // GPIOC_BSRR = GPIO8; /* LED off */ +// // for (i = 0; i < 800000; i++) /* Wait a bit. */ +// // __asm__("nop"); +// // GPIOC_BRR = GPIO8; /* LED on */ +// // for (i = 0; i < 800000; i++) /* Wait a bit. */ +// // __asm__("nop"); +// +// /* Using API functions gpio_set()/gpio_clear(): */ +// // gpio_set(GPIOC, GPIO8); /* LED off */ +// // for (i = 0; i < 800000; i++) /* Wait a bit. */ +// // __asm__("nop"); +// // gpio_clear(GPIOC, GPIO8); /* LED on */ +// // for (i = 0; i < 800000; i++) /* Wait a bit. */ +// // __asm__("nop"); +// +// /* Using API function gpio_toggle(): */ +// gpio_toggle(GPIOC, GPIO8); /* LED on/off */ +// for (i = 0; i < 800000; i++) /* Wait a bit. */ +// __asm__("nop"); +// } +// +// return 0; + for(;;); +} diff --git a/include/libopencm3/efm32/tinygecko/devicerevision.h b/include/libopencm3/efm32/tinygecko/devicerevision.h new file mode 100644 index 00000000..83e0e0dd --- /dev/null +++ b/include/libopencm3/efm32/tinygecko/devicerevision.h @@ -0,0 +1,26 @@ +/* this implements d0034_efm32tg_reference_manual.pdf's 7.3.4 "Device Revision" + * section */ + +#ifndef LIBOPENCM3_EFM32_TINYGECKO_DEVICEREVISION_H +#define LIBOPENCM3_EFM32_TINYGECKO_DEVICEREVISION_H + +#include + +#define DEVICEREVISION_PID2 MMIO32(0xE00FFFE8) +#define DEVICEREVISION_PID3 MMIO32(0xE00FFFEC) + +/* devicerevision_revision_get has a comment that would make these definitions + * obsolete; i'm not sure how far it is reasonable to parameterize everythin + * g*/ +#define DEVICEREVISION_REVISION_LENGTH 4 +#define DEVICEREVISION_REVISION_SHIFT 4 +#define DEVICEREVISION_REVISION_MASK (~(~0< + +typedef void (*efm32_vector_table_entry_t)(void); + +typedef struct { + unsigned int *initial_sp_value; + efm32_vector_table_entry_t reset; + efm32_vector_table_entry_t nmi; + efm32_vector_table_entry_t hard_fault; + efm32_vector_table_entry_t memory_manage_fault; + efm32_vector_table_entry_t bus_fault; + efm32_vector_table_entry_t usage_fault; + efm32_vector_table_entry_t reserved_x001c[4]; + efm32_vector_table_entry_t sv_call; + efm32_vector_table_entry_t reserved_debug; + efm32_vector_table_entry_t reserved_x0034; + efm32_vector_table_entry_t pend_sv; + efm32_vector_table_entry_t systick; + efm32_vector_table_entry_t irq[EFM32_VECTOR_NIRQ]; +} efm32_vector_table_t; + +#endif diff --git a/lib/efm32/tinygecko/EFM32TG840F32.ld b/lib/efm32/tinygecko/EFM32TG840F32.ld new file mode 100644 index 00000000..f7baa904 --- /dev/null +++ b/lib/efm32/tinygecko/EFM32TG840F32.ld @@ -0,0 +1,15 @@ +/* lengths from d011_efm32tg840_datasheet.pdf table 1.1, offset from + * d0034_efm32tg_reference_manual.pdf figure 5.2. + * + * the origins and memory structure are constant over all tinygeckos, but the + * MEMORY section requires the use of constants, and has thus to be duplicated + * over the chip variants. + * */ + +MEMORY +{ + rom (rx) : ORIGIN = 0, LENGTH = 32k + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4k +} + +INCLUDE tinygecko.ld; diff --git a/lib/efm32/tinygecko/Makefile b/lib/efm32/tinygecko/Makefile new file mode 100644 index 00000000..b785d4df --- /dev/null +++ b/lib/efm32/tinygecko/Makefile @@ -0,0 +1,59 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 chrysn +## +## This program is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . +## + +LIBNAME = libopencm3_efm32tinygecko + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F1 +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = vector.o devicerevision.o + +VPATH += ../ + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +endif + +all: $(LIBNAME).a + +$(LIBNAME).a: $(OBJS) + @printf " AR $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(AR) $(ARFLAGS) $@ $^ + +%.o: %.c + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) -o $@ -c $< + +clean: + @printf " CLEAN lib/efm32/tinygecko\n" + $(Q)rm -f *.o *.d + $(Q)rm -f $(LIBNAME).a + +.PHONY: clean + +-include $(OBJS:.o=.d) + diff --git a/lib/efm32/tinygecko/devicerevision.c b/lib/efm32/tinygecko/devicerevision.c new file mode 100644 index 00000000..216ab1bd --- /dev/null +++ b/lib/efm32/tinygecko/devicerevision.c @@ -0,0 +1,10 @@ +#include + +u8 devicerevision_revision_get(void) +{ + /* probably this is more elegant, more readable and closer to the spec, + * and i'll just get used to doing things like that: + return (DEVICEREVISION_PID2 & 0xf0) | ((DEVICEREVISION_PID3 & 0xf0) >> 4); + */ + return ((DEVICEREVISION_PID2 & DEVICEREVISION_REVISION_MASK) >> DEVICEREVISION_REVISION_SHIFT << DEVICEREVISION_REVISION_LENGTH) | ((DEVICEREVISION_PID3 & DEVICEREVISION_REVISION_MASK) >> DEVICEREVISION_REVISION_SHIFT); +} diff --git a/lib/efm32/tinygecko/tinygecko.ld b/lib/efm32/tinygecko/tinygecko.ld new file mode 100644 index 00000000..db3b81f5 --- /dev/null +++ b/lib/efm32/tinygecko/tinygecko.ld @@ -0,0 +1,78 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann , + * 2012 chrysn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + . = ORIGIN(rom); + + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + _etext = .; + } >rom + + . = ORIGIN(ram); + + .data : AT(_etext) { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram AT >rom + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support - discard it for now. + */ + /DISCARD/ : { *(.ARM.exidx) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/lib/efm32/tinygecko/vector.c b/lib/efm32/tinygecko/vector.c new file mode 100644 index 00000000..0a7c09f9 --- /dev/null +++ b/lib/efm32/tinygecko/vector.c @@ -0,0 +1,92 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski , + * 2012 chrysn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#define WEAK __attribute__ ((weak)) + +/* Symbols exported by the linker script(s). */ +extern unsigned _etext, _data, _edata, _ebss, _stack; + +void main(void); +void reset_handler(void); +void blocking_handler(void); +void null_handler(void); + +void WEAK nmi_handler(void); +void WEAK hard_fault_handler(void); +void WEAK mem_manage_handler(void); +void WEAK bus_fault_handler(void); +void WEAK usage_fault_handler(void); +void WEAK sv_call_handler(void); +void WEAK debug_monitor_handler(void); +void WEAK pend_sv_handler(void); +void WEAK sys_tick_handler(void); + + +__attribute__ ((section(".vectors"))) +efm32_vector_table_t vector_table = { + .initial_sp_value = &_stack, + .reset = reset_handler, + .nmi = nmi_handler, + .hard_fault = hard_fault_handler, + .memory_manage_fault = mem_manage_handler, + .bus_fault = bus_fault_handler, + .usage_fault = usage_fault_handler, + .sv_call = sv_call_handler, + .pend_sv = pend_sv_handler, + .systick = sys_tick_handler, +}; + +void reset_handler(void) +{ + volatile unsigned *src, *dest; + + __asm__("MSR msp, %0" : : "r"(&_stack)); + + for (src = &_etext, dest = &_data; dest < &_edata; src++, dest++) + *dest = *src; + + while (dest < &_ebss) + *dest++ = 0; + + /* Call the application's entry point. */ + main(); +} + +void blocking_handler(void) +{ + while (1) ; +} + +void null_handler(void) +{ + /* Do nothing. */ +} + +#pragma weak nmi_handler = null_handler +#pragma weak hard_fault_handler = blocking_handler +#pragma weak mem_manage_handler = blocking_handler +#pragma weak bus_fault_handler = blocking_handler +#pragma weak usage_fault_handler = blocking_handler +#pragma weak sv_call_handler = null_handler +#pragma weak debug_monitor_handler = null_handler +#pragma weak pend_sv_handler = null_handler +#pragma weak sys_tick_handler = null_handler