From 2275ed7b0c355920927be6709a87a0482a749eb2 Mon Sep 17 00:00:00 2001 From: chrysn Date: Sun, 26 Feb 2012 03:40:18 +0100 Subject: [PATCH] overhauled documentation includes minor refactoring in example code and modification of how the generic and the tinygecko specific vector.h go together (bringing it in line with stm32/f1's memorymap.h) --- Makefile | 2 +- examples/efm32/tinygecko/Makefile.include | 2 +- .../efm32-tg-stk3300/miniblink/miniblink.c | 37 ++++++++++--- include/libopencm3/efm32/tinygecko/cmu.h | 30 ++++++++--- .../efm32/tinygecko/devicerevision.h | 4 ++ include/libopencm3/efm32/tinygecko/gpio.h | 52 +++++++++++++++---- include/libopencm3/efm32/tinygecko/vector.h | 14 +++-- include/libopencm3/efm32/vector.h | 24 ++++++--- lib/efm32/tinygecko/Makefile | 3 +- lib/efm32/tinygecko/vector.c | 2 +- 10 files changed, 132 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index 4e410968..07825ec8 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ LIBDIR = $(DESTDIR)/$(PREFIX)/lib SHAREDIR = $(DESTDIR)/$(PREFIX)/share/libopencm3/scripts INSTALL = install -TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lm3s +TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lm3s efm32/tinygecko # Be silent per default, but 'make V=1' will show all compiler calls. ifneq ($(V),1) diff --git a/examples/efm32/tinygecko/Makefile.include b/examples/efm32/tinygecko/Makefile.include index 1ee8d49a..76691ce4 100644 --- a/examples/efm32/tinygecko/Makefile.include +++ b/examples/efm32/tinygecko/Makefile.include @@ -30,7 +30,7 @@ GDB = $(PREFIX)-gdb #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 + -fno-common -mcpu=cortex-m3 -mthumb -msoft-float -MD LDSCRIPT ?= ${TOOLCHAIN_DIR}/lib/efm32/tinygecko/$(MCU).ld LDFLAGS += -lc -lnosys -L$(TOOLCHAIN_DIR)/lib/efm32/tinygecko \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \ diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c index 30536261..0941add7 100644 --- a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c @@ -21,11 +21,37 @@ #include #include +void led_setup(void); +void led_toggle(void); + +/** @file + * Minimal example for making the User LED of the EFM32-TG-STK330 eval board blink. + */ + +/** + * Toggle the User LED in an infinite loop, with time between the toggling + * determined by a busy loop stupidly counting up. + */ + int main(void) { // FIXME: As of now, this doesn't work without x being volatile; an issue with linking? volatile int x; + led_setup(); + + while(1) { + for(x = 0; x < 200000; ++x); + led_toggle(); + }; +} + +/** + * Enable GPIO, and set up port D7 as an output pin. + */ + +void led_setup(void) +{ // Before GPIO works, according to d0034_efm32tg_reference_manual.pdf // note in section 28.3.7, we'll have to enable GPIO in CMU_HFPERCLKEN0 @@ -36,10 +62,9 @@ int main(void) // and 16.3 (called UIF_LED0) GPIO_PD_MODEL = GPIO_MODE_PUSHPULL<<(7*4); - GPIO_PD_DOUTSET = 1<<7; - - while(1) { - for(x = 0; x < 200000; ++x); - GPIO_PD_DOUTTGL = 1<<7; - }; +} + +void led_toggle(void) +{ + GPIO_PD_DOUTTGL = 1<<7; } diff --git a/include/libopencm3/efm32/tinygecko/cmu.h b/include/libopencm3/efm32/tinygecko/cmu.h index 38217ed1..e690ebd9 100644 --- a/include/libopencm3/efm32/tinygecko/cmu.h +++ b/include/libopencm3/efm32/tinygecko/cmu.h @@ -17,17 +17,29 @@ * along with this program. If not, see . */ -/* this interface correspons to the description in - * d0034_efm32tg_reference_manual.pdf section 11. */ +/** @file + * + * Definitions for the CMU (Clock Management Unit). + * + * This corresponds to the description in d0034_efm32tg_reference_manual.pdf + * section 11. + * + * @see CMU_registers + */ +/* FIXME: i'd prefer not to @see CMU_registers but have some direct link placed + * automatically from a file to its groups */ #ifndef LIBOPENCM3_EFM32_TINYGECKO_CMU_H #define LIBOPENCM3_EFM32_TINYGECKO_CMU_H #include -#define CMU_BASE 0x400C8000 /* according to d0034_efm32tg_reference_manual.pdf figure 5.2 */ +#define CMU_BASE 0x400C8000 /**< Register base address for the CMU according to d0034_efm32tg_reference_manual.pdf figure 5.2. */ -/* this is d0034_efm32tg_reference_manual.pdf section 11.4 */ +/** These definitions reflect d0034_efm32tg_reference_manual.pdf section 11.4. + * + * @defgroup CMU_registers CMU registers + * @{ */ #define CMU_CTRL MMIO32(CMU_BASE + 0x000) #define CMU_HFCORECLKDIV MMIO32(CMU_BASE + 0x004) @@ -58,8 +70,14 @@ #define CMU_ROUTE MMIO32(CMU_BASE + 0x080) #define CMU_LOCK MMIO32(CMU_BASE + 0x084) -/* this is incomplete because i'm impatient and want a working result - * quickly */ +/** @} */ + +/** + * This section is incomplete because i'm impatient and want a working result + * quickly + * + * @todo Include all bits and bit groups from the manual. + */ #define CMU_HFPERCLKEN0_GPIO (1<<6) diff --git a/include/libopencm3/efm32/tinygecko/devicerevision.h b/include/libopencm3/efm32/tinygecko/devicerevision.h index 83e0e0dd..c7c64aa4 100644 --- a/include/libopencm3/efm32/tinygecko/devicerevision.h +++ b/include/libopencm3/efm32/tinygecko/devicerevision.h @@ -1,3 +1,7 @@ +/* FIXME: proper documentation, see where this fits, if we need this at all + * etc. this was just a first attempt at implementing something easy with + * MMIO32. */ + /* this implements d0034_efm32tg_reference_manual.pdf's 7.3.4 "Device Revision" * section */ diff --git a/include/libopencm3/efm32/tinygecko/gpio.h b/include/libopencm3/efm32/tinygecko/gpio.h index 3417eee6..710651c5 100644 --- a/include/libopencm3/efm32/tinygecko/gpio.h +++ b/include/libopencm3/efm32/tinygecko/gpio.h @@ -17,18 +17,36 @@ * along with this program. If not, see . */ -/* this interface corresponds to the description in - * d0034_efm32tg_reference_manual.pdf section 28. the interface tries to be - * close to stm32/f1's gpio interface. */ +/** @file + * + * Definitions for the GPIO subsystem (General Purpose Input Output). + * + * This corresponds to the description in d0034_efm32tg_reference_manual.pdf + * section 28. + * + * @see GPIO_registers + * @see GPIO_MODE_values + */ +/* FIXME: i'd prefer not to @see CMU_registers but have some direct link placed + * automatically from a file to its groups */ #ifndef LIBOPENCM3_EFM32_TINYGECKO_GPIO_H #define LIBOPENCM3_EFM32_TINYGECKO_GPIO_H #include -#define GPIO_BASE 0x40006000 /* according to d0034_efm32tg_reference_manual.pdf figure 5.2 */ +#define GPIO_BASE 0x40006000 /**< Register base address for the GPIO according to d0034_efm32tg_reference_manual.pdf figure 5.2. */ -/* this is rather straight forward d0034_efm32tg_reference_manual.pdf section 28.4 */ +/** These definitions reflect d0034_efm32tg_reference_manual.pdf section 28.4 + * + * The bulk of the registers defined here (like GPIO_PA_CTRL) will not be used + * inside the convenience functions, but are provided for direct access. + * + * @todo This section could profit from bit-banding. + * + * @defgroup GPIO_registers GPIO registers + * @{ + */ #define GPIO_Px_CTRL_OFFSET 0x000 #define GPIO_Px_MODEL_OFFSET 0x004 #define GPIO_Px_MODEH_OFFSET 0x008 @@ -122,10 +140,24 @@ #define GPIO_EM4WUPOL MMIO32(GPIO_BASE + 0x138) #define GPIO_EM4WUCAUSE MMIO32(GPIO_BASE + 0x13C) -/* these are the modes defined for the MODEx fields in the MODEL/MODEH - * registers, named as in d0034_efm32tg_reference_manual.pdf's sections - * 28.5.2/28.5.3. for explanations of what they really do, rather see section - * 28.3.1. */ +/** @} */ + +/** These are the modes defined for the MODEx fields in the MODEL/MODEH + * registers. + * + * For example, to set the mode for the 3rd pin of port A to pushpull, set + * `GPIO_PA_MODEL = GPIO_MODE_PUSHPULL << (3*4);`. + * + * @todo Update the example as soon as there are convenience functions to do + * this properly. + * + * They are named as in d0034_efm32tg_reference_manual.pdf's sections + * 28.5.2/28.5.3. For explanations of what they really do, rather see section + * 28.3.1. + * + * @defgroup GPIO_MODE_values GPIO MODE values + * @{ + */ #define GPIO_MODE_DISABLED 0 #define GPIO_MODE_INPUT 1 @@ -144,6 +176,8 @@ #define GPIO_MODE_WIREDANDDRIVEPULLUP 14 #define GPIO_MODE_WIREDANDDRIVEPULLUPFILTER 15 +/** @} */ + //void gpio_set(u32 gpioport, u16 gpios); //void gpio_clear(u32 gpioport, u16 gpios); //void gpio_toggle(u32 gpioport, u16 gpios); diff --git a/include/libopencm3/efm32/tinygecko/vector.h b/include/libopencm3/efm32/tinygecko/vector.h index c609da3b..1f2eeb72 100644 --- a/include/libopencm3/efm32/tinygecko/vector.h +++ b/include/libopencm3/efm32/tinygecko/vector.h @@ -1,11 +1,15 @@ -/* this implements d0002_efm32_cortex-m3_reference_manual.pdf's table 1.1's "number of interrupts" line. */ - +/** @file + * + * Definitions for vector tables on Tiny Gecko systems. + * + * @see include/libopencm3/efm32/vector.h + * + * @todo The definitions of the individual IRQs will go here too. + * */ #ifndef LIBOPENCM3_EFM32_TINYGECKO_VECTOR_H #define LIBOPENCM3_EFM32_TINYGECKO_VECTOR_H -#define EFM32_VECTOR_NIRQ 23 - -#include "../vector.h" +#define EFM32_VECTOR_NIRQ 23 /**< See d0002_efm32_cortex-m3_reference_manual.pdf's table 1.1's "number of interrupts" line */ #endif diff --git a/include/libopencm3/efm32/vector.h b/include/libopencm3/efm32/vector.h index 96ca301b..8a385ec3 100644 --- a/include/libopencm3/efm32/vector.h +++ b/include/libopencm3/efm32/vector.h @@ -1,21 +1,29 @@ -/* this implements d0002_efm32_cortex-m3_reference_manual.pdf's figure 2.2. +/** @file * - * the structure of the vector table is implemented independently of the vector - * table, as it can be relocated to other memory locations too. + * Definitions for handling vector tables. * - * don't include this file directly; rather, include the family's vector.h - * file, which defines the number of interrupts (EFM_VECTOR_NIRQ) from table - * 1.1 */ + * This implements d0002_efm32_cortex-m3_reference_manual.pdf's figure 2.2. + * + * The structure of the vector table is implemented independently of the system + * vector table starting at memory position 0x0, as it can be relocated to + * other memory locations too. + */ #ifndef LIBOPENCM3_EFM32_VECTOR_H #define LIBOPENCM3_EFM32_VECTOR_H #include -typedef void (*efm32_vector_table_entry_t)(void); +#ifdef TINYGECKO +# include +#else +# error "efm32 family not defined." +#endif + +typedef void (*efm32_vector_table_entry_t)(void); /**< Type of an interrupt function. Only used to avoid hard-to-read function pointers in the efm32_vector_table_t struct. */ typedef struct { - unsigned int *initial_sp_value; + unsigned int *initial_sp_value; /**< The value the stack pointer is set to initially */ efm32_vector_table_entry_t reset; efm32_vector_table_entry_t nmi; efm32_vector_table_entry_t hard_fault; diff --git a/lib/efm32/tinygecko/Makefile b/lib/efm32/tinygecko/Makefile index b785d4df..afe1e934 100644 --- a/lib/efm32/tinygecko/Makefile +++ b/lib/efm32/tinygecko/Makefile @@ -19,6 +19,7 @@ ## LIBNAME = libopencm3_efm32tinygecko +FAMILY = TINYGECKO PREFIX ?= arm-none-eabi #PREFIX ?= arm-elf @@ -26,7 +27,7 @@ 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 + -ffunction-sections -fdata-sections -MD -D$(FAMILY) # ARFLAGS = rcsv ARFLAGS = rcs OBJS = vector.o devicerevision.o diff --git a/lib/efm32/tinygecko/vector.c b/lib/efm32/tinygecko/vector.c index 0a7c09f9..624785e4 100644 --- a/lib/efm32/tinygecko/vector.c +++ b/lib/efm32/tinygecko/vector.c @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -#include +#include #define WEAK __attribute__ ((weak))