aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doxyfile8
-rw-r--r--Makefile2
-rw-r--r--examples/efm32/tinygecko/Makefile.include97
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/Makefile.include29
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/README9
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/Makefile23
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/README8
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/generate_lcd_mapping.py76
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_demo.c130
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_mapping.yaml192
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/Makefile22
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README13
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c40
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c88
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c71
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c30
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/Makefile26
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/README9
l---------examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/efm32_cmu.c1
l---------examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/efm32_gpio.c1
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/miniblink.c69
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/Makefile23
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/README9
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c71
-rw-r--r--examples/efm32/tinygecko/olimex-em32-32g880f128-h/Makefile.include29
-rw-r--r--examples/efm32/tinygecko/olimex-em32-32g880f128-h/README14
-rw-r--r--examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/Makefile26
-rw-r--r--examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/README9
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/efm32_cmu.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/efm32_gpio.c1
-rw-r--r--examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/miniblink.c70
-rw-r--r--examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/Makefile26
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_acmp.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_adc.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_aes.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_assert.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_burtc.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_cmu.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dac.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dbg.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dma.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_ebi.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_emu.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_gpio.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_i2c.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_int.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_lcd.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_lesense.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_letimer.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_leuart.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_mpu.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_msc.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_opamp.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_pcnt.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_prs.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_rmu.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_rtc.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_system.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_timer.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_usart.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_vcmp.c1
l---------examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_wdog.c1
-rw-r--r--examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/gdbinit14
-rw-r--r--examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/test.c115
-rw-r--r--include/libopencm3/efm32/memorymap.h37
-rw-r--r--include/libopencm3/efm32/tinygecko/README.dox14
-rw-r--r--include/libopencm3/efm32/tinygecko/cmu.convenienceheaders63
-rw-r--r--include/libopencm3/efm32/tinygecko/cmu.h678
-rw-r--r--include/libopencm3/efm32/tinygecko/cmu.yaml458
-rw-r--r--include/libopencm3/efm32/tinygecko/devicerevision.h49
-rw-r--r--include/libopencm3/efm32/tinygecko/emu.convenienceheaders18
-rw-r--r--include/libopencm3/efm32/tinygecko/emu.h127
-rw-r--r--include/libopencm3/efm32/tinygecko/emu.yaml50
-rw-r--r--include/libopencm3/efm32/tinygecko/generate-license.yaml19
-rw-r--r--include/libopencm3/efm32/tinygecko/generate.py176
-rw-r--r--include/libopencm3/efm32/tinygecko/generate.yaml3
-rw-r--r--include/libopencm3/efm32/tinygecko/gpio.h498
-rw-r--r--include/libopencm3/efm32/tinygecko/irq.h55
-rw-r--r--include/libopencm3/efm32/tinygecko/lcd.convenienceheaders0
-rw-r--r--include/libopencm3/efm32/tinygecko/lcd.h295
-rw-r--r--include/libopencm3/efm32/tinygecko/lcd.yaml241
-rw-r--r--include/libopencm3/efm32/tinygecko/memorymap.h76
-rw-r--r--include/libopencm3/efm32/vector.h66
-rw-r--r--include/libopencmsis/core_cm3.h201
-rw-r--r--lib/efm32/tinygecko/EFM32TG840F32.ld15
-rw-r--r--lib/efm32/tinygecko/Makefile60
-rw-r--r--lib/efm32/tinygecko/devicerevision.c29
-rw-r--r--lib/efm32/tinygecko/gpio.c42
-rw-r--r--lib/efm32/tinygecko/tinygecko.ld78
-rw-r--r--lib/efm32/tinygecko/vector.c159
90 files changed, 4884 insertions, 5 deletions
diff --git a/Doxyfile b/Doxyfile
index e5b6a38..beb5dda 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -654,7 +654,7 @@ EXCLUDE_SYMLINKS = NO
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
-EXCLUDE_PATTERNS =
+EXCLUDE_PATTERNS = *.d
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1413,13 +1413,13 @@ ENABLE_PREPROCESSING = YES
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
-MACRO_EXPANSION = NO
+MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_DEFINED tags.
-EXPAND_ONLY_PREDEF = NO
+EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# pointed to by INCLUDE_PATH will be searched when a #include is found.
@@ -1447,7 +1447,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED =
+PREDEFINED = __attribute__(x)=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
diff --git a/Makefile b/Makefile
index 56ec68d..931e247 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 lpc17xx lm3s
+TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lpc17xx 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
new file mode 100644
index 0000000..8c42816
--- /dev/null
+++ b/examples/efm32/tinygecko/Makefile.include
@@ -0,0 +1,97 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+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\
+ -D$(FAMILY)
+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 0000000..218abd8
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/Makefile.include
@@ -0,0 +1,29 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+MCU = EFM32TG840F32
+FAMILY = TINYGECKO
+
+EACOMMANDER = ~/energymicro/energymicro/eACommander.sh
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../Makefile.include
+
+upload: $(BINARY).bin
+ # eacommander is just as nonfree as jlink.sh, but much less of a hasle
+ $(EACOMMANDER) --flash $< --verify --mode mcu --address 0 --reset
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/README b/examples/efm32/tinygecko/efm32-tg-stk3300/README
new file mode 100644
index 0000000..ffa3b59
--- /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/lcd_demo/Makefile b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/Makefile
new file mode 100644
index 0000000..7ef06ad
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/Makefile
@@ -0,0 +1,23 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+BINARY = lcd_demo
+
+include ../Makefile.include
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/README b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/README
new file mode 100644
index 0000000..207ed10
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/README
@@ -0,0 +1,8 @@
+=========================================
+EFM32-TG-STK3300 Examples LCD Demo README
+=========================================
+
+This is an example on how to use the LCD peripherial on Energy Micro Tiny Gecko
+chips.
+
+It's intended for the EFM32-TG-STK3300 eval board.
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/generate_lcd_mapping.py b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/generate_lcd_mapping.py
new file mode 100644
index 0000000..1b6405f
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/generate_lcd_mapping.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+import yaml
+
+class Font(dict):
+ def __init__(self, letterdict):
+ for (k, v) in letterdict.items():
+ self[k] = set(v.split())
+
+class Display(object):
+ def __init__(self, data):
+ self.mapping = {}
+
+ for c, segs in enumerate(data['coms']):
+ for s, name in enumerate(segs):
+ self.mapping[name] = (c, s)
+
+ def render_text(self, text, symbols, font):
+ cursor = 1
+ segments = set()
+ for letter in text:
+ if letter == '.':
+ segments.add("a%s_dp"%(cursor-1))
+ elif letter == ':':
+ segments.add("a%s_colon"%(cursor-1))
+ elif letter in font:
+ for segment in font[letter]:
+ segments.add("a%s_%s"%(cursor, segment))
+ cursor += 1
+
+ for s in symbols:
+ segments.add(s)
+
+ coms = {}
+ for segment in segments:
+ com, seg = self.mapping[segment]
+ coms[com] = coms.get(com, 0) | (1<<seg)
+
+ return coms
+
+def main():
+ data = yaml.load(open("lcd_mapping.yaml"))
+
+ d = Display(data)
+
+ text = "{FNORD}"
+ symbols = ['gecko']
+ f = Font({
+ '-': 'g1 g2',
+ 'A': 'e f a b c g1 g2',
+ 'C': 'a f e d',
+ 'D': 'a b c d i l',
+ 'E': 'a f g1 g2 e d',
+ 'F': 'a f g1 g2 e',
+ 'H': "f b g1 g2 e c",
+ 'I': "i l a d",
+ 'L': 'f e d',
+ 'M': 'e f h j b c',
+ 'N': 'e f h m c b',
+ 'O': 'a f e d c b',
+ 'R': 'a e f g1 j m',
+ 'T': 'i l a',
+ 'U': 'f e d c b',
+ '[': 'a d e f',
+ ']': 'a b c d',
+ '{': 'a d k h g1',
+ '}': 'a j g2 m d',
+ })
+
+ for com, data in d.render_text(text, symbols, f).items():
+ print "set_bank(%d, %#08.0x);"%(com, data)
+# with open('lcd_mapping.c', 'w') as outfile:
+# for symbol in data['symbols']:
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_demo.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_demo.c
new file mode 100644
index 0000000..d4ddb74
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_demo.c
@@ -0,0 +1,130 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Demo of the LCD display aboard the EFM32-TG-STK330 eval board.
+ */
+
+#include <libopencm3/efm32/tinygecko/cmu.h>
+#include <libopencm3/efm32/tinygecko/gpio.h>
+#include <libopencm3/efm32/tinygecko/lcd.h>
+#include "../lightswitch/lightswitch-common.c"
+void led_toggle(void) { gpio_toggle(GPIO_PD, GPIO7); }
+
+void delay(void)
+{
+ int x;
+
+ /* Start up delay until we mess with clock stuff, so the debugger can catch up. */
+ for(x = 0; x < 10000000; ++x) led_on();
+}
+
+void lcd_init(void)
+{
+ /* LCD is a LE module. We're constantly powered on for now, so using
+ * HFCORECLK/2 */
+ CMU_HFCORECLKEN0 |= CMU_HFCORECLKEN0_LE;
+ CMU_LFCLKSEL = (CMU_LFCLKSEL & ~CMU_LFCLKSEL_LFA_MASK) | CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;
+ /* We need to get this down to reasonable 100Hz from 14MHz, 7MHz at
+ * LFACLK, 70kHz after LFA prescaler, 10kHz after FDIV. Octaplexing
+ * brings us down to about 500Hz. */
+ CMU_LFAPRESC0 |= CMU_LFAPRESC0_LCD_DIV128;
+ CMU_LCDCTRL |= CMU_LCDCTRL_FDIV_MASK; /* factor 7+1 */
+
+ /* If we don't wait for the prescaler to become ready, the "Do it" step
+ * won't pass. */
+ while (CMU_SYNCBUSY & CMU_SYNCBUSY_LFAPRESC0);
+
+ CMU_LFACLKEN0 |= CMU_LFACLKEN0_LCD;
+
+ while (CMU_SYNCBUSY & CMU_SYNCBUSY_LFACLKEN0);
+
+ /* Voltage is around 3.3V anyway, we don't need voltage boosting,
+ * leaving it disabled. I don't fully understand the implications of
+ * biasing yet, but it seems like he more biased the better, and will
+ * just affect frame rate negatively. */
+ LCD_DISPCTRL = (LCD_DISPCTRL & ~(LCD_DISPCTRL_BIAS_MASK | LCD_DISPCTRL_MUX_MASK)) | LCD_DISPCTRL_BIAS_ONEFOURTH | LCD_DISPCTRL_MUX_OCTAPLEX;
+
+ /* Segments default to disabled, enable the 20 relevant ones */
+ LCD_SEGEN = ~(~0<<5);
+
+ /* Do it */
+ LCD_CTRL |= LCD_CTRL_EN;
+
+ while (LCD_SYNCBUSY & LCD_SYNCBUSY_CTRL) led_off();
+ led_on();
+}
+
+void set_bank(u8 com, u32 data)
+{
+ switch(com)
+ {
+ case 0: LCD_SEGD0L = data; break;
+ case 1: LCD_SEGD1L = data; break;
+ case 2: LCD_SEGD2L = data; break;
+ case 3: LCD_SEGD3L = data; break;
+ case 4: LCD_SEGD4L = data; break;
+ case 5: LCD_SEGD5L = data; break;
+ case 6: LCD_SEGD6L = data; break;
+ case 7: LCD_SEGD7L = data; break;
+ }
+}
+
+int main(void)
+{
+ u8 active_bit = 0;
+ u8 active_com = 0;
+
+ gpio_setup();
+
+// delay();
+
+ lcd_init();
+
+ /* "{FNORD}" with a gecko as generated by current generate_lcd_mapping.py */
+set_bank(0, 0x000a00);
+set_bank(1, 0x0031cb);
+set_bank(2, 0x004622);
+set_bank(3, 0x0012a8);
+set_bank(4, 0x00481a);
+set_bank(5, 0x001140);
+set_bank(6, 0x004642);
+set_bank(7, 0x0051ac);
+
+ while(1)
+ {
+ if (pb0_get())
+ {
+ while(pb0_get());
+
+ set_bank(active_com, ~0);
+ active_bit = (active_bit + 1) % 21; /* one more to see where 0 is */
+ set_bank(active_com, ~(1<<active_bit));
+ }
+ if (pb1_get())
+ {
+ while(pb1_get());
+
+ set_bank(active_com, ~0);
+ active_com = (active_com + 1) % 9; /* one more to see where 0 is */
+ set_bank(active_com, ~(1<<active_bit));
+ }
+ led_toggle();
+ }
+}
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_mapping.yaml b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_mapping.yaml
new file mode 100644
index 0000000..e3efbe1
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_mapping.yaml
@@ -0,0 +1,192 @@
+description:
+ LCD segment layout for the EFM32TG_STK3300 kit.
+
+ Determined by trial and error.
+
+ The digit display is called D1..D4 left to right, the alphanumerics
+ A1..A7.
+
+ The 7 segment display bars are labeled a..g from top cw with g being
+ the last in the center.
+
+ The 14 segment display bars are labelled a..f as with 7-segment, g1
+ and g2 the parts of 7-segment's g from left to right, and then h, i,
+ j left to right top parts, and k, l, m left to right bottom parts.
+
+ (Labelling according to the 7 segment display Wikipedia article; for 14,
+ found in German Wikipedia.)
+
+ Sectors start at the top, CCW.
+
+ Rings are numbered from the outside startin at 0, the dot in the middle
+ being 4.
+symbols: [efm, antenna, celsius, fahrenheit]
+coms:
+ -
+ - sector_0
+ - sector_1
+ - sector_2
+ - sector_3
+ - sector_4
+ - sector_5
+ - sector_6
+ - sector_7
+ - efm
+ - a5_a
+ - a4_colon
+ - a6_a
+ - antenna
+ - battery_outline
+ - celsius
+ - fahrenheit
+ - battery_1
+ - battery_0
+ - battery_2
+ - ring0
+ -
+ - gecko
+ - a1_a
+ - a1_b
+ - a2_a
+ - a2_b
+ - a3_a
+ - a3_b
+ - a4_a
+ - a4_b
+ - a5_h
+ - a5_b
+ - a6_h
+ - a6_b
+ - a7_a
+ - a7_b
+ - d4_d
+ - d3_d
+ - d2_d
+ - d1_d
+ - ring1
+ -
+ - lock_closed
+ - a1_h
+ - a1_j
+ - a2_h
+ - a2_j
+ - a3_h
+ - a3_j
+ - a4_h
+ - a4_j
+ - a5_f
+ - a5_j
+ - a6_f
+ - a6_j
+ - a7_h
+ - a7_j
+ - d4_c
+ - d3_c
+ - d2_c
+ - d1_c
+ - ring3
+ -
+ - a_minus
+ - a1_f
+ - a1_i
+ - a2_f
+ - a2_i
+ - a3_f
+ - a3_i
+ - a4_f
+ - a4_i
+ - a5_g1
+ - a5_i
+ - a6_g1
+ - a6_i
+ - a7_f
+ - a7_i
+ - d4_e
+ - d3_e
+ - d2_e
+ - d1_e
+ - lock_open
+ -
+ - a2_colon
+ - a1_g1
+ - a1_g2
+ - a2_g1
+ - a2_g2
+ - a3_g1
+ - a3_g2
+ - a4_g1
+ - a4_g2
+ - a5_l
+ - a5_g2
+ - a6_l
+ - a6_g2
+ - a7_g1
+ - a7_g2
+ - d4_g
+ - d3_g
+ - d2_g
+ - d1_g
+ - d2_dp
+ -
+ - a2_dp
+ - a1_l
+ - a1_c
+ - a2_l
+ - a2_c
+ - a3_l
+ - a3_c
+ - a4_l
+ - a4_c
+ - a5_k
+ - a5_c
+ - a6_k
+ - a6_c
+ - a7_l
+ - a7_c
+ - d4_b
+ - d3_b
+ - d2_b
+ - d1_b
+ - d2_dp
+ -
+ - a4_dp
+ - a1_k
+ - a1_m
+ - a2_k
+ - a2_m
+ - a3_k
+ - a3_m
+ - a4_k
+ - a4_m
+ - a5_e
+ - a5_m
+ - a6_e
+ - a6_m
+ - a7_k
+ - a7_m
+ - d4_f
+ - d3_f
+ - d2_f
+ - d1_f
+ - ring4
+ -
+ - a1_dp
+ - a1_e
+ - a1_d
+ - a2_e
+ - a2_d
+ - a3_e
+ - a3_d
+ - a4_e
+ - a4_d
+ - a4_dp
+ - a5_d
+ - a5_dp
+ - a6_d
+ - a7_e
+ - a7_d
+ - d4_a
+ - d3_a
+ - d2_a
+ - d1_a
+ - ring2
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/Makefile b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/Makefile
new file mode 100644
index 0000000..d3a1987
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/Makefile
@@ -0,0 +1,22 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+BINARY = lightswitch
+
+include ../Makefile.include
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README
new file mode 100644
index 0000000..41943dc
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README
@@ -0,0 +1,13 @@
+============================================
+EFM32-TG-STK3300 Examples lightswitch README
+============================================
+
+This is a small example program for GPIO input and output, and how the device
+can be configured to use minimal power (although the example is merely
+scratching the surface of what is possible powersaving-wise).
+
+It's intended for the EFM32-TG-STK3300 eval board. It turn the User LED on when
+PB0 is pressed, and off when PB1 is pressed.
+
+Various implementations are offered (-busywait, -interrupt), and can configured
+in lightswitch.c.
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c
new file mode 100644
index 0000000..d78d0e1
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/efm32/tinygecko/irq.h>
+#include <libopencm3/efm32/tinygecko/emu.h>
+
+#define ISER0 MMIO32(0xE000E100)
+#define ICER0 MMIO32(0xE000E180)
+#define ISPR0 MMIO32(0XE000E200)
+#define ICPR0 MMIO32(0XE000E280)
+
+/** @file Simplest implementation of the lightswitch mechanism. */
+
+int main(void)
+{
+ gpio_setup();
+
+ while(1) {
+ if (pb0_get())
+ led_on();
+ if (pb1_get())
+ led_off();
+ };
+}
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c
new file mode 100644
index 0000000..dcc5984
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file Common definitions used by all lightswitch implementations */
+
+#include <libopencm3/efm32/tinygecko/gpio.h>
+#include <libopencm3/efm32/tinygecko/cmu.h>
+
+/** The User LED is connected to PD7 to the plus side of the LED according to
+ * t0011_efm32_tiny_gecko_stk_user_manual.pdf figures 16.2 and 16.3 (called
+ * UIF_LED0)
+ */
+#define LED_PORT GPIO_PD
+#define LED_PIN GPIO7
+
+#define BUTTON0_PORT GPIO_PD
+#define BUTTON0_PORT_EXTIPSEL GPIO_EXTIPSEL_PORTD
+#define BUTTON0_PIN_NUMBER 8
+#define BUTTON0_PIN GPIO8
+#define BUTTON1_PORT GPIO_PB
+#define BUTTON1_PORT_EXTIPSEL GPIO_EXTIPSEL_PORTB
+#define BUTTON1_PIN_NUMBER 11
+#define BUTTON1_PIN GPIO11
+
+void gpio_setup(void);
+void led_on(void);
+void led_off(void);
+
+bool pb0_get(void);
+bool pb1_get(void);
+
+/**
+ * Enable GPIO, and set up port D7 as an output pin and D8 and B11 as input.
+ */
+
+void gpio_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
+
+ CMU_HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
+
+ gpio_set_mode(LED_PORT, GPIO_MODE_PUSHPULL, LED_PIN);
+
+ // Button PB0 is connected to pin PD8 and pulled low when pushed,
+ // Botton PB1 to pin PB11 (sources as for LED). Pullups and debouncing
+ // are alreay in place in hardware, so no filtering or pullup is
+ // needed.
+
+ gpio_set_mode(BUTTON0_PORT, GPIO_MODE_INPUT, BUTTON0_PIN);
+ gpio_set_mode(BUTTON1_PORT, GPIO_MODE_INPUT, BUTTON1_PIN);
+}
+
+void led_on(void)
+{
+ gpio_set(LED_PORT, LED_PIN);
+}
+
+void led_off(void)
+{
+ gpio_clear(LED_PORT, LED_PIN);
+}
+
+bool pb0_get(void)
+{
+ return !gpio_get(GPIO_PD, GPIO8);
+}
+
+bool pb1_get(void)
+{
+ return !gpio_get(GPIO_PB, GPIO11);
+}
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c
new file mode 100644
index 0000000..71a1008
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/efm32/tinygecko/irq.h>
+#include <libopencm3/efm32/tinygecko/emu.h>
+
+#define ISER0 MMIO32(0xE000E100)
+
+void interrupt_setup()
+{
+ // These are the ports the pin interrupts for 8 and 11 are to be
+ // configured to, and they should trigger on falling edge.
+
+ GPIO_EXTIPSELH = (BUTTON0_PORT_EXTIPSEL << ((BUTTON0_PIN_NUMBER-8)*4)) |
+ (BUTTON1_PORT_EXTIPSEL << ((BUTTON1_PIN_NUMBER-8)*4));
+
+ GPIO_EXTIFALL = BUTTON0_PIN | BUTTON1_PIN;
+
+ // Enable interrupts on the GPIO side
+
+ GPIO_INSENSE = GPIO_INSENSE_INT;
+ GPIO_IEN = BUTTON0_PIN | BUTTON1_PIN;
+
+ // Enable GPIO interrupts in NVIC
+
+ ISER0 = (1<<IRQ_GPIO_EVEN) | (1<<IRQ_GPIO_ODD);
+}
+
+int main(void)
+{
+ gpio_setup();
+ interrupt_setup();
+
+ while(1) {
+ emu_sleep_em1();
+ };
+}
+
+void gpio_even_isr()
+{
+ // Clearing the GPIO interrupt pending register. While the NVIC
+ // interrupt pending register gets cleared automatically once it jumps
+ // here, the pin's pending state has to be cleared explicitly.
+ // (Dispatch to different subroutines for different even pins that
+ // trigger an interrupt would happen here.)
+ GPIO_IFC = BUTTON0_PIN;
+ led_on();
+}
+
+void gpio_odd_isr()
+{
+ // See gpio_even_isr.
+ GPIO_IFC = BUTTON1_PIN;
+ led_off();
+}
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c
new file mode 100644
index 0000000..72a5299
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Example for switching the User LED of the EFM32-TG-STK330 eval board on and
+ * off using the buttons.
+ */
+
+#include "lightswitch-common.c"
+
+/** Change this include to -busywait, -interrupt, or -prs (not implemented
+ * yet). The overall behavior will not change, but different implementations
+ * will be used. */
+#include "lightswitch-busywait.c"
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/Makefile b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/Makefile
new file mode 100644
index 0000000..0da7462
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/Makefile
@@ -0,0 +1,26 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+BINARY = miniblink
+
+OBJS += efm32_gpio.o efm32_cmu.o
+CFLAGS += -I/tmp/EFM32_CMSIS_2.4.1/efm32lib/inc/ -I /tmp/EFM32_CMSIS_2.4.1/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/ -DEFM32TG840F32 -I.
+
+include ../Makefile.include
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/README b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/README
new file mode 100644
index 0000000..49c6d11
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/README
@@ -0,0 +1,9 @@
+===================================================
+EFM32-TG-STK3300 Examples miniblink-efm32lib README
+===================================================
+
+This is a port of the miniblink example to the efm32lib library.
+
+It's intended for the EFM32-TG-STK3300 eval board. It should blink the user LED
+on the board, just as the original miniblink example does.
+
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/efm32_cmu.c b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/efm32_cmu.c
new file mode 120000
index 0000000..168574b
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/efm32_cmu.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_cmu.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/efm32_gpio.c b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/efm32_gpio.c
new file mode 120000
index 0000000..0b2df21
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/efm32_gpio.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_gpio.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/miniblink.c b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/miniblink.c
new file mode 100644
index 0000000..9fa0b23
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink-efm32lib/miniblink.c
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <efm32_cmu.h>
+#include <efm32_gpio.h>
+
+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)
+{
+ int x;
+
+ led_setup();
+
+ while(1) {
+ for(x = 0; x < 200000; ++x) asm("mov r0,r0"); /* no-op, prevent compiler from optimizing this away */
+ 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
+
+ CMU->HFPERCLKEN0 |= _CMU_HFPERCLKEN0_GPIO_MASK;
+
+ // The User LED is connected to PD7 to the plus side of the LED
+ // according to t0011_efm32_tiny_gecko_stk_user_manual.pdf figures 16.2
+ // and 16.3 (called UIF_LED0)
+
+ GPIO_PinModeSet(gpioPortD, 7, gpioModePushPull, 0);
+}
+
+void led_toggle(void)
+{
+ GPIO_PinOutToggle(gpioPortD, 7);
+}
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 0000000..760b99b
--- /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 <uwe@hermann-uwe.de>
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+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 0000000..d19e4fe
--- /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 0000000..0269847
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/miniblink/miniblink.c
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/efm32/tinygecko/gpio.h>
+#include <libopencm3/efm32/tinygecko/cmu.h>
+
+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)
+{
+ int x;
+
+ led_setup();
+
+ while(1) {
+ for(x = 0; x < 200000; ++x) asm("mov r0,r0"); /* no-op, prevent compiler from optimizing this away */
+ 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
+
+ CMU_HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
+
+ // The User LED is connected to PD7 to the plus side of the LED
+ // according to t0011_efm32_tiny_gecko_stk_user_manual.pdf figures 16.2
+ // and 16.3 (called UIF_LED0)
+
+ gpio_set_mode(GPIO_PD, GPIO_MODE_PUSHPULL, GPIO7);
+ // GPIO_PD_MODEL = GPIO_MODE_PUSHPULL<<(7*4);
+}
+
+void led_toggle(void)
+{
+ gpio_toggle(GPIO_PD, GPIO7);
+ // GPIO_PD_DOUTTGL = 1<<7;
+}
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/Makefile.include b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/Makefile.include
new file mode 100644
index 0000000..6e927a6
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/Makefile.include
@@ -0,0 +1,29 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+MCU = EFM32TG840F32
+FAMILY = GECKO
+
+EACOMMANDER = ~/energymicro/energymicro/eACommander.sh
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../Makefile.include
+
+upload: $(BINARY).bin
+ # eacommander is just as nonfree as jlink.sh, but much less of a hasle
+ $(EACOMMANDER) --flash $< --verify --mode out --address 0 --reset
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/README b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/README
new file mode 100644
index 0000000..7360a8c
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/README
@@ -0,0 +1,14 @@
+========================
+EM-32G880F128-H Examples
+========================
+
+Examples in this directory are designed to be run on the OlimexEM-32G880F128-H
+header breakout board, which is based on the EFM32G880F128 MCU.
+
+The board is equipped with two user LEDs, a user button, reset button, power
+supply, 20 pin debug connector and 10 pin UEXT connector (Olimex' open
+versatile microcontroller connector).
+
+The build system is designed to upload programs using the EFM32-TG-STK3300
+board's external Segger debugger, which has to be configured for external
+operation beforehand.
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/Makefile b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/Makefile
new file mode 100644
index 0000000..df8985a
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/Makefile
@@ -0,0 +1,26 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+BINARY = miniblink
+
+OBJS += efm32_gpio.o efm32_cmu.o
+CFLAGS += -I/tmp/EFM32_CMSIS_2.4.1/efm32lib/inc/ -I /tmp/EFM32_CMSIS_2.4.1/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/ -DEFM32G880F128 -I.
+
+include ../Makefile.include
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/README b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/README
new file mode 100644
index 0000000..2500f4d
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/README
@@ -0,0 +1,9 @@
+====================================================
+EM32-32G880F128-H Examples miniblink-efm32lib README
+====================================================
+
+This is a port of the miniblink example to the efm32lib library.
+
+It's intended for the EM32-32G880F128-H eval board. It should blink LED1 on the
+board, just as the original miniblink example does.
+
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/efm32_cmu.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/efm32_cmu.c
new file mode 120000
index 0000000..168574b
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/efm32_cmu.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_cmu.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/efm32_gpio.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/efm32_gpio.c
new file mode 120000
index 0000000..0b2df21
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/efm32_gpio.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_gpio.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/miniblink.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/miniblink.c
new file mode 100644
index 0000000..3838c94
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/miniblink-efm32lib/miniblink.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <efm32_cmu.h>
+#include <efm32_gpio.h>
+
+void led_setup(void);
+void led_toggle(void);
+
+/** @file
+ * Minimal example for making the User LED of the olimex EM32-32G880F128-H 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)
+{
+ int x;
+
+ led_setup();
+
+ while(1) {
+ for(x = 0; x < 200000; ++x) asm("mov r0,r0"); /* no-op, prevent compiler from optimizing this away */
+ led_toggle();
+ };
+}
+
+/**
+ * Enable GPIO, and set up port E1 as an output pin, and inverted.
+ */
+
+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
+
+ CMU->HFPERCLKEN0 |= _CMU_HFPERCLKEN0_GPIO_MASK;
+
+ // The User LED is connected to PD7 to the plus side of the LED
+ // according to t0011_efm32_tiny_gecko_stk_user_manual.pdf figures 16.2
+ // and 16.3 (called UIF_LED0)
+
+ GPIO_PinModeSet(gpioPortE, 1, gpioModePushPull, 0);
+}
+
+void led_toggle(void)
+{
+ GPIO_PinOutToggle(gpioPortE, 1);
+}
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/Makefile b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/Makefile
new file mode 100644
index 0000000..181e15a
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/Makefile
@@ -0,0 +1,26 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+BINARY = test
+
+OBJS += core_cm3.o $(patsubst %.c,%.o,$(wildcard efm32_*.c))
+CFLAGS += -I/tmp/EFM32_CMSIS_2.4.1/efm32lib/inc/ -I /tmp/EFM32_CMSIS_2.4.1/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/ -DEFM32G880F128 -I.
+
+include ../Makefile.include
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_acmp.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_acmp.c
new file mode 120000
index 0000000..1e1fcef
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_acmp.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_acmp.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_adc.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_adc.c
new file mode 120000
index 0000000..00fca91
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_adc.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_adc.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_aes.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_aes.c
new file mode 120000
index 0000000..5048a82
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_aes.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_aes.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_assert.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_assert.c
new file mode 120000
index 0000000..d5de54d
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_assert.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_assert.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_burtc.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_burtc.c
new file mode 120000
index 0000000..8a73bbd
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_burtc.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_burtc.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_cmu.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_cmu.c
new file mode 120000
index 0000000..168574b
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_cmu.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_cmu.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dac.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dac.c
new file mode 120000
index 0000000..7e12e03
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dac.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_dac.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dbg.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dbg.c
new file mode 120000
index 0000000..1e0b9ae
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dbg.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_dbg.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dma.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dma.c
new file mode 120000
index 0000000..c72b91c
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_dma.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_dma.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_ebi.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_ebi.c
new file mode 120000
index 0000000..c9d26bb
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_ebi.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_ebi.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_emu.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_emu.c
new file mode 120000
index 0000000..7a8b76e
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_emu.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_emu.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_gpio.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_gpio.c
new file mode 120000
index 0000000..0b2df21
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_gpio.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_gpio.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_i2c.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_i2c.c
new file mode 120000
index 0000000..681adc3
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_i2c.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_i2c.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_int.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_int.c
new file mode 120000
index 0000000..176d6cf
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_int.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_int.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_lcd.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_lcd.c
new file mode 120000
index 0000000..4d6026b
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_lcd.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_lcd.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_lesense.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_lesense.c
new file mode 120000
index 0000000..8c7ea28
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_lesense.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_lesense.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_letimer.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_letimer.c
new file mode 120000
index 0000000..aa5eca6
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_letimer.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_letimer.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_leuart.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_leuart.c
new file mode 120000
index 0000000..64b3a57
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_leuart.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_leuart.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_mpu.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_mpu.c
new file mode 120000
index 0000000..141dcfb
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_mpu.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_mpu.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_msc.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_msc.c
new file mode 120000
index 0000000..c1f750e
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_msc.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_msc.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_opamp.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_opamp.c
new file mode 120000
index 0000000..b6a558b
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_opamp.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_opamp.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_pcnt.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_pcnt.c
new file mode 120000
index 0000000..2df78bd
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_pcnt.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_pcnt.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_prs.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_prs.c
new file mode 120000
index 0000000..15b98fe
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_prs.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_prs.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_rmu.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_rmu.c
new file mode 120000
index 0000000..242f40d
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_rmu.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_rmu.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_rtc.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_rtc.c
new file mode 120000
index 0000000..9ec9a46
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_rtc.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_rtc.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_system.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_system.c
new file mode 120000
index 0000000..74114f4
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_system.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_system.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_timer.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_timer.c
new file mode 120000
index 0000000..b81acaa
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_timer.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_timer.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_usart.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_usart.c
new file mode 120000
index 0000000..7c78c2c
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_usart.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_usart.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_vcmp.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_vcmp.c
new file mode 120000
index 0000000..e3b6650
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_vcmp.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_vcmp.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_wdog.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_wdog.c
new file mode 120000
index 0000000..12c48f1
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/efm32_wdog.c
@@ -0,0 +1 @@
+/tmp/EFM32_CMSIS_2.4.1/efm32lib/src/efm32_wdog.c \ No newline at end of file
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/gdbinit b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/gdbinit
new file mode 100644
index 0000000..7ccaa72
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/gdbinit
@@ -0,0 +1,14 @@
+# gets set when loading the file, without this i get the "Remote 'g' packet
+# reply is too long" errors
+set arm abi AAPCS
+
+target remote localhost:2331
+monitor speed auto
+# this seems to be less about the architecture and more about how to
+# communicate with gdb. "set endian big" works just as well.
+monitor endian little
+
+# sometimes this doesn't work, then the gdbserver has to be restarted
+monitor reset
+monitor go
+monitor halt
diff --git a/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/test.c b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/test.c
new file mode 100644
index 0000000..02954bb
--- /dev/null
+++ b/examples/efm32/tinygecko/olimex-em32-32g880f128-h/test-efm32lib/test.c
@@ -0,0 +1,115 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <efm32_acmp.h>
+#include <efm32_adc.h>
+#include <efm32_aes.h>
+#include <efm32_assert.h>
+#include <efm32_bitband.h>
+#include <efm32_burtc.h>
+#include <efm32_chip.h>
+#include <efm32_cmu.h>
+#include <efm32_common.h>
+#include <efm32_dac.h>
+#include <efm32_dbg.h>
+#include <efm32_dma.h>
+#include <efm32_ebi.h>
+#include <efm32_emu.h>
+#include <efm32_gpio.h>
+#include <efm32_i2c.h>
+#include <efm32_int.h>
+#include <efm32_lcd.h>
+#include <efm32_lesense.h>
+#include <efm32_letimer.h>
+#include <efm32_leuart.h>
+#include <efm32_mpu.h>
+#include <efm32_msc.h>
+#include <efm32_opamp.h>
+#include <efm32_pcnt.h>
+#include <efm32_prs.h>
+#include <efm32_rmu.h>
+#include <efm32_rtc.h>
+#include <efm32_system.h>
+#include <efm32_timer.h>
+#include <efm32_usart.h>
+#include <efm32_vcmp.h>
+#include <efm32_version.h>
+#include <efm32_wdog.h>
+
+#include <stdio.h>
+
+void setup(void);
+void led_toggle(void);
+bool button_is_pressed(void);
+void debug(int a);
+
+#define LOG_SIZE 1024
+volatile char logbuffer[LOG_SIZE];
+
+int main(void)
+{
+ int x;
+ int n_pressed = 0;
+
+ setup();
+
+ while(1) {
+ if (button_is_pressed())
+ {
+ for(x = 0; x < 200000; ++x) asm("mov r0,r0"); /* no-op, prevent compiler from optimizing this away */
+ n_pressed += 1;
+ debug(n_pressed);
+ }
+ led_toggle();
+ };
+}
+
+void debug(int a)
+{
+ snprintf(logbuffer, LOG_SIZE, "Data %d.\n", a);
+}
+
+void 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
+
+ CMU->HFPERCLKEN0 |= _CMU_HFPERCLKEN0_GPIO_MASK;
+
+ GPIO_PinModeSet(gpioPortE, 1, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortE, 2, gpioModePushPull, 0);
+
+ GPIO_PinModeSet(gpioPortE, 0, gpioModeInputPull, 1); /* pull up */
+
+ // Counter-blink the other user LED
+
+ GPIO_PinOutToggle(gpioPortE, 2);
+}
+
+void led_toggle(void)
+{
+ GPIO_PinOutToggle(gpioPortE, 1);
+ GPIO_PinOutToggle(gpioPortE, 2);
+}
+
+bool button_is_pressed(void)
+{
+ return !GPIO_PinInGet(gpioPortE, 0);
+}
diff --git a/include/libopencm3/efm32/memorymap.h b/include/libopencm3/efm32/memorymap.h
new file mode 100644
index 0000000..ff0e544
--- /dev/null
+++ b/include/libopencm3/efm32/memorymap.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ *
+ * Dispatcher for the base address definitions, depending on the particular
+ * Gecko family.
+ *
+ * @see tinygecko/memorymap.h
+ */
+
+#ifndef LIBOPENCM3_EFM32_MEMORYMAP_H
+#define LIBOPENCM3_EFM32_MEMORYMAP_H
+
+#ifdef TINYGECKO
+# include <libopencm3/efm32/tinygecko/memorymap.h>
+#else
+# error "efm32 family not defined."
+#endif
+
+#endif
diff --git a/include/libopencm3/efm32/tinygecko/README.dox b/include/libopencm3/efm32/tinygecko/README.dox
new file mode 100644
index 0000000..04da755
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/README.dox
@@ -0,0 +1,14 @@
+/**
+
+@brief EFM32 Tiny Gecko headers
+
+This directory contains all headers specific to the Tiny Gecko family of the
+Energy Micro EFM32 series.
+
+The individual peripherials described here all include hints at where the
+information was taken from, but usually it stems from
+d0034_efm32tg_reference_manual.pdf.
+
+@defgroup EFM32TG EFM32 Tiny Gecko
+
+*/
diff --git a/include/libopencm3/efm32/tinygecko/cmu.convenienceheaders b/include/libopencm3/efm32/tinygecko/cmu.convenienceheaders
new file mode 100644
index 0000000..212405d
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/cmu.convenienceheaders
@@ -0,0 +1,63 @@
+/** CMU convenience functions
+ *
+ * These functions assist in clock switching, and are intended to be safer to
+ * use than direct fiddling with registers. They try to be suitable for typical
+ * applications, and will invest some bytes of code in order to minimize power
+ * consumption.
+ *
+ * @todo Work on this module is stalled until I can figure out if there is a
+ * way to have a cmu_shutdown_unused function at all.
+ *
+ * @defgroup EFM32TG_CMU_convenience CMU convenience functions
+ * @{
+ */
+
+/** Disable all oscillators not currently in use.
+ *
+ * The implementation follows d0034_efm32tg_reference_manual.pdf figure 11.1.
+ * The clock out pin configurations are not depicted there, but described in
+ * section 11.3.4.
+ *
+ * @todo This function is ignorant of ongoing calibrations.
+ *
+ * @todo This doesn't work at all: Fields like HFCLKSEL are write-only.
+ * */
+static void cmu_shutdown_unused(void)
+{
+ /* Is HFXO needed? */
+ if (!(
+ (CMU_CMD & CMU_CMD_HFCLKSEL_MASK) == CMU_CMD_HFCLKSEL_HFXO ||
+ (
+ (CMU_CTRL & CMU_CTRL_CLKOUTSEL1_MASK) == CMU_CTRL_CLKOUTSEL1_HFXOQ &&
+ (CMU_ROUTE & CMU_ROUTE_CLKOUT1PEN)
+ ) || (
+ (CMU_CTRL & CMU_CTRL_CLKOUTSEL0_MASK) == CMU_CTRL_CLKOUTSEL0_HFXO &&
+ (CMU_ROUTE & CMU_ROUTE_CLKOUT0PEN)
+ )))
+ CMU_OSCENCMD = CMU_OSCENCMD_HFXODIS;
+
+ /* Is HFRCO neede? */
+ if (!(
+ (CMU_CMD & CMU_CMD_HFCLKSEL_MASK) == CMU_CMD_HFCLKSEL_HFRCO ||
+ (
+ (CMU_CTRL & CMU_CTRL_CLKOUTSEL1_MASK) == CMU_CTRL_CLKOUTSEL1_HFRCOQ &&
+ (CMU_ROUTE & CMU_ROUTE_CLKOUT1PEN)
+ ) || (
+ (CMU_CTRL & CMU_CTRL_CLKOUTSEL0_MASK) == CMU_CTRL_CLKOUTSEL0_HFRCO &&
+ (CMU_ROUTE & CMU_ROUTE_CLKOUT0PEN)
+ )))
+ {}
+// CMU_OSCENCMD = CMU_OSCENCMD_HFRCODIS;
+}
+
+/** Switch HFCLK to LFRC. This call is not only blocking, but even freezes
+ * everything depending on HFCLK until LFRC is stable. The procedure is
+ * sketched in d0034_efm32tg_reference_manual.pdf figure 11.2. */
+static void cmu_hfclk_switch_blocking(void)
+{
+ CMU_OSCENCMD = CMU_OSCENCMD_LFRCOEN;
+ CMU_CMD = CMU_CMD_HFCLKSEL_LFRCO;
+ CMU_OSCENCMD = CMU_OSCENCMD_HFRCODIS;
+}
+
+/** @} */
diff --git a/include/libopencm3/efm32/tinygecko/cmu.h b/include/libopencm3/efm32/tinygecko/cmu.h
new file mode 100644
index 0000000..80c959f
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/cmu.h
@@ -0,0 +1,678 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * @see EFM32TG_CMU
+ */
+
+/** Definitions for the CMU subsystem (Clock Management Unit).
+ *
+ * This corresponds to the description in d0034_efm32tg_reference_manual.pdf
+ * section 11.
+ *
+ * @ingroup EFM32TG
+ * @defgroup EFM32TG_CMU CMU (Clock Management Unit)
+ * @{
+ */
+
+#ifndef LIBOPENCM3_EFM32_TINYGECKO_CMU_H
+#define LIBOPENCM3_EFM32_TINYGECKO_CMU_H
+
+#include <libopencm3/cm3/common.h>
+#include <libopencm3/efm32/memorymap.h>
+
+/** Register definitions and register value definitions for the CMU subsystem
+ *
+ * @defgroup EFM32TG_CMU_regsandvals CMU registers and values
+ * @{
+ */
+
+/** These definitions reflect d0034_efm32tg_reference_manual.pdf section 11.4
+ *
+ * @defgroup EFM32TG_CMU_registers CMU registers
+ * @{
+ */
+
+#define CMU_CTRL MMIO32(CMU_BASE + 0x000) /**< @see EFM32TG_CMU_CTRL_bits */
+#define CMU_HFCORECLKDIV MMIO32(CMU_BASE + 0x004) /**< @see EFM32TG_CMU_HFCORECLKDIV_values */
+#define CMU_HFPERCLKDIV MMIO32(CMU_BASE + 0x008) /**< @see EFM32TG_CMU_HFPERCLKDIV_bits */
+#define CMU_HFRCOCTRL MMIO32(CMU_BASE + 0x00c) /**< @see EFM32TG_CMU_HFRCOCTRL_bits */
+#define CMU_LFRCOCTRL MMIO32(CMU_BASE + 0x010)
+#define CMU_AUXHFRCOCTRL MMIO32(CMU_BASE + 0x014) /**< @see EFM32TG_CMU_AUXHFRCOCTRL_bits */
+#define CMU_CALCTRL MMIO32(CMU_BASE + 0x018) /**< @see EFM32TG_CMU_CALCTRL_bits */
+#define CMU_CALCNT MMIO32(CMU_BASE + 0x01c)
+#define CMU_OSCENCMD MMIO32(CMU_BASE + 0x020) /**< @see EFM32TG_CMU_OSCENCMD_bits */
+#define CMU_CMD MMIO32(CMU_BASE + 0x024) /**< @see EFM32TG_CMU_CMD_bits */
+#define CMU_LFCLKSEL MMIO32(CMU_BASE + 0x028) /**< @see EFM32TG_CMU_LFCLKSEL_bits */
+#define CMU_STATUS MMIO32(CMU_BASE + 0x02c) /**< @see EFM32TG_CMU_STATUS_bits */
+#define CMU_IF MMIO32(CMU_BASE + 0x030) /**< @see EFM32TG_CMU_I_bits */
+#define CMU_IFS MMIO32(CMU_BASE + 0x034) /**< @see EFM32TG_CMU_I_bits */
+#define CMU_IFC MMIO32(CMU_BASE + 0x038) /**< @see EFM32TG_CMU_I_bits */
+#define CMU_IEN MMIO32(CMU_BASE + 0x03c) /**< @see EFM32TG_CMU_I_bits */
+#define CMU_HFCORECLKEN0 MMIO32(CMU_BASE + 0x040) /**< @see EFM32TG_CMU_HFCORECLKEN0_bits */
+#define CMU_HFPERCLKEN0 MMIO32(CMU_BASE + 0x044) /**< @see EFM32TG_CMU_HFPERCLKEN0_bits */
+#define CMU_SYNCBUSY MMIO32(CMU_BASE + 0x050) /**< @see EFM32TG_CMU_SYNCBUSY_bits */
+#define CMU_FREEZE MMIO32(CMU_BASE + 0x054) /**< @see EFM32TG_CMU_FREEZE_bits */
+#define CMU_LFACLKEN0 MMIO32(CMU_BASE + 0x058) /**< @see EFM32TG_CMU_LFACLKEN0_bits */
+#define CMU_LFBCLKEN0 MMIO32(CMU_BASE + 0x060) /**< @see EFM32TG_CMU_LFBCLKEN0_bits */
+#define CMU_LFAPRESC0 MMIO32(CMU_BASE + 0x068) /**< @see EFM32TG_CMU_LFAPRESC0_bits */
+#define CMU_LFBPRESC0 MMIO32(CMU_BASE + 0x070) /**< @see EFM32TG_CMU_LFBPRESC0_bits */
+#define CMU_PCNTCTRL MMIO32(CMU_BASE + 0x078) /**< @see EFM32TG_CMU_PCNTCTRL_bits */
+#define CMU_LCDCTRL MMIO32(CMU_BASE + 0x07c) /**< @see EFM32TG_CMU_LCDCTRL_bits */
+#define CMU_ROUTE MMIO32(CMU_BASE + 0x080) /**< @see EFM32TG_CMU_ROUTE_bits */
+#define CMU_LOCK MMIO32(CMU_BASE + 0x084) /**< @see EFM32TG_CMU_LOCK_values */
+
+/** @} */
+
+/** Bit states for the CMU_CTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.1 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_CTRL_bits CMU CTRL bits
+ * @{
+ */
+
+#define CMU_CTRL_DBGCLK_AUXHFRCO (0<<28)
+#define CMU_CTRL_DBGCLK_HFCLK (1<<28)
+#define CMU_CTRL_DBGCLK_MASK (0x1<<28)
+#define CMU_CTRL_CLKOUTSEL1_LFRCO (0<<23)
+#define CMU_CTRL_CLKOUTSEL1_LFXO (1<<23)
+#define CMU_CTRL_CLKOUTSEL1_HFCLK (2<<23)
+#define CMU_CTRL_CLKOUTSEL1_LFXOQ (3<<23)
+#define CMU_CTRL_CLKOUTSEL1_HFXOQ (4<<23)
+#define CMU_CTRL_CLKOUTSEL1_LFRCOQ (5<<23)
+#define CMU_CTRL_CLKOUTSEL1_HFRCOQ (6<<23)
+#define CMU_CTRL_CLKOUTSEL1_AUXHFRCOQ (7<<23)
+#define CMU_CTRL_CLKOUTSEL1_MASK (0x7<<23)
+#define CMU_CTRL_CLKOUTSEL0_HFRCO (0<<20)
+#define CMU_CTRL_CLKOUTSEL0_HFXO (1<<20)
+#define CMU_CTRL_CLKOUTSEL0_HFCLK2 (2<<20)
+#define CMU_CTRL_CLKOUTSEL0_HFCLK4 (3<<20)
+#define CMU_CTRL_CLKOUTSEL0_HFCLK8 (4<<20)
+#define CMU_CTRL_CLKOUTSEL0_HFCLK16 (5<<20)
+#define CMU_CTRL_CLKOUTSEL0_ULFRCO (6<<20)
+#define CMU_CTRL_CLKOUTSEL0_AUXHFRCO (7<<20)
+#define CMU_CTRL_CLKOUTSEL0_MASK (0x7<<20)
+#define CMU_CTRL_LFXOTIMEOUT_8CYCLES (0<<18)
+#define CMU_CTRL_LFXOTIMEOUT_1KCYCLES (1<<18)
+#define CMU_CTRL_LFXOTIMEOUT_16KCYCLES (2<<18)
+#define CMU_CTRL_LFXOTIMEOUT_32KCYCLES (3<<18)
+#define CMU_CTRL_LFXOTIMEOUT_MASK (0x3<<18)
+#define CMU_CTRL_LFXOBUFCUR (1<<17)
+#define CMU_CTRL_LXFOBOOST_70PCENT (0<<13)
+#define CMU_CTRL_LXFOBOOST_100PCENT (1<<13)
+#define CMU_CTRL_LXFOBOOST_MASK (0x1<<13)
+#define CMU_CTRL_LFXOMODE_XTAL (0<<11)
+#define CMU_CTRL_LFXOMODE_BUFEXTCLK (1<<11)
+#define CMU_CTRL_LFXOMODE_DIGEXTCLK (2<<11)
+#define CMU_CTRL_LFXOMODE_MASK (0x3<<11)
+#define CMU_CTRL_HFXOTIMEOUT_8CYCLES (0<<9)
+#define CMU_CTRL_HFXOTIMEOUT_256CYCLES (1<<9)
+#define CMU_CTRL_HFXOTIMEOUT_1KCYCLES (2<<9)
+#define CMU_CTRL_HFXOTIMEOUT_16KCYCLES (3<<9)
+#define CMU_CTRL_HFXOTIMEOUT_MASK (0x3<<9)
+#define CMU_CTRL_HFXOGLITCHDETEN (1<<7)
+#define CMU_CTRL_HFXOBUFCUR_MASK (0x3<<5)
+#define CMU_CTRL_HFXOBOOST_50PCENT (0<<2)
+#define CMU_CTRL_HFXOBOOST_70PCENT (1<<2)
+#define CMU_CTRL_HFXOBOOST_80PCENT (2<<2)
+#define CMU_CTRL_HFXOBOOST_100PCENT (3<<2)
+#define CMU_CTRL_HFXOBOOST_MASK (0x3<<2)
+#define CMU_CTRL_HFXOMODE_XTAL (0<<0)
+#define CMU_CTRL_HFXOMODE_BUFEXTCLK (1<<0)
+#define CMU_CTRL_HFXOMODE_DIGEXTCLK (2<<0)
+#define CMU_CTRL_HFXOMODE_MASK (0x3<<0)
+
+/** @} */
+
+/** Values for the CMU_HFCORECLKDIV register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.2 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_HFCORECLKDIV_values CMU HFCORECLKDIV values
+ * @{
+ */
+
+#define CMU_HFCORECLKDIV_HFCLK 0
+#define CMU_HFCORECLKDIV_HFCLK2 1
+#define CMU_HFCORECLKDIV_HFCLK4 2
+#define CMU_HFCORECLKDIV_HFCLK8 3
+#define CMU_HFCORECLKDIV_HFCLK16 4
+#define CMU_HFCORECLKDIV_HFCLK32 5
+#define CMU_HFCORECLKDIV_HFCLK64 6
+#define CMU_HFCORECLKDIV_HFCLK128 7
+#define CMU_HFCORECLKDIV_HFCLK256 8
+#define CMU_HFCORECLKDIV_HFCLK512 9
+
+/** @} */
+
+/** Bit states for the CMU_HFPERCLKDIV register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.3 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_HFPERCLKDIV_bits CMU HFPERCLKDIV bits
+ * @{
+ */
+
+#define CMU_HFPERCLKDIV_HFPERCLKEN (1<<8)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK (0<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK2 (1<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK4 (2<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK8 (3<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK16 (4<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK32 (5<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK64 (6<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK128 (7<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK256 (8<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK512 (9<<0)
+#define CMU_HFPERCLKDIV_HFPERCLKDIV_MASK (0x7<<0)
+
+/** @} */
+
+/** Bit states for the CMU_HFRCOCTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.4 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_HFRCOCTRL_bits CMU HFRCOCTRL bits
+ * @{
+ */
+
+#define CMU_HFRCOCTRL_SUDELAY_MASK (0x1f<<12)
+#define CMU_HFRCOCTRL_BAND_1MHZ (0<<8)
+#define CMU_HFRCOCTRL_BAND_7MHZ (1<<8)
+#define CMU_HFRCOCTRL_BAND_11MHZ (2<<8)
+#define CMU_HFRCOCTRL_BAND_14MHZ (3<<8)
+#define CMU_HFRCOCTRL_BAND_21MHZ (4<<8)
+#define CMU_HFRCOCTRL_BAND_28MHZ (5<<8)
+#define CMU_HFRCOCTRL_BAND_MASK (0x7<<8)
+#define CMU_HFRCOCTRL_TUNING_MASK (0xff<<0)
+
+/** @} */
+
+/** Bit states for the CMU_AUXHFRCOCTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.6 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_AUXHFRCOCTRL_bits CMU AUXHFRCOCTRL bits
+ * @{
+ */
+
+#define CMU_AUXHFRCOCTRL_BAND_14MHZ (0<<8)
+#define CMU_AUXHFRCOCTRL_BAND_11MHZ (1<<8)
+#define CMU_AUXHFRCOCTRL_BAND_7MHZ (2<<8)
+#define CMU_AUXHFRCOCTRL_BAND_1MHZ (3<<8)
+#define CMU_AUXHFRCOCTRL_BAND_28MHZ (6<<8)
+#define CMU_AUXHFRCOCTRL_BAND_21MHZ (7<<8)
+#define CMU_AUXHFRCOCTRL_BAND_MASK (0x7<<8)
+#define CMU_AUXHFRCOCTRL_TUNING_MASK (0xff<<0)
+
+/** @} */
+
+/** Bit states for the CMU_CALCTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.6.7 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_CALCTRL_bits CMU CALCTRL bits
+ * @{
+ */
+
+#define CMU_CALCTRL_CONT (1<<6)
+#define CMU_CALCTRL_DOWNSEL_HFCLK (0<<3)
+#define CMU_CALCTRL_DOWNSEL_HFXO (1<<3)
+#define CMU_CALCTRL_DOWNSEL_LFXO (2<<3)
+#define CMU_CALCTRL_DOWNSEL_HFRCO (3<<3)
+#define CMU_CALCTRL_DOWNSEL_LFRCO (4<<3)
+#define CMU_CALCTRL_DOWNSEL_AUXHFRCO (5<<3)
+#define CMU_CALCTRL_DOWNSEL_MASK (0x7<<3)
+#define CMU_CALCTRL_UPSEL_HFXO (0<<0)
+#define CMU_CALCTRL_UPSEL_LFXO (1<<0)
+#define CMU_CALCTRL_UPSEL_HFRCO (2<<0)
+#define CMU_CALCTRL_UPSEL_LFRCO (3<<0)
+#define CMU_CALCTRL_UPSEL_AUXHFRCO (4<<0)
+#define CMU_CALCTRL_UPSEL_MASK (0x7<<0)
+
+/** @} */
+
+/** Bit states for the CMU_OSCENCMD register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.9 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_OSCENCMD_bits CMU OSCENCMD bits
+ * @{
+ */
+
+#define CMU_OSCENCMD_LFXODIS (1<<9)
+#define CMU_OSCENCMD_LFXOEN (1<<8)
+#define CMU_OSCENCMD_LFRCODIS (1<<7)
+#define CMU_OSCENCMD_LFRCOEN (1<<6)
+#define CMU_OSCENCMD_AUXHFRCODIS (1<<5)
+#define CMU_OSCENCMD_AUXHFRCOEN (1<<4)
+#define CMU_OSCENCMD_HFXODIS (1<<3)
+#define CMU_OSCENCMD_HFXOEN (1<<2)
+#define CMU_OSCENCMD_HFRCODIS (1<<1)
+#define CMU_OSCENCMD_HFRCOEN (1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_CMD register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.10 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_CMD_bits CMU CMD bits
+ * @{
+ */
+
+#define CMU_CMD_CALSTOP (1<<4)
+#define CMU_CMD_CALSTART (1<<3)
+#define CMU_CMD_HFCLKSEL_HFRCO (1<<0)
+#define CMU_CMD_HFCLKSEL_HFXO (2<<0)
+#define CMU_CMD_HFCLKSEL_LFRCO (3<<0)
+#define CMU_CMD_HFCLKSEL_LFXO (4<<0)
+#define CMU_CMD_HFCLKSEL_MASK (0x7<<0)
+
+/** @} */
+
+/** Bit states for the CMU_LFCLKSEL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.11 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_LFCLKSEL_bits CMU LFCLKSEL bits
+ * @{
+ */
+
+#define CMU_LFCLKSEL_LFBE_DISABLED (0<<20)
+#define CMU_LFCLKSEL_LFBE_ULFRCO (1<<20)
+#define CMU_LFCLKSEL_LFBE_MASK (0x1<<20)
+#define CMU_LFCLKSEL_LFAE_DISABLED (0<<16)
+#define CMU_LFCLKSEL_LFAE_ULFRCO (1<<16)
+#define CMU_LFCLKSEL_LFAE_MASK (0x1<<16)
+#define CMU_LFCLKSEL_LFB_DISABLED (0<<2)
+#define CMU_LFCLKSEL_LFB_LFRCO (1<<2)
+#define CMU_LFCLKSEL_LFB_LFXO (2<<2)
+#define CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2 (3<<2)
+#define CMU_LFCLKSEL_LFB_MASK (0x3<<2)
+#define CMU_LFCLKSEL_LFA_DISABLED (0<<0)
+#define CMU_LFCLKSEL_LFA_LFRCO (1<<0)
+#define CMU_LFCLKSEL_LFA_LFXO (2<<0)
+#define CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 (3<<0)
+#define CMU_LFCLKSEL_LFA_MASK (0x3<<0)
+
+/** @} */
+
+/** Bit states for the CMU_STATUS register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.12 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_STATUS_bits CMU STATUS bits
+ * @{
+ */
+
+#define CMU_STATUS_CALBSY (1<<14)
+#define CMU_STATUS_LFXOSEL (1<<13)
+#define CMU_STATUS_LFRCOSEL (1<<12)
+#define CMU_STATUS_HFXOSEL (1<<11)
+#define CMU_STATUS_HFRCOSEL (1<<10)
+#define CMU_STATUS_LFXORDY (1<<9)
+#define CMU_STATUS_LFXOENS (1<<8)
+#define CMU_STATUS_LFRCORDY (1<<7)
+#define CMU_STATUS_LFRCOENS (1<<6)
+#define CMU_STATUS_AUXHFRCORDY (1<<5)
+#define CMU_STATUS_AUXHFRCOENS (1<<4)
+#define CMU_STATUS_HFXORDY (1<<3)
+#define CMU_STATUS_HFXOENS (1<<2)
+#define CMU_STATUS_HFRCORDY (1<<1)
+#define CMU_STATUS_HFRCOENS (1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_HFCORECLKEN0 register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.17 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_HFCORECLKEN0_bits CMU HFCORECLKEN0 bits
+ * @{
+ */
+
+#define CMU_HFCORECLKEN0_LE (1<<2)
+#define CMU_HFCORECLKEN0_DMA (1<<1)
+#define CMU_HFCORECLKEN0_AES (1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_HFPERCLKEN0 register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.18 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_HFPERCLKEN0_bits CMU HFPERCLKEN0 bits
+ * @{
+ */
+
+#define CMU_HFPERCLKEN0_I2C0 (1<<11)
+#define CMU_HFPERCLKEN0_DAC0 (1<<10)
+#define CMU_HFPERCLKEN0_ADC0 (1<<9)
+#define CMU_HFPERCLKEN0_PRS (1<<8)
+#define CMU_HFPERCLKEN0_VCMP (1<<7)
+#define CMU_HFPERCLKEN0_GPIO (1<<6)
+#define CMU_HFPERCLKEN0_TIMER1 (1<<5)
+#define CMU_HFPERCLKEN0_TIMER0 (1<<4)
+#define CMU_HFPERCLKEN0_USART1 (1<<3)
+#define CMU_HFPERCLKEN0_USART0 (1<<2)
+#define CMU_HFPERCLKEN0_ACMP1 (1<<1)
+#define CMU_HFPERCLKEN0_ACMP0 (1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_SYNCBUSY register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.19 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_SYNCBUSY_bits CMU SYNCBUSY bits
+ * @{
+ */
+
+#define CMU_SYNCBUSY_LFBPRESC0 (1<<6)
+#define CMU_SYNCBUSY_LFBCLKEN0 (1<<4)
+#define CMU_SYNCBUSY_LFAPRESC0 (1<<2)
+#define CMU_SYNCBUSY_LFACLKEN0 (1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_FREEZE register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.20 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_FREEZE_bits CMU FREEZE bits
+ * @{
+ */
+
+#define CMU_FREEZE_REGFREEZE_UPDATE (0<<0)
+#define CMU_FREEZE_REGFREEZE_FREEZE (1<<0)
+#define CMU_FREEZE_REGFREEZE_MASK (0x1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_LFACLKEN0 register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.21 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_LFACLKEN0_bits CMU LFACLKEN0 bits
+ * @{
+ */
+
+#define CMU_LFACLKEN0_LCD (1<<3)
+#define CMU_LFACLKEN0_LETIMER0 (1<<2)
+#define CMU_LFACLKEN0_RTC (1<<1)
+#define CMU_LFACLKEN0_LESENSE (1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_LFBCLKEN0 register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.22 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_LFBCLKEN0_bits CMU LFBCLKEN0 bits
+ * @{
+ */
+
+#define CMU_LFBCLKEN0_LEUART0 (1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_LFAPRESC0 register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.23 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_LFAPRESC0_bits CMU LFAPRESC0 bits
+ * @{
+ */
+
+#define CMU_LFAPRESC0_LCD_DIV16 (0<<12)
+#define CMU_LFAPRESC0_LCD_DIV32 (1<<12)
+#define CMU_LFAPRESC0_LCD_DIV64 (2<<12)
+#define CMU_LFAPRESC0_LCD_DIV128 (3<<12)
+#define CMU_LFAPRESC0_LCD_MASK (0x3<<12)
+#define CMU_LFAPRESC0_LETIMER0_DIV1 (0<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV2 (1<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV4 (2<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV8 (3<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV16 (4<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV32 (5<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV64 (6<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV128 (7<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV256 (8<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV512 (9<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV1024 (10<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV2048 (11<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV4096 (12<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV8192 (13<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV16384 (14<<8)
+#define CMU_LFAPRESC0_LETIMER0_DIV32768 (15<<8)
+#define CMU_LFAPRESC0_LETIMER0_MASK (0xf<<8)
+#define CMU_LFAPRESC0_RTC_DIV1 (0<<4)
+#define CMU_LFAPRESC0_RTC_DIV2 (1<<4)
+#define CMU_LFAPRESC0_RTC_DIV4 (2<<4)
+#define CMU_LFAPRESC0_RTC_DIV8 (3<<4)
+#define CMU_LFAPRESC0_RTC_DIV16 (4<<4)
+#define CMU_LFAPRESC0_RTC_DIV32 (5<<4)
+#define CMU_LFAPRESC0_RTC_DIV64 (6<<4)
+#define CMU_LFAPRESC0_RTC_DIV128 (7<<4)
+#define CMU_LFAPRESC0_RTC_DIV256 (8<<4)
+#define CMU_LFAPRESC0_RTC_DIV512 (9<<4)
+#define CMU_LFAPRESC0_RTC_DIV1024 (10<<4)
+#define CMU_LFAPRESC0_RTC_DIV2048 (11<<4)
+#define CMU_LFAPRESC0_RTC_DIV4096 (12<<4)
+#define CMU_LFAPRESC0_RTC_DIV8192 (13<<4)
+#define CMU_LFAPRESC0_RTC_DIV16384 (14<<4)
+#define CMU_LFAPRESC0_RTC_DIV32768 (15<<4)
+#define CMU_LFAPRESC0_RTC_MASK (0xf<<4)
+#define CMU_LFAPRESC0_LESENSE_DIV1 (0<<0)
+#define CMU_LFAPRESC0_LESENSE_DIV2 (1<<0)
+#define CMU_LFAPRESC0_LESENSE_DIV4 (2<<0)
+#define CMU_LFAPRESC0_LESENSE_DIV8 (3<<0)
+#define CMU_LFAPRESC0_LESENSE_MASK (0x3<<0)
+
+/** @} */
+
+/** Bit states for the CMU_LFBPRESC0 register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.24 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_LFBPRESC0_bits CMU LFBPRESC0 bits
+ * @{
+ */
+
+#define CMU_LFBPRESC0_LEUART0_DIV1 (0<<0)
+#define CMU_LFBPRESC0_LEUART0_DIV2 (1<<0)
+#define CMU_LFBPRESC0_LEUART0_DIV4 (2<<0)
+#define CMU_LFBPRESC0_LEUART0_DIV8 (3<<0)
+#define CMU_LFBPRESC0_LEUART0_MASK (0x3<<0)
+
+/** @} */
+
+/** Bit states for the CMU_PCNTCTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.25 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_PCNTCTRL_bits CMU PCNTCTRL bits
+ * @{
+ */
+
+#define CMU_PCNTCTRL_PCNT0CLKSEL_LFACLK (0<<1)
+#define CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0 (1<<1)
+#define CMU_PCNTCTRL_PCNT0CLKSEL_MASK (0x1<<1)
+#define CMU_PCNTCTRL_PCNT0CLKEN (1<<0)
+
+/** @} */
+
+/** Bit states for the CMU_LCDCTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.26 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_LCDCTRL_bits CMU LCDCTRL bits
+ * @{
+ */
+
+#define CMU_LCDCTRL_VBFDIV_DIV1 (0<<4)
+#define CMU_LCDCTRL_VBFDIV_DIV2 (1<<4)
+#define CMU_LCDCTRL_VBFDIV_DIV4 (2<<4)
+#define CMU_LCDCTRL_VBFDIV_DIV8 (3<<4)
+#define CMU_LCDCTRL_VBFDIV_DIV16 (4<<4)
+#define CMU_LCDCTRL_VBFDIV_DIV32 (5<<4)
+#define CMU_LCDCTRL_VBFDIV_DIV64 (6<<4)
+#define CMU_LCDCTRL_VBFDIV_DIV128 (7<<4)
+#define CMU_LCDCTRL_VBFDIV_MASK (0x7<<4)
+#define CMU_LCDCTRL_VBOOSTEN (1<<3)
+#define CMU_LCDCTRL_FDIV_MASK (0x7<<0)
+
+/** @} */
+
+/** Bit states for the CMU_ROUTE register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.27 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_ROUTE_bits CMU ROUTE bits
+ * @{
+ */
+
+#define CMU_ROUTE_LOCATION_LOC0 (0<<4)
+#define CMU_ROUTE_LOCATION_LOC1 (1<<4)
+#define CMU_ROUTE_LOCATION_MASK (0x7<<4)
+#define CMU_ROUTE_CLKOUT1PEN (1<<1)
+#define CMU_ROUTE_CLKOUT0PEN (1<<0)
+
+/** @} */
+
+/** Values for the CMU_LOCK register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 11.5.28 for definitions.
+ *
+ * @defgroup EFM32TG_CMU_LOCK_values CMU LOCK values
+ * @{
+ */
+
+#define CMU_LOCK_IS_UNLOCKED 0
+#define CMU_LOCK_IS_LOCKED 1
+#define CMU_LOCK_SET_LOCKED 0
+#define CMU_LOCK_SET_UNLOCKED 0x580E
+
+/** @} */
+
+/** Bit states for the CMU "I" group of registers (IF, IFS, IFC, IEN)
+ *
+ * These registers use this:
+ *
+ * <ul>
+ *
+ * <li>The CMU_IF register; see d0034_efm32tg_reference_manual.pdf section
+ * 11.5.13 for definitions.</li>
+ *
+ * <li>The CMU_IFS register; see d0034_efm32tg_reference_manual.pdf section
+ * 11.5.14 for definitions.</li>
+ *
+ * <li>The CMU_IFC register; see d0034_efm32tg_reference_manual.pdf section
+ * 11.5.15 for definitions.</li>
+ *
+ * <li>The CMU_IEN register; see d0034_efm32tg_reference_manual.pdf section
+ * 11.5.16 for definitions.</li>
+ *
+ * </ul>
+ *
+ * @defgroup EFM32TG_CMU_I_bits CMU I bits group
+ * @{
+ */
+
+#define CMU_I_CALOF (1<<6)
+#define CMU_I_CALRDY (1<<5)
+#define CMU_I_AUXHFRCORDY (1<<4)
+#define CMU_I_LFXORDY (1<<3)
+#define CMU_I_LFRCORDY (1<<2)
+#define CMU_I_HFXORDY (1<<1)
+#define CMU_I_HFRCORDY (1<<0)
+
+/** @} */
+
+/** @} */
+
+/** CMU convenience functions
+ *
+ * These functions assist in clock switching, and are intended to be safer to
+ * use than direct fiddling with registers. They try to be suitable for typical
+ * applications, and will invest some bytes of code in order to minimize power
+ * consumption.
+ *
+ * @todo Work on this module is stalled until I can figure out if there is a
+ * way to have a cmu_shutdown_unused function at all.
+ *
+ * @defgroup EFM32TG_CMU_convenience CMU convenience functions
+ * @{
+ */
+
+/** Disable all oscillators not currently in use.
+ *
+ * The implementation follows d0034_efm32tg_reference_manual.pdf figure 11.1.
+ * The clock out pin configurations are not depicted there, but described in
+ * section 11.3.4.
+ *
+ * @todo This function is ignorant of ongoing calibrations.
+ *
+ * @todo This doesn't work at all: Fields like HFCLKSEL are write-only.
+ * */
+static void cmu_shutdown_unused(void)
+{
+ /* Is HFXO needed? */
+ if (!(
+ (CMU_CMD & CMU_CMD_HFCLKSEL_MASK) == CMU_CMD_HFCLKSEL_HFXO ||
+ (
+ (CMU_CTRL & CMU_CTRL_CLKOUTSEL1_MASK) == CMU_CTRL_CLKOUTSEL1_HFXOQ &&
+ (CMU_ROUTE & CMU_ROUTE_CLKOUT1PEN)
+ ) || (
+ (CMU_CTRL & CMU_CTRL_CLKOUTSEL0_MASK) == CMU_CTRL_CLKOUTSEL0_HFXO &&
+ (CMU_ROUTE & CMU_ROUTE_CLKOUT0PEN)
+ )))
+ CMU_OSCENCMD = CMU_OSCENCMD_HFXODIS;
+
+ /* Is HFRCO neede? */
+ if (!(
+ (CMU_CMD & CMU_CMD_HFCLKSEL_MASK) == CMU_CMD_HFCLKSEL_HFRCO ||
+ (
+ (CMU_CTRL & CMU_CTRL_CLKOUTSEL1_MASK) == CMU_CTRL_CLKOUTSEL1_HFRCOQ &&
+ (CMU_ROUTE & CMU_ROUTE_CLKOUT1PEN)
+ ) || (
+ (CMU_CTRL & CMU_CTRL_CLKOUTSEL0_MASK) == CMU_CTRL_CLKOUTSEL0_HFRCO &&
+ (CMU_ROUTE & CMU_ROUTE_CLKOUT0PEN)
+ )))
+ {}
+// CMU_OSCENCMD = CMU_OSCENCMD_HFRCODIS;
+}
+
+/** Switch HFCLK to LFRC. This call is not only blocking, but even freezes
+ * everything depending on HFCLK until LFRC is stable. The procedure is
+ * sketched in d0034_efm32tg_reference_manual.pdf figure 11.2. */
+static void cmu_hfclk_switch_blocking(void)
+{
+ CMU_OSCENCMD = CMU_OSCENCMD_LFRCOEN;
+ CMU_CMD = CMU_CMD_HFCLKSEL_LFRCO;
+ CMU_OSCENCMD = CMU_OSCENCMD_HFRCODIS;
+}
+
+/** @} */
+
+/** @} */
+
+#endif
diff --git a/include/libopencm3/efm32/tinygecko/cmu.yaml b/include/libopencm3/efm32/tinygecko/cmu.yaml
new file mode 100644
index 0000000..7b83b7f
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/cmu.yaml
@@ -0,0 +1,458 @@
+copyright: "2012 chrysn <chrysn@fsfe.org>"
+license: lgpl-3+
+ingroup: EFM32TG
+shortdocname: EFM32TG_CMU
+shortname: CMU
+longname: Clock Management Unit
+baseref: d0034_efm32tg_reference_manual.pdf section 11
+registers_baserefext: ".4"
+templateregs:
+ - name: I
+ comment: Bits for the various CMU interrupt registers
+ fields:
+ - {name: CALOF, shift: 6}
+ - {name: CALRDY, shift: 5}
+ - {name: AUXHFRCORDY, shift: 4}
+ - {name: LFXORDY, shift: 3}
+ - {name: LFRCORDY, shift: 2}
+ - {name: HFXORDY, shift: 1}
+ - {name: HFRCORDY, shift: 0}
+registers:
+ - name: CTRL
+ offset: 0x000
+ definition_baserefext: ".5.1"
+ fields:
+ - name: DBGCLK
+ shift: 28
+ values:
+ - {name: AUXHFRCO, value: 0}
+ - {name: HFCLK, value: 1}
+ - name: CLKOUTSEL1
+ shift: 23
+ length: 3
+ values:
+ - {name: LFRCO, value: 0}
+ - {name: LFXO, value: 1}
+ - {name: HFCLK, value: 2}
+ - {name: LFXOQ, value: 3}
+ - {name: HFXOQ, value: 4}
+ - {name: LFRCOQ, value: 5}
+ - {name: HFRCOQ, value: 6}
+ - {name: AUXHFRCOQ, value: 7}
+ - name: CLKOUTSEL0
+ shift: 20
+ length: 3
+ values:
+ - {name: HFRCO, value: 0}
+ - {name: HFXO, value: 1}
+ - {name: HFCLK2, value: 2}
+ - {name: HFCLK4, value: 3}
+ - {name: HFCLK8, value: 4}
+ - {name: HFCLK16, value: 5}
+ - {name: ULFRCO, value: 6}
+ - {name: AUXHFRCO, value: 7}
+ - name: LFXOTIMEOUT
+ shift: 18
+ length: 2
+ values:
+ - {name: 8CYCLES, value: 0}
+ - {name: 1KCYCLES, value: 1}
+ - {name: 16KCYCLES, value: 2}
+ - {name: 32KCYCLES, value: 3}
+ - name: LFXOBUFCUR
+ shift: 17
+ - name: LXFOBOOST
+ shift: 13
+ values:
+ - {name: 70PCENT, value: 0}
+ - {name: 100PCENT, value: 1}
+ - name: LFXOMODE
+ shift: 11
+ length: 2
+ values:
+ - {name: XTAL, value: 0}
+ - {name: BUFEXTCLK, value: 1}
+ - {name: DIGEXTCLK, value: 2}
+ - name: HFXOTIMEOUT
+ shift: 9
+ length: 2
+ values:
+ - {name: 8CYCLES, value: 0}
+ - {name: 256CYCLES, value: 1}
+ - {name: 1KCYCLES, value: 2}
+ - {name: 16KCYCLES, value: 3}
+ - name: HFXOGLITCHDETEN
+ shift: 7
+ - name: HFXOBUFCUR
+ shift: 5
+ length: 2
+ type: undocumented
+ - name: HFXOBOOST
+ shift: 2
+ length: 2
+ values:
+ - {name: 50PCENT, value: 0}
+ - {name: 70PCENT, value: 1}
+ - {name: 80PCENT, value: 2}
+ - {name: 100PCENT, value: 3}
+ - name: HFXOMODE
+ shift: 0
+ length: 2
+ values:
+ - {name: XTAL, value: 0}
+ - {name: BUFEXTCLK, value: 1}
+ - {name: DIGEXTCLK, value: 2}
+ - name: HFCORECLKDIV
+ offset: 0x004
+ definition_baserefext: ".5.2"
+ values: &HFCORECLKDIV_values
+ - {value: 0, name: HFCLK}
+ - {value: 1, name: HFCLK2}
+ - {value: 2, name: HFCLK4}
+ - {value: 3, name: HFCLK8}
+ - {value: 4, name: HFCLK16}
+ - {value: 5, name: HFCLK32}
+ - {value: 6, name: HFCLK64}
+ - {value: 7, name: HFCLK128}
+ - {value: 8, name: HFCLK256}
+ - {value: 9, name: HFCLK512}
+ - name: HFPERCLKDIV
+ offset: 0x008
+ definition_baserefext: ".5.3"
+ fields:
+ - name: HFPERCLKEN
+ shift: 8
+ - name: HFPERCLKDIV
+ shift: 0
+ length: 3
+ # not using generically named values here due to different register structure
+ values: *HFCORECLKDIV_values
+ - name: HFRCOCTRL
+ offset: 0x00c
+ definition_baserefext: ".5.4"
+ fields:
+ - name: SUDELAY
+ shift: 12
+ length: 5
+ type: undocumented
+ - name: BAND
+ shift: 8
+ length: 3
+ values:
+ - {value: 0, name: 1MHZ}
+ - {value: 1, name: 7MHZ}
+ - {value: 2, name: 11MHZ}
+ - {value: 3, name: 14MHZ}
+ - {value: 4, name: 21MHZ}
+ - {value: 5, name: 28MHZ}
+ - name: TUNING
+ shift: 0
+ length: 8
+ type: uint
+ - name: LFRCOCTRL
+ offset: 0x010
+ definition_baserefext: ".5.5"
+ length: 7
+ type: uint
+ - name: AUXHFRCOCTRL
+ offset: 0x014
+ definition_baserefext: ".5.6"
+ fields:
+ - name: BAND
+ shift: 8
+ length: 3
+ values:
+ - {value: 0, name: 14MHZ}
+ - {value: 1, name: 11MHZ}
+ - {value: 2, name: 7MHZ}
+ - {value: 3, name: 1MHZ}
+ - {value: 6, name: 28MHZ}
+ - {value: 7, name: 21MHZ}
+ - name: TUNING
+ shift: 0
+ length: 8
+ type: uint
+ - name: CALCTRL
+ offset: 0x018
+ definition_baserefext: ".6.7"
+ fields:
+ - name: CONT
+ shift: 6
+ - name: DOWNSEL
+ shift: 3
+ length: 3
+ values:
+ - {value: 0, name: HFCLK}
+ - {value: 1, name: HFXO}
+ - {value: 2, name: LFXO}
+ - {value: 3, name: HFRCO}
+ - {value: 4, name: LFRCO}
+ - {value: 5, name: AUXHFRCO}
+ - name: UPSEL
+ shift: 0
+ length: 3
+ values:
+ - {value: 0, name: HFXO}
+ - {value: 1, name: LFXO}
+ - {value: 2, name: HFRCO}
+ - {value: 3, name: LFRCO}
+ - {value: 4, name: AUXHFRCO}
+ - name: CALCNT
+ offset: 0x01c
+ definition_baserefext: ".5.8"
+ length: 19
+ type: uint
+ - name: OSCENCMD
+ offset: 0x020
+ definition_baserefext: ".5.9"
+ fields:
+ - {name: LFXODIS, shift: 9}
+ - {name: LFXOEN, shift: 8}
+ - {name: LFRCODIS, shift: 7}
+ - {name: LFRCOEN, shift: 6}
+ - {name: AUXHFRCODIS, shift: 5}
+ - {name: AUXHFRCOEN, shift: 4}
+ - {name: HFXODIS, shift: 3}
+ - {name: HFXOEN, shift: 2}
+ - {name: HFRCODIS, shift: 1}
+ - {name: HFRCOEN, shift: 0}
+ - name: CMD
+ offset: 0x024
+ definition_baserefext: ".5.10"
+ fields:
+ - name: CALSTOP
+ shift: 4
+ - name: CALSTART
+ shift: 3
+ - name: HFCLKSEL
+ shift: 0
+ length: 3
+ values:
+ - {value: 1, name: HFRCO}
+ - {value: 2, name: HFXO}
+ - {value: 3, name: LFRCO}
+ - {value: 4, name: LFXO}
+ - name: LFCLKSEL
+ offset: 0x028
+ definition_baserefext: ".5.11"
+ fields:
+ - name: LFBE
+ shift: 20
+ values: &LFCLKSEL_LFBE
+ - {value: 0, name: DISABLED}
+ - {value: 1, name: ULFRCO}
+ - name: LFAE
+ shift: 16
+ values: *LFCLKSEL_LFBE
+ - name: LFB
+ shift: 2
+ length: 2
+ values: &LFCLKSEL_LFB
+ - {value: 0, name: DISABLED}
+ - {value: 1, name: LFRCO}
+ - {value: 2, name: LFXO}
+ - {value: 3, name: HFCORECLKLEDIV2}
+ - name: LFA
+ shift: 0
+ length: 2
+ values: *LFCLKSEL_LFB
+ - name: STATUS
+ offset: 0x02c
+ definition_baserefext: ".5.12"
+ fields:
+ - {name: CALBSY, shift: 14}
+ - {name: LFXOSEL, shift: 13}
+ - {name: LFRCOSEL, shift: 12}
+ - {name: HFXOSEL, shift: 11}
+ - {name: HFRCOSEL, shift: 10}
+ - {name: LFXORDY, shift: 9}
+ - {name: LFXOENS, shift: 8}
+ - {name: LFRCORDY, shift: 7}
+ - {name: LFRCOENS, shift: 6}
+ - {name: AUXHFRCORDY, shift: 5}
+ - {name: AUXHFRCOENS, shift: 4}
+ - {name: HFXORDY, shift: 3}
+ - {name: HFXOENS, shift: 2}
+ - {name: HFRCORDY, shift: 1}
+ - {name: HFRCOENS, shift: 0}
+ - name: IF
+ offset: 0x030
+ definition_baserefext: ".5.13"
+ fields: I
+ - name: IFS
+ offset: 0x034
+ definition_baserefext: ".5.14"
+ fields: I
+ - name: IFC
+ offset: 0x038
+ definition_baserefext: ".5.15"
+ fields: I
+ - name: IEN
+ offset: 0x03c
+ definition_baserefext: ".5.16"
+ fields: I
+ - name: HFCORECLKEN0
+ offset: 0x040
+ definition_baserefext: ".5.17"
+ fields:
+ - {name: LE, shift: 2}
+ - {name: DMA, shift: 1}
+ - {name: AES, shift: 0}
+ - name: HFPERCLKEN0
+ offset: 0x044
+ definition_baserefext: ".5.18"
+ fields:
+ - {name: I2C0, shift: 11}
+ - {name: DAC0, shift: 10}
+ - {name: ADC0, shift: 9}
+ - {name: PRS, shift: 8}
+ - {name: VCMP, shift: 7}
+ - {name: GPIO, shift: 6}
+ - {name: TIMER1, shift: 5}
+ - {name: TIMER0, shift: 4}
+ - {name: USART1, shift: 3}
+ - {name: USART0, shift: 2}
+ - {name: ACMP1, shift: 1}
+ - {name: ACMP0, shift: 0}
+ - name: SYNCBUSY
+ offset: 0x050
+ definition_baserefext: ".5.19"
+ fields:
+ - {name: LFBPRESC0, shift: 6}
+ - {name: LFBCLKEN0, shift: 4}
+ - {name: LFAPRESC0, shift: 2}
+ - {name: LFACLKEN0, shift: 0}
+ - name: FREEZE
+ offset: 0x054
+ definition_baserefext: ".5.20"
+ fields:
+ - name: REGFREEZE
+ shift: 0
+ values:
+ - {value: 0, name: UPDATE}
+ - {value: 1, name: FREEZE}
+ - name: LFACLKEN0
+ offset: 0x058
+ definition_baserefext: ".5.21"
+ fields:
+ - {name: LCD, shift: 3}
+ - {name: LETIMER0, shift: 2}
+ - {name: RTC, shift: 1}
+ - {name: LESENSE, shift: 0}
+ - name: LFBCLKEN0
+ offset: 0x060
+ definition_baserefext: ".5.22"
+ fields:
+ - {name: LEUART0, shift: 0}
+ - name: LFAPRESC0
+ offset: 0x068
+ definition_baserefext: ".5.23"
+ fields:
+ - name: LCD
+ shift: 12
+ length: 2
+ values:
+ - {value: 0, name: DIV16}
+ - {value: 1, name: DIV32}
+ - {value: 2, name: DIV64}
+ - {value: 3, name: DIV128}
+ - name: LETIMER0
+ shift: 8
+ length: 4
+ values: &LFAPRESC0_LETIMER0_values
+ - {value: 0, name: DIV1}
+ - {value: 1, name: DIV2}
+ - {value: 2, name: DIV4}
+ - {value: 3, name: DIV8}
+ - {value: 4, name: DIV16}
+ - {value: 5, name: DIV32}
+ - {value: 6, name: DIV64}
+ - {value: 7, name: DIV128}
+ - {value: 8, name: DIV256}
+ - {value: 9, name: DIV512}
+ - {value: 10, name: DIV1024}
+ - {value: 11, name: DIV2048}
+ - {value: 12, name: DIV4096}
+ - {value: 13, name: DIV8192}
+ - {value: 14, name: DIV16384}
+ - {value: 15, name: DIV32768}
+ - name: RTC
+ shift: 4
+ length: 4
+ values: *LFAPRESC0_LETIMER0_values
+ - name: LESENSE
+ shift: 0
+ length: 2
+ values:
+ - {value: 0, name: DIV1}
+ - {value: 1, name: DIV2}
+ - {value: 2, name: DIV4}
+ - {value: 3, name: DIV8}
+ - name: LFBPRESC0
+ offset: 0x070
+ definition_baserefext: ".5.24"
+ fields:
+ - name: LEUART0
+ shift: 0
+ length: 2
+ values:
+ - {value: 0, name: DIV1}
+ - {value: 1, name: DIV2}
+ - {value: 2, name: DIV4}
+ - {value: 3, name: DIV8}
+ - name: PCNTCTRL
+ offset: 0x078
+ definition_baserefext: ".5.25"
+ fields:
+ - name: PCNT0CLKSEL
+ shift: 1
+ values:
+ - {value: 0, name: LFACLK}
+ - {value: 1, name: PCNT0S0}
+ - name: PCNT0CLKEN
+ shift: 0
+ - name: LCDCTRL
+ offset: 0x07c
+ definition_baserefext: ".5.26"
+ fields:
+ - name: VBFDIV
+ shift: 4
+ length: 3
+ values:
+ - {value: 0, name: DIV1}
+ - {value: 1, name: DIV2}
+ - {value: 2, name: DIV4}
+ - {value: 3, name: DIV8}
+ - {value: 4, name: DIV16}
+ - {value: 5, name: DIV32}
+ - {value: 6, name: DIV64}
+ - {value: 7, name: DIV128}
+ - name: VBOOSTEN
+ shift: 3
+ - name: FDIV
+ shift: 0
+ length: 3
+ type: uint
+ - name: ROUTE
+ offset: 0x080
+ definition_baserefext: ".5.27"
+ fields:
+ - name: LOCATION
+ shift: 4
+ length: 3
+ values:
+ - {value: 0, name: LOC0}
+ - {value: 1, name: LOC1}
+ - name: CLKOUT1PEN
+ shift: 1
+ - name: CLKOUT0PEN
+ shift: 0
+ - name: LOCK
+ offset: 0x084
+ definition_baserefext: ".5.28"
+ length: 16
+ values:
+ - {name: IS_UNLOCKED, value: 0}
+ - {name: IS_LOCKED, value: 1}
+ - {name: SET_LOCKED, value: 0}
+ - {name: SET_UNLOCKED, value: "0x580E"}
diff --git a/include/libopencm3/efm32/tinygecko/devicerevision.h b/include/libopencm3/efm32/tinygecko/devicerevision.h
new file mode 100644
index 0000000..45da408
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/devicerevision.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* 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 */
+
+#ifndef LIBOPENCM3_EFM32_TINYGECKO_DEVICEREVISION_H
+#define LIBOPENCM3_EFM32_TINYGECKO_DEVICEREVISION_H
+
+#include <libopencm3/cm3/common.h>
+
+#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<<DEVICEREVISION_REVISION_LENGTH)<<DEVICEREVISION_REVISION_SHIFT) /* 0x000000f0, bits 7:4 */
+
+#define DEVICEREVISION_REVISION_A 0x00
+
+/* Read the device's hardcoded Revision. Return values can be compared against
+ * the DEVICEREVISION_REVISION_A constant, the only value given in the current
+ * specification. */
+extern u8 devicerevision_revision_get(void);
+
+#endif
diff --git a/include/libopencm3/efm32/tinygecko/emu.convenienceheaders b/include/libopencm3/efm32/tinygecko/emu.convenienceheaders
new file mode 100644
index 0000000..7d5893d
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/emu.convenienceheaders
@@ -0,0 +1,18 @@
+/** EMU convenience functions
+ *
+ * These functions can be used to send the chip to low energy modes.
+ *
+ * @todo Implement other sleep modes than EM1. Implement WFI vs WFE waits.
+ *
+ * @defgroup EFM32TG_EMU_convenience EMU convenience functions
+ * @{
+ */
+
+/** Put the system into EM1 low energy mode. */
+static void emu_sleep_em1(void)
+{
+ /* FIXME: set SLEEPDEEP to 0 */
+ __asm__("wfi");
+}
+
+/** @} */
diff --git a/include/libopencm3/efm32/tinygecko/emu.h b/include/libopencm3/efm32/tinygecko/emu.h
new file mode 100644
index 0000000..9a043cb
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/emu.h
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * @see EFM32TG_EMU
+ */
+
+/** Definitions for the EMU subsystem (Energy Management Unit).
+ *
+ * This corresponds to the description in d0034_efm32tg_reference_manual.pdf
+ * section 10.
+ *
+ * @ingroup EFM32TG
+ * @defgroup EFM32TG_EMU EMU (Energy Management Unit)
+ * @{
+ */
+
+#ifndef LIBOPENCM3_EFM32_TINYGECKO_EMU_H
+#define LIBOPENCM3_EFM32_TINYGECKO_EMU_H
+
+#include <libopencm3/cm3/common.h>
+#include <libopencm3/efm32/memorymap.h>
+
+/** Register definitions and register value definitions for the EMU subsystem
+ *
+ * @defgroup EFM32TG_EMU_regsandvals EMU registers and values
+ * @{
+ */
+
+/** These definitions reflect d0034_efm32tg_reference_manual.pdf section 10.4
+ *
+ * @defgroup EFM32TG_EMU_registers EMU registers
+ * @{
+ */
+
+#define EMU_CTRL MMIO32(EMU_BASE + 0x000) /**< @see EFM32TG_EMU_CTRL_bits */
+#define EMU_LOCK MMIO32(EMU_BASE + 0x008) /**< @see EFM32TG_EMU_LOCK_values */
+#define EMU_AUXCTRL MMIO32(EMU_BASE + 0x024) /**< @see EFM32TG_EMU_AUXCTRL_bits */
+
+/** @} */
+
+/** Bit states for the EMU_CTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 10.5.1 for definitions, and
+ * 10.3.2 for details (especially on why EM4CTRL_TWO and _THREE are defined).
+ *
+ * @defgroup EFM32TG_EMU_CTRL_bits EMU CTRL bits
+ * @{
+ */
+
+#define EMU_CTRL_EM4CTRL_TWO (2<<2)
+#define EMU_CTRL_EM4CTRL_THREE (3<<2)
+#define EMU_CTRL_EM4CTRL_MASK (0x3<<2)
+#define EMU_CTRL_EM2BLOCK (1<<1) /**< When this bit is set, no mode lower than EM1 will be entered */
+#define EMU_CTRL_EMVREG (1<<0) /**< When this bit is set, the voltage regulator will stay on in modes lower than EM1 */
+
+/** @} */
+
+/** Values for the EMU_LOCK register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 10.5.2 for definitions. There
+ * seems not to be another mention of it.
+ *
+ * @defgroup EFM32TG_EMU_LOCK_values EMU LOCK values
+ * @{
+ */
+
+#define EMU_LOCK_IS_UNLOCKED 0 /**< When the LOCK register reads as this value, it is open */
+#define EMU_LOCK_IS_LOCKED 1 /**< When the LOCK register reads as this value, it is locked */
+#define EMU_LOCK_SET_LOCKED 0 /**< Write this to the LOCK register to lock the EMU */
+#define EMU_LOCK_SET_UNLOCKED 0xade8 /**< Write this to the LOCK register to unlock the EMU */
+
+/** @} */
+
+/** Bit states for the EMU_AUXCTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 10.5.3 for definitions, and
+ * 9.5.3 for details.
+ *
+ * @defgroup EFM32TG_EMU_AUXCTRL_bits EMU AUXCTRL bits
+ * @{
+ */
+
+#define EMU_AUXCTRL_HRCCLR (1<<0)
+
+/** @} */
+
+/** @} */
+
+/** EMU convenience functions
+ *
+ * These functions can be used to send the chip to low energy modes.
+ *
+ * @todo Implement other sleep modes than EM1. Implement WFI vs WFE waits.
+ *
+ * @defgroup EFM32TG_EMU_convenience EMU convenience functions
+ * @{
+ */
+
+/** Put the system into EM1 low energy mode. */
+static void emu_sleep_em1(void)
+{
+ /* FIXME: set SLEEPDEEP to 0 */
+ __asm__("wfi");
+}
+
+/** @} */
+
+/** @} */
+
+#endif
diff --git a/include/libopencm3/efm32/tinygecko/emu.yaml b/include/libopencm3/efm32/tinygecko/emu.yaml
new file mode 100644
index 0000000..4e0b30e
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/emu.yaml
@@ -0,0 +1,50 @@
+copyright: "2012 chrysn <chrysn@fsfe.org>"
+license: lgpl-3+
+ingroup: EFM32TG
+shortdocname: EFM32TG_EMU
+shortname: EMU
+longname: Energy Management Unit
+baseref: d0034_efm32tg_reference_manual.pdf section 10
+registers_baserefext: ".4"
+registers:
+ - name: CTRL
+ definition_baserefext: .5.1
+ details: ", and 10.3.2 for details (especially on why EM4CTRL_TWO and _THREE are defined)."
+ offset: 0x000
+ fields:
+ - name: EM4CTRL
+ shift: 2
+ length: 2
+ values:
+ - {name: TWO, value: 2}
+ - {name: THREE, value: 3}
+ - name: EM2BLOCK
+ shift: 1
+ doc: When this bit is set, no mode lower than EM1 will be entered
+ - name: EMVREG
+ shift: 0
+ doc: When this bit is set, the voltage regulator will stay on in modes lower than EM1
+ - name: LOCK
+ definition_baserefext: .5.2
+ details: ". There seems not to be another mention of it."
+ offset: 0x008
+ values:
+ - name: IS_UNLOCKED
+ value: 0
+ doc: When the LOCK register reads as this value, it is open
+ - name: IS_LOCKED
+ value: 1
+ doc: When the LOCK register reads as this value, it is locked
+ - name: SET_LOCKED
+ value: 0
+ doc: Write this to the LOCK register to lock the EMU
+ - name: SET_UNLOCKED
+ value: "0xade8"
+ doc: Write this to the LOCK register to unlock the EMU
+ - name: AUXCTRL
+ definition_baserefext: .5.3
+ details: ", and 9.5.3 for details."
+ offset: 0x024
+ fields:
+ - name: HRCCLR
+ shift: 0
diff --git a/include/libopencm3/efm32/tinygecko/generate-license.yaml b/include/libopencm3/efm32/tinygecko/generate-license.yaml
new file mode 100644
index 0000000..baeef88
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/generate-license.yaml
@@ -0,0 +1,19 @@
+"lgpl-3+": |
+ /*
+ * This file is part of the {projectname} project.
+ *
+ * Copyright (C) {copyright}
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
diff --git a/include/libopencm3/efm32/tinygecko/generate.py b/include/libopencm3/efm32/tinygecko/generate.py
new file mode 100644
index 0000000..7f426a4
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/generate.py
@@ -0,0 +1,176 @@
+#!/usr/bin/env python
+
+import yaml
+import logging
+import textwrap
+
+def commentblock(*textblocks, **formatargs):
+ ret = []
+ nowrapcommands = set("@defgroup")
+ ret.extend(textwrap.wrap(textblocks[0].format(**formatargs), 80, initial_indent="/** ", subsequent_indent=" * "))
+ last_block_was_at = textblocks[0].startswith('@')
+ for b in textblocks[1:]:
+ formatted = b.format(**formatargs)
+
+ if not (last_block_was_at and b.startswith('@')):
+ ret.append(" *")
+ if any(b.startswith(c) for c in nowrapcommands):
+ ret.append(" * " + formatted)
+ else:
+ ret.extend(textwrap.wrap(formatted, 80, initial_indent=" * ", subsequent_indent=" * "))
+ last_block_was_at = b.startswith('@')
+ return "\n".join(ret) + "\n */\n"
+
+def yaml2h(filenamebase):
+ headername = "%s.h"%filenamebase
+ yamlname = "%s.yaml"%filenamebase
+ conveniencename = "%s.convenienceheaders"%filenamebase
+
+ logging.info("Generating %s from %s", headername, yamlname)
+
+ data = yaml.load(open(yamlname))
+ # some defaults
+ data.setdefault("projectname", "libopencm3")
+ data.setdefault("includeguard", "LIBOPENCM3_EFM32_TINYGECKO_%s_H"%data['shortname'])
+
+ with open(headername, 'w') as outfile:
+ def wc(*args, **kwargs): # wrap "outfile" and "data" (as default) arguments -- i'm a lazy typer
+ final_kwargs = data.copy()
+ final_kwargs.update(kwargs)
+ outfile.write(commentblock(*args, **final_kwargs))
+ def wc_close():
+ outfile.write("/** @} */\n")
+ def nl(): outfile.write("\n")
+ def define(key, value, comment=None):
+ outfile.write("#define ")
+ outfile.write(key)
+ outfile.write(" "*max(24-len(key), 1))
+ outfile.write(str(value))
+ if comment is not None:
+ outfile.write(" /**< %s */"%comment)
+ nl()
+
+ outfile.write(licensedata[data['license']].format(**data))
+ nl()
+ wc("@file", "@see {shortdocname}")
+ nl()
+ wc("Definitions for the {shortname} subsystem ({longname}).", "This corresponds to the description in {baseref}.", "@ingroup {ingroup}", "@defgroup {shortdocname} {shortname} ({longname})", "@{{")
+ nl()
+ outfile.write("#ifndef {includeguard}\n#define {includeguard}\n".format(**data))
+ nl()
+ outfile.write("#include <libopencm3/cm3/common.h>\n#include <libopencm3/efm32/memorymap.h>\n")
+ nl()
+ wc("Register definitions and register value definitions for the {shortname} subsystem", "@defgroup {shortdocname}_regsandvals {shortname} registers and values", "@{{")
+ nl()
+
+ regs = data['registers']
+
+ for template in data.get('templateregs', []):
+ template['is_template'] = []
+ regs.append(template)
+
+ regs_dict = dict((x['name'], x) for x in regs) # for easier access. they've got to be a list in yaml to preserve order
+
+ wc("These definitions reflect {baseref}{registers_baserefext}", "@defgroup {shortdocname}_registers {shortname} registers", "@{{")
+ nl()
+
+ for regdata in regs:
+ has_bits = "fields" in regdata
+ has_values = "values" in regdata
+ is_template = "is_template" in regdata
+ if is_template:
+ # this isn't a real register, just a template
+ continue
+ secondcomponent_name = regdata['name']
+ if (has_bits and isinstance(regdata['fields'], str)) or (has_values and isinstance(regdata['values'], str)):
+ # uses a template
+ secondcomponent_name = regdata['fields'] if has_bits else regdata['values']
+ regs_dict[secondcomponent_name]['is_template'].append(regdata['name'])
+
+ define("%s_%s"%(data['shortname'], regdata['name']), "MMIO32(%s_BASE + %#.003x)"%(data['shortname'], regdata['offset']), "@see %s_%s_%s"%(data['shortdocname'], secondcomponent_name, 'values' if 'values' in regdata else 'bits') if has_bits or has_values else None)
+ nl()
+ wc_close() # close register definitions
+ nl()
+
+ for regdata in regs:
+ has_bits = "fields" in regdata
+ has_values = "values" in regdata
+ is_template = "is_template" in regdata
+ if not has_bits and not has_values:
+ continue
+
+ if (has_bits and isinstance(regdata['fields'], str)) or (has_values and isinstance(regdata['values'], str)):
+ # uses a template, doesn't need own section
+ continue
+
+ commentlines = []
+ if is_template:
+ commentlines.append("%s for the {shortname} \"{name}\" group of registers (%s)"%("Bit states" if has_bits else "Values", ", ".join(regdata['is_template'])))
+ assert len(regdata['is_template']) > 0, "What should I talk about when nobody uses this template?"
+ if 'override_backref' in regdata:
+ commentlines.append(regdata['override_backref'])
+ else:
+ commentlines.append("These registers use this:")
+ commentlines.append("<ul>") # FIXME: once we're using markdown 1.8, this can be changed to markdown
+ for user in regdata['is_template']:
+ userdata = regs_dict[user]
+ # FIXME: this is an ugly hack around this being in a single wc() line which doesn't take per-line contexts
+ mergeddata = data.copy()
+ mergeddata.update(userdata)
+ commentlines.append(("<li>The {shortname}_{name} register; see {baseref}{definition_baserefext} for definitions"+regdata.get("details", "."+"</li>")).format(**mergeddata))
+ commentlines.append("</ul>")
+ commentlines.append('@defgroup {shortdocname}_{name}_%s {shortname} {name} %s'%(('bits' if has_bits else 'values', 'bits group' if has_bits else 'values group')))
+ else:
+ commentlines.append("%s for the {shortname}_{name} register"%("Bit states" if has_bits else "Values"))
+ commentlines.append("See {baseref}{definition_baserefext} for definitions"+regdata.get("details", "."))
+ commentlines.append('@defgroup {shortdocname}_{name}_%s {shortname} {name} %s'%(('bits' if has_bits else 'values',)*2))
+ commentlines.append('@{{')
+ wc(*commentlines, **regdata)
+ nl()
+
+ if has_bits:
+ for field in regdata['fields']:
+ #shiftdefine = "_%s_%s_%s_shift"%(shortname, regdata['name'], field['name'])
+ #define(shiftdefine, field['shift'])
+
+ # there is one condition under which field's doc would get shown; show it immediately otherwise
+ if 'doc' in field and not ("values" not in field and field.get("length", 1) == 1):
+ wc(field['doc'])
+
+ if "values" in field:
+ for value in field.get("values"):
+ define("%s_%s_%s_%s"%(data['shortname'], regdata['name'], field['name'], value['name']), value['value'] if "mask" in field else "(%s<<%s)"%(value['value'], field['shift']), value.get('doc', None))
+ else:
+ if field.get('length', 1) == 1:
+ define("%s_%s_%s"%(data['shortname'], regdata['name'], field['name']), "(1<<%s)"%field['shift'], field.get('doc', None))
+ else:
+ # FIXME: this should require the 'type' parameter to be set on this field
+ pass
+
+ if "values" in field or field.get("length", 1) != 1:
+ if "mask" in field:
+ mask = field['mask']
+ else:
+ mask = "(%#x<<%s)"%(~(~0<<field.get('length', 1)), field['shift'])
+ define("%s_%s_%s_MASK"%(data['shortname'], regdata['name'], field['name']), mask)
+ else:
+ for value in regdata['values']:
+ define("%s_%s_%s"%(data['shortname'], regdata['name'], value['name']), value['value'], value.get('doc', None))
+
+ nl()
+ wc_close()
+ nl()
+ wc_close() # close registers and values
+ nl()
+
+ outfile.write(open(conveniencename).read())
+
+ nl()
+ wc_close() # close convenience
+ nl()
+ outfile.write("#endif\n")
+
+if __name__ == "__main__":
+ licensedata = yaml.load(open("generate-license.yaml"))
+ for basename in yaml.load(open('generate.yaml')):
+ yaml2h(basename)
diff --git a/include/libopencm3/efm32/tinygecko/generate.yaml b/include/libopencm3/efm32/tinygecko/generate.yaml
new file mode 100644
index 0000000..b7ade5d
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/generate.yaml
@@ -0,0 +1,3 @@
+- emu
+- cmu
+- lcd
diff --git a/include/libopencm3/efm32/tinygecko/gpio.h b/include/libopencm3/efm32/tinygecko/gpio.h
new file mode 100644
index 0000000..2c65d0d
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/gpio.h
@@ -0,0 +1,498 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * @see EFM32TG_GPIO
+ */
+
+/** Definitions for the GPIO subsystem (General Purpose Input Output).
+ *
+ * This corresponds to the description in d0034_efm32tg_reference_manual.pdf
+ * section 28.
+ *
+ * @ingroup EFM32TG
+ * @defgroup EFM32TG_GPIO GPIO (General Purpose Input Output)
+ * @{
+ */
+
+#ifndef LIBOPENCM3_EFM32_TINYGECKO_GPIO_H
+#define LIBOPENCM3_EFM32_TINYGECKO_GPIO_H
+
+#include <libopencm3/cm3/common.h>
+#include <libopencm3/efm32/memorymap.h>
+
+/** Register definitions and register value definitions for the GPIO subsystem
+ *
+ * @defgroup EFM32TG_GPIO_regsandvals GPIO registers and values
+ * @{
+ */
+
+/** 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 EFM32TG_GPIO_registers GPIO registers
+ * @{
+ */
+#define GPIO_Px_CTRL(port) MMIO32(port + 0x000) /**< @see EFM32TG_GPIO_Px_CTRL_bits */
+#define GPIO_Px_MODEL(port) MMIO32(port + 0x004) /**< @see EFM32TG_GPIO_MODE_values */
+#define GPIO_Px_MODEH(port) MMIO32(port + 0x008) /**< @see EFM32TG_GPIO_MODE_values */
+#define GPIO_Px_DOUT(port) MMIO32(port + 0x00C) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_Px_DOUTSET(port) MMIO32(port + 0x010) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_Px_DOUTCLR(port) MMIO32(port + 0x014) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_Px_DOUTTGL(port) MMIO32(port + 0x018) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_Px_DIN(port) MMIO32(port + 0x01C) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_Px_PINLOCKN(port) MMIO32(port + 0x020) /**< @see EFM32TG_GPIO_pinnumberbits */
+
+#define GPIO_PA (GPIO_BASE + 0x000)
+#define GPIO_PA_CTRL GPIO_Px_CTRL(GPIO_PA)
+#define GPIO_PA_MODEL GPIO_Px_MODEL(GPIO_PA)
+#define GPIO_PA_MODEH GPIO_Px_MODEH(GPIO_PA)
+#define GPIO_PA_DOUT GPIO_Px_DOUT(GPIO_PA)
+#define GPIO_PA_DOUTSET GPIO_Px_DOUTSET(GPIO_PA)
+#define GPIO_PA_DOUTCLR GPIO_Px_DOUTCLR(GPIO_PA)
+#define GPIO_PA_DOUTTGL GPIO_Px_DOUTTGL(GPIO_PA)
+#define GPIO_PA_DIN GPIO_Px_DIN(GPIO_PA)
+#define GPIO_PA_PINLOCKN GPIO_Px_PINLOCKN(GPIO_PA)
+
+#define GPIO_PB (GPIO_BASE + 0x024)
+#define GPIO_PB_CTRL GPIO_Px_CTRL(GPIO_PB)
+#define GPIO_PB_MODEL GPIO_Px_MODEL(GPIO_PB)
+#define GPIO_PB_MODEH GPIO_Px_MODEH(GPIO_PB)
+#define GPIO_PB_DOUT GPIO_Px_DOUT(GPIO_PB)
+#define GPIO_PB_DOUTSET GPIO_Px_DOUTSET(GPIO_PB)
+#define GPIO_PB_DOUTCLR GPIO_Px_DOUTCLR(GPIO_PB)
+#define GPIO_PB_DOUTTGL GPIO_Px_DOUTTGL(GPIO_PB)
+#define GPIO_PB_DIN GPIO_Px_DIN(GPIO_PB)
+#define GPIO_PB_PINLOCKN GPIO_Px_PINLOCKN(GPIO_PB)
+
+#define GPIO_PC (GPIO_BASE + 0x048)
+#define GPIO_PC_CTRL GPIO_Px_CTRL(GPIO_PC)
+#define GPIO_PC_MODEL GPIO_Px_MODEL(GPIO_PC)
+#define GPIO_PC_MODEH GPIO_Px_MODEH(GPIO_PC)
+#define GPIO_PC_DOUT GPIO_Px_DOUT(GPIO_PC)
+#define GPIO_PC_DOUTSET GPIO_Px_DOUTSET(GPIO_PC)
+#define GPIO_PC_DOUTCLR GPIO_Px_DOUTCLR(GPIO_PC)
+#define GPIO_PC_DOUTTGL GPIO_Px_DOUTTGL(GPIO_PC)
+#define GPIO_PC_DIN GPIO_Px_DIN(GPIO_PC)
+#define GPIO_PC_PINLOCKN GPIO_Px_PINLOCKN(GPIO_PC)
+
+#define GPIO_PD (GPIO_BASE + 0x06C)
+#define GPIO_PD_CTRL GPIO_Px_CTRL(GPIO_PD)
+#define GPIO_PD_MODEL GPIO_Px_MODEL(GPIO_PD)
+#define GPIO_PD_MODEH GPIO_Px_MODEH(GPIO_PD)
+#define GPIO_PD_DOUT GPIO_Px_DOUT(GPIO_PD)
+#define GPIO_PD_DOUTSET GPIO_Px_DOUTSET(GPIO_PD)
+#define GPIO_PD_DOUTCLR GPIO_Px_DOUTCLR(GPIO_PD)
+#define GPIO_PD_DOUTTGL GPIO_Px_DOUTTGL(GPIO_PD)
+#define GPIO_PD_DIN GPIO_Px_DIN(GPIO_PD)
+#define GPIO_PD_PINLOCKN GPIO_Px_PINLOCKN(GPIO_PD)
+
+#define GPIO_PE (GPIO_BASE + 0x090)
+#define GPIO_PE_CTRL GPIO_Px_CTRL(GPIO_PE)
+#define GPIO_PE_MODEL GPIO_Px_MODEL(GPIO_PE)
+#define GPIO_PE_MODEH GPIO_Px_MODEH(GPIO_PE)
+#define GPIO_PE_DOUT GPIO_Px_DOUT(GPIO_PE)
+#define GPIO_PE_DOUTSET GPIO_Px_DOUTSET(GPIO_PE)
+#define GPIO_PE_DOUTCLR GPIO_Px_DOUTCLR(GPIO_PE)
+#define GPIO_PE_DOUTTGL GPIO_Px_DOUTTGL(GPIO_PE)
+#define GPIO_PE_DIN GPIO_Px_DIN(GPIO_PE)
+#define GPIO_PE_PINLOCKN GPIO_Px_PINLOCKN(GPIO_PE)
+
+#define GPIO_PF (GPIO_BASE + 0x0B4)
+#define GPIO_PF_CTRL GPIO_Px_CTRL(GPIO_PF)
+#define GPIO_PF_MODEL GPIO_Px_MODEL(GPIO_PF)
+#define GPIO_PF_MODEH GPIO_Px_MODEH(GPIO_PF)
+#define GPIO_PF_DOUT GPIO_Px_DOUT(GPIO_PF)
+#define GPIO_PF_DOUTSET GPIO_Px_DOUTSET(GPIO_PF)
+#define GPIO_PF_DOUTCLR GPIO_Px_DOUTCLR(GPIO_PF)
+#define GPIO_PF_DOUTTGL GPIO_Px_DOUTTGL(GPIO_PF)
+#define GPIO_PF_DIN GPIO_Px_DIN(GPIO_PF)
+#define GPIO_PF_PINLOCKN GPIO_Px_PINLOCKN(GPIO_PF)
+
+#define GPIO_EXTIPSELL MMIO32(GPIO_BASE + 0x100) /**< @see EFM32TG_GPIO_EXTIP_values */
+#define GPIO_EXTIPSELH MMIO32(GPIO_BASE + 0x104) /**< @see EFM32TG_GPIO_EXTIP_values */
+#define GPIO_EXTIRISE MMIO32(GPIO_BASE + 0x108) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_EXTIFALL MMIO32(GPIO_BASE + 0x10C) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_IEN MMIO32(GPIO_BASE + 0x110) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_IF MMIO32(GPIO_BASE + 0x114) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_IFS MMIO32(GPIO_BASE + 0x118) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_IFC MMIO32(GPIO_BASE + 0x11C) /**< @see EFM32TG_GPIO_pinnumberbits */
+#define GPIO_ROUTE MMIO32(GPIO_BASE + 0x120) /**< @see EFM32TG_GPIO_ROUTE_bits */
+#define GPIO_INSENSE MMIO32(GPIO_BASE + 0x124) /**< @see EFM32TG_GPIO_INSENSE_bits */
+#define GPIO_LOCK MMIO32(GPIO_BASE + 0x128) /**< @see EFM32TG_GPIO_LOCK_values */
+#define GPIO_CTRL MMIO32(GPIO_BASE + 0x12C) /**< @see EFM32TG_GPIO_CTRL_bits */
+#define GPIO_CMD MMIO32(GPIO_BASE + 0x130) /**< @see EFM32TG_GPIO_CMD_bits */
+#define GPIO_EM4WUEN MMIO32(GPIO_BASE + 0x134) /**< @see EFM32TG_GPIO_EM4WUEN_bits */
+#define GPIO_EM4WUPOL MMIO32(GPIO_BASE + 0x138) /**< @see EFM32TG_GPIO_EM4WUPOL_bits */
+#define GPIO_EM4WUCAUSE MMIO32(GPIO_BASE + 0x13C) /**< @see EFM32TG_GPIO_EM4WUCAUSE_bits */
+
+/** @} */
+
+/** Pin number bits
+ *
+ * Provided for convenience. They can be used on the GPIO_Px_DOUT,
+ * GPIO_Px_DOUTSET, GPIO_Px_DOUTCLR, GPIO_Px_DOUTTGL, GPIO_Px_DIN,
+ * GPIO_Px_PINLOCKN, GPIO_Px_EXTIRISE, GPIO_Px_EXTIFALL, GPIO_IEN, GPIO_IF,
+ * GPIO_IFS, and GPIO_IFC registers.
+ *
+ * @defgroup EFM32TG_GPIO_pinnumberbits GPIO pin number bits
+ * @{
+ */
+
+#define GPIO0 (1 << 0)
+#define GPIO1 (1 << 1)
+#define GPIO2 (1 << 2)
+#define GPIO3 (1 << 3)
+#define GPIO4 (1 << 4)
+#define GPIO5 (1 << 5)
+#define GPIO6 (1 << 6)
+#define GPIO7 (1 << 7)
+#define GPIO8 (1 << 8)
+#define GPIO9 (1 << 9)
+#define GPIO10 (1 << 10)
+#define GPIO11 (1 << 11)
+#define GPIO12 (1 << 12)
+#define GPIO13 (1 << 13)
+#define GPIO14 (1 << 14)
+#define GPIO15 (1 << 15)
+#define GPIO_ALL 0xffff
+
+/** @} */
+
+/** Bit states for the GPIO_Px_CTRL register
+ *
+ * They are named as in d0034_efm32tg_reference_manual.pdf's section
+ * 28.5.1.
+ *
+ * @defgroup EFM32TG_GPIO_Px_CTRL_bits GPIO Px CTRL bits
+ * @{
+ */
+
+#define GPIO_CTRL_DRIVEMODE_STANDARD 0 /**< 6mA drive current */
+#define GPIO_CTRL_DRIVEMODE_LOWEST 1 /**< 0.5mA drive current */
+#define GPIO_CTRL_DRIVEMODE_HIGH 2 /**< 20mA drive current */
+#define GPIO_CTRL_DRIVEMODE_LOW 3 /**< 2mA drive current */
+
+/** @} */
+
+/** These are the modes defined for the MODEx fields in the GPIO_Px_MODEL and
+ * GPIO_Px_MODEH registers.
+ *
+ * These bit state definitions are not localized, meaning that they have to be
+ * bitshifted by multiples of 4 to configure other pins than 0; configurations
+ * for pins 0 to 7 go to GPIO_Px_MODEL (shifted by 4*pin), configurations for
+ * pins 8 to 15 go to GPIO_Px_MODEH (shifted by 4*(pin-8)).
+ *
+ * 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 EFM32TG_GPIO_MODE_values GPIO MODE values
+ * @{
+ */
+
+#define GPIO_MODE_DISABLED 0
+#define GPIO_MODE_INPUT 1
+#define GPIO_MODE_INPUTPULL 2
+#define GPIO_MODE_INPUTPULLFILTER 3
+#define GPIO_MODE_PUSHPULL 4
+#define GPIO_MODE_PUSHPULLDRIVE 5
+#define GPIO_MODE_WIREDOR 6
+#define GPIO_MODE_WIREDORPULLDOWN 7
+#define GPIO_MODE_WIREDAND 8
+#define GPIO_MODE_WIREDANDFILTER 9
+#define GPIO_MODE_WIREDANDPULLUP 10
+#define GPIO_MODE_WIREDANDPULLUPFILTER 11
+#define GPIO_MODE_WIREDANDDRIVE 12
+#define GPIO_MODE_WIREDANDDRIVEFILTER 13
+#define GPIO_MODE_WIREDANDDRIVEPULLUP 14
+#define GPIO_MODE_WIREDANDDRIVEPULLUPFILTER 15
+#define GPIO_MODE_MASK 0x0f
+
+/** @} */
+
+/** These are the modes defined for the EXTIPSELx fields in the GPIO_EXTIPSELL
+ * and GPIO_EXTIPSELH registers.
+ *
+ * These bit state definitions are not localized, meaning that they have to be
+ * bitshifted by multiples of 4 to configure other pins than 0; configurations
+ * for pins 0 to 7 go to GPIO_EXTIPSELL (shifted by 4*pin), configurations for
+ * pins 8 to 15 go to GPIO_EXTIPSELH (shifted by 4*(pin-8)).
+ *
+ * They are named as in d0034_efm32tg_reference_manual.pdf's sections
+ * 28.5.10/28.5.11. For explanations of what they do, rather see section
+ * 28.3.5.
+ *
+ * @defgroup EFM32TG_GPIO_EXTIP_values GPIO EXTIPSEL values
+ * @{
+ */
+
+#define GPIO_EXTIPSEL_PORTA 0 /**< Port A pin x selected for external interrupt x */
+#define GPIO_EXTIPSEL_PORTB 1 /**< Port B pin x selected for external interrupt x */
+#define GPIO_EXTIPSEL_PORTC 2 /**< Port C pin x selected for external interrupt x */
+#define GPIO_EXTIPSEL_PORTD 3 /**< Port D pin x selected for external interrupt x */
+#define GPIO_EXTIPSEL_PORTE 4 /**< Port E pin x selected for external interrupt x */
+#define GPIO_EXTIPSEL_PORTF 5 /**< Port F pin x selected for external interrupt x */
+
+/** @} */
+
+/** Bit states for the GPIO_ROUTE register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 28.5.18 for definitions, and
+ * 28.3.4.1 for explanations.
+ *
+ * @defgroup EFM32TG_GPIO_ROUTE_bits GPIO ROUTE bits
+ * @{
+ */
+
+#define GPIO_ROUTE_SWLOCATION_MASK (0x03<<8)
+#define GPIO_ROUTE_SWLOCATION_LOC0 (0<<8) /**< Route SW pins to location 0 (see chip data sheet for exact pins */
+#define GPIO_ROUTE_SWLOCATION_LOC1 (1<<8) /**< Route SW pins to location 1 (see chip data sheet for exact pins */
+#define GPIO_ROUTE_SWLOCATION_LOC2 (2<<8) /**< Route SW pins to location 2 (see chip data sheet for exact pins */
+#define GPIO_ROUTE_SWLOCATION_LOC3 (3<<8) /**< Route SW pins to location 3 (see chip data sheet for exact pins */
+
+#define GPIO_ROUTE_SWOPEN (1<<2) /**< Serial Wire Viewer Output pin enabled */
+#define GPIO_ROUTE_SWDIOPEN (1<<1) /**< Serial Wire Data pin enabled */
+#define GPIO_ROUTE_SWCLKPEN (1<<0) /**< Serial Wire Clock pin enabled */
+
+/** @} */
+
+/** Bit states for the GPIO_INSENSE register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 28.5.19 for definitions, and
+ * 28.3.7 for details.
+ *
+ * @defgroup EFM32TG_GPIO_INSENSE_bits GPIO INSENSE bits
+ * @{
+ */
+
+#define GPIO_INSENSE_PRS (1<<1) /**< Input sensing for PRS enabled */
+#define GPIO_INSENSE_INT (1<<0) /**< Input sensing for interrupts enabled */
+
+/** @} */
+
+/** Values for the GPIO_LOCK register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 28.5.20 for definitions, and
+ * 28.3.1.1 for explanations.
+ *
+ * @defgroup EFM32TG_GPIO_LOCK_values GPIO LOCK bits
+ * @{
+ */
+
+#define GPIO_LOCK_IS_UNLOCKED 0 /**< When the LOCK register reads as this value, it is open */
+#define GPIO_LOCK_IS_LOCKED 1 /**< When the LOCK register reads as this value, it is locked */
+#define GPIO_LOCK_SET_LOCKED 0 /**< Write this to the LOCK register to lock down GPIO */
+#define GPIO_LOCK_SET_UNLOCKED 0xa543 /**< Write this to the LOCK register to unlock the GPIO */
+
+/** @} */
+
+/** Bit states for the GPIO_CTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 28.5.21 for definitions, and
+ * 28.3.4 for explanations.
+ *
+ * @defgroup EFM32TG_GPIO_CTRL_bits GPIO CTRL bits
+ * @{
+ */
+
+#define GPIO_CTRL_EM4RET (1<<0) /**< Retention of states in EM4 */
+
+/** @} */
+
+/** Bit states for the GPIO_CMD register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 28.5.22 for definitions and
+ * figure 28.5 in case you wonder if that register is mentioned anywhere else
+ * at all.
+ *
+ * @defgroup EFM32TG_GPIO_CMD_bits GPIO CMD bits
+ * @{
+ */
+
+#define GPIO_CMD_EM4WUCLR (1<<0) /**< Write this flag to clear EM4 wakeup requests */
+
+/** @} */
+
+/** Bit states for the GPIO_EM4WUEN register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 28.5.23 for definitions, and
+ * 28.3.2 for explanations.
+ *
+ * @defgroup EFM32TG_GPIO_EM4WUEN_bits GPIO EM4WUEN bits
+ * @{
+ */
+
+#define GPIO_EM4WUEN_A0 0x01 /**< Wake up from EM4 on A0 activity */
+#define GPIO_EM4WUEN_A6 0x02 /**< Wake up from EM4 on A6 activity */
+#define GPIO_EM4WUEN_C9 0x04 /**< Wake up from EM4 on C9 activity */
+#define GPIO_EM4WUEN_F1 0x08 /**< Wake up from EM4 on F1 activity */
+#define GPIO_EM4WUEN_F3 0x10 /**< Wake up from EM4 on F3 activity */
+#define GPIO_EM4WUEN_E13 0x20 /**< Wake up from EM4 on E13 activity */
+
+/** @} */
+
+/** Bit states for the GPIO_EM4WUPOL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 28.5.24 for definitions, and
+ * 28.3.2 for explanations.
+ *
+ * @defgroup EFM32TG_GPIO_EM4WUPOL_bits GPIO EM4WUPOL bits
+ * @{
+ */
+
+#define GPIO_EM4WUPOL_A0 0x01 /**< High wake up from EM4 on A0 */
+#define GPIO_EM4WUPOL_A6 0x02 /**< High wake up from EM4 on A6 */
+#define GPIO_EM4WUPOL_C9 0x04 /**< High wake up from EM4 on C9 */
+#define GPIO_EM4WUPOL_F1 0x08 /**< High wake up from EM4 on F1 */
+#define GPIO_EM4WUPOL_F3 0x10 /**< High wake up from EM4 on F3 */
+#define GPIO_EM4WUPOL_E13 0x20 /**< High wake up from EM4 on E13 */
+
+/** @} */
+
+/** Bit states for the GPIO_EM4WUCAUSE register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 28.5.25 for definitions, and
+ * 28.3.2 for explanations.
+ *
+ * @defgroup EFM32TG_GPIO_EM4WUCAUSE_bits GPIO EM4WUCAUSE bits
+ * @{
+ */
+
+#define GPIO_EM4WUCAUSE_A0 0x01 /**< Woke up from EM4 on A0 */
+#define GPIO_EM4WUCAUSE_A6 0x02 /**< Woke up from EM4 on A6 */
+#define GPIO_EM4WUCAUSE_C9 0x04 /**< Woke up from EM4 on C9 */
+#define GPIO_EM4WUCAUSE_F1 0x08 /**< Woke up from EM4 on F1 */
+#define GPIO_EM4WUCAUSE_F3 0x10 /**< Woke up from EM4 on F3 */
+#define GPIO_EM4WUCAUSE_E13 0x20 /**< Woke up from EM4 on E13 */
+
+/** @} */
+
+/** @} */
+
+/** GPIO convenience functions
+ *
+ * These functions try to be close to the STM32 F1 utility functions where
+ * possible.
+ *
+ * The functions intentionally don't cover all the possible read- and write
+ * operations to the GPIO registers. For example, reading the configured output
+ * strength for a port is rarely required.
+ *
+ * Many convenience functions are static to allow inlining by the compiler.
+ *
+ * @todo Implement all the non-trivial but useful convenience functions.
+ *
+ * @defgroup EFM32TG_GPIO_convenience GPIO convenience functions
+ * @{
+ */
+
+/** Set a whole GPIO port's out data to a particular value
+ *
+ * \param gpioport Address of a GPIO port to use (eg GPIO_PA)
+ * \param gpios Bit pattern the output of the port will be configured to (eg GPIO6|GPIO3 to switch pins 6 and 3 to high and all the others to low)
+ */
+static void gpio_port_write(u32 gpioport, u16 data)
+{
+ GPIO_Px_DOUT(gpioport) = data;
+}
+/** Set some bits in a GPIO port's out data
+ *
+ * \param gpioport Address of a GPIO port to use (eg GPIO_PA)
+ * \param gpios GPIO pin(s) to be set to 1 (eg GPIO6|GPIO3 to switch pins 6 and 3 to high and leave all the others in their previous state)
+ */
+static void gpio_set(u32 gpioport, u16 gpios)
+{
+ GPIO_Px_DOUTSET(gpioport) = gpios;
+}
+/** Clear some bits in a GPIO port's out data
+ *
+ * \param gpioport Address of a GPIO port to use (eg GPIO_PA)
+ * \param gpios GPIO pin(s) to be set to 0 (eg GPIO6|GPIO3 to switch pins 6 and 3 to low and leave all the others in their previous state)
+ */
+static void gpio_clear(u32 gpioport, u16 gpios)
+{
+ GPIO_Px_DOUTCLR(gpioport) = gpios;
+}
+/** Toggle some bits in a GPIO port's out data
+ *
+ * \param gpioport Address of a GPIO port to use (eg GPIO_PA)
+ * \param gpios GPIO pin(s) that will be toggled (eg GPIO6|GPIO3 to toggle the output directions of pins 6 and 3 and leave all the others in their previous state)
+ */
+static void gpio_toggle(u32 gpioport, u16 gpios)
+{
+ GPIO_Px_DOUTTGL(gpioport) = gpios;
+}
+
+/** Read input bits from a GPIO's port in data
+ *
+ * \param gpioport Address of a GPIO port to use (eg GPIO_PA)
+ * \returns Current value of the in register of the given port
+ */
+static u16 gpio_port_read(u32 gpioport)
+{
+ return GPIO_Px_DIN(gpioport);
+}
+/** Read input bits from a GPIO's port in data
+ *
+ * \param gpioport Address of a GPIO port to use (eg GPIO_PA)
+ * \param gpios Bits that will be read (eg GPIO6|GPIO3 to read pins 6 and 3)
+ * \returns Bit pattern that contains 1 in all pin positions that currently read as high (eg GPIO6 if port A's 6th pin is currently high and the 3rd pin is low)
+ */
+static u16 gpio_get(u32 gpioport, u16 gpios)
+{
+ return gpio_port_read(gpioport) & gpios;
+}
+
+/** Configure a particular pin configuration on one or more pins
+ *
+ * This function is not atomic. It has to be made sure that it is not
+ * interrupted by other code that modifies the port's configuration.
+ *
+ * \param gpioport Address of a GPIO port to use (eg GPIO_PA)
+ * \param mode Pin configuration mode to set (eg GPIO_MODE_INPUT)
+ * \param gpios Pins to configure (eg GPIO6|GPIO3 to set the mode on pins 6 and 3)
+ */
+void gpio_set_mode(u32 gpioport, u8 mode, u16 gpios);
+
+/** Configure the alternate drive strength for a port
+ *
+ * \param gpioport Address of a GPIO port to use (eg GPIO_PA)
+ * \param strength Alternate drive strength to configure for the port (eg GPIO_CTRL_DRIVEMODE_HIGH)
+ */
+static void gpio_set_strength(u32 gpioport, u8 strength)
+{
+ GPIO_Px_CTRL(gpioport) = strength;
+}
+
+/** @} */
+
+/** @} */
+
+#endif
diff --git a/include/libopencm3/efm32/tinygecko/irq.h b/include/libopencm3/efm32/tinygecko/irq.h
new file mode 100644
index 0000000..1b0a484
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/irq.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ *
+ * Definitions of interrupt names on EFM32 Tiny Gecko systems
+ *
+ * The names and numbers are taken from d0034_efm32tg_reference_manual.pdf table 4.1.
+ */
+
+#ifndef LIBOPENCM3_EFM32_TINYGECKO_VECTOR_H
+#define LIBOPENCM3_EFM32_TINYGECKO_VECTOR_H
+
+#define IRQ_DMA 0
+#define IRQ_GPIO_EVEN 1
+#define IRQ_TIMER0 2
+#define IRQ_USART0_RX 3
+#define IRQ_USART0_TX 4
+#define IRQ_ACMP01 5
+#define IRQ_ADC0 6
+#define IRQ_DAC0 7
+#define IRQ_I2C0 8
+#define IRQ_GPIO_ODD 9
+#define IRQ_TIMER1 10
+#define IRQ_USART1_RX 11
+#define IRQ_USART1_TX 12
+#define IRQ_LESENSE 13
+#define IRQ_LEUART0 14
+#define IRQ_LETIMER0 15
+#define IRQ_PCNT0 16
+#define IRQ_RTC 17
+#define IRQ_CMU 18
+#define IRQ_VCMP 19
+#define IRQ_LCD 20
+#define IRQ_MSC 21
+#define IRQ_AES 22
+#define IRQ_COUNT 23 /**< See also d0002_efm32_cortex-m3_reference_manual.pdf's table 1.1's "number of interrupts" line, which shows that there are really no more interrupts and it is sufficient to allocate only 23 slots. */
+
+#endif
diff --git a/include/libopencm3/efm32/tinygecko/lcd.convenienceheaders b/include/libopencm3/efm32/tinygecko/lcd.convenienceheaders
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/lcd.convenienceheaders
diff --git a/include/libopencm3/efm32/tinygecko/lcd.h b/include/libopencm3/efm32/tinygecko/lcd.h
new file mode 100644
index 0000000..d46ef24
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/lcd.h
@@ -0,0 +1,295 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * @see EFM32TG_LCD
+ */
+
+/** Definitions for the LCD subsystem (Liquid Crystal Display driver).
+ *
+ * This corresponds to the description in d0034_efm32tg_reference_manual.pdf
+ * section 29.
+ *
+ * @ingroup EFM32TG
+ * @defgroup EFM32TG_LCD LCD (Liquid Crystal Display driver)
+ * @{
+ */
+
+#ifndef LIBOPENCM3_EFM32_TINYGECKO_LCD_H
+#define LIBOPENCM3_EFM32_TINYGECKO_LCD_H
+
+#include <libopencm3/cm3/common.h>
+#include <libopencm3/efm32/memorymap.h>
+
+/** Register definitions and register value definitions for the LCD subsystem
+ *
+ * @defgroup EFM32TG_LCD_regsandvals LCD registers and values
+ * @{
+ */
+
+/** These definitions reflect d0034_efm32tg_reference_manual.pdf section 29.4
+ *
+ * @defgroup EFM32TG_LCD_registers LCD registers
+ * @{
+ */
+
+#define LCD_CTRL MMIO32(LCD_BASE + 0x000) /**< @see EFM32TG_LCD_CTRL_bits */
+#define LCD_DISPCTRL MMIO32(LCD_BASE + 0x004) /**< @see EFM32TG_LCD_DISPCTRL_bits */
+#define LCD_SEGEN MMIO32(LCD_BASE + 0x008)
+#define LCD_BACTRL MMIO32(LCD_BASE + 0x00c) /**< @see EFM32TG_LCD_BACTRL_bits */
+#define LCD_STATUS MMIO32(LCD_BASE + 0x010) /**< @see EFM32TG_LCD_STATUS_bits */
+#define LCD_AREGA MMIO32(LCD_BASE + 0x014)
+#define LCD_AREGB MMIO32(LCD_BASE + 0x018)
+#define LCD_IF MMIO32(LCD_BASE + 0x01c) /**< @see EFM32TG_LCD_I_bits */
+#define LCD_IFS MMIO32(LCD_BASE + 0x020) /**< @see EFM32TG_LCD_I_bits */
+#define LCD_IFC MMIO32(LCD_BASE + 0x024) /**< @see EFM32TG_LCD_I_bits */
+#define LCD_IEN MMIO32(LCD_BASE + 0x028) /**< @see EFM32TG_LCD_I_bits */
+#define LCD_SEGD0L MMIO32(LCD_BASE + 0x040) /**< @see EFM32TG_LCD_SEG_bits */
+#define LCD_SEGD1L MMIO32(LCD_BASE + 0x044) /**< @see EFM32TG_LCD_SEG_bits */
+#define LCD_SEGD2L MMIO32(LCD_BASE + 0x048) /**< @see EFM32TG_LCD_SEG_bits */
+#define LCD_SEGD3L MMIO32(LCD_BASE + 0x04c) /**< @see EFM32TG_LCD_SEG_bits */
+#define LCD_FREEZE MMIO32(LCD_BASE + 0x060) /**< @see EFM32TG_LCD_FREEZE_bits */
+#define LCD_SYNCBUSY MMIO32(LCD_BASE + 0x064) /**< @see EFM32TG_LCD_SYNCBUSY_bits */
+#define LCD_SEGD4L MMIO32(LCD_BASE + 0x0cc) /**< @see EFM32TG_LCD_SEG_bits */
+#define LCD_SEGD5L MMIO32(LCD_BASE + 0x0d0) /**< @see EFM32TG_LCD_SEG_bits */
+#define LCD_SEGD6L MMIO32(LCD_BASE + 0x0d4) /**< @see EFM32TG_LCD_SEG_bits */
+#define LCD_SEGD7L MMIO32(LCD_BASE + 0x0d8) /**< @see EFM32TG_LCD_SEG_bits */
+
+/** @} */
+
+/** Bit states for the LCD_CTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 29.5.1 for definitions.
+ *
+ * @defgroup EFM32TG_LCD_CTRL_bits LCD CTRL bits
+ * @{
+ */
+
+#define LCD_CTRL_DSC (1<<23)
+#define LCD_CTRL_UDCTRL_REGULAR (0<<1)
+#define LCD_CTRL_UDCTRL_FCEVENT (1<<1)
+#define LCD_CTRL_UDCTRL_FRAMESTART (2<<1)
+#define LCD_CTRL_UDCTRL_MASK (0x3<<1)
+#define LCD_CTRL_EN (1<<0)
+
+/** @} */
+
+/** Bit states for the LCD_DISPCTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 29.5.2 for definitions.
+ *
+ * @defgroup EFM32TG_LCD_DISPCTRL_bits LCD DISPCTRL bits
+ * @{
+ */
+
+#define LCD_DISPCTRL_VBLEV_LEVEL0 (0<<18)
+#define LCD_DISPCTRL_VBLEV_LEVEL1 (1<<18)
+#define LCD_DISPCTRL_VBLEV_LEVEL2 (2<<18)
+#define LCD_DISPCTRL_VBLEV_LEVEL3 (3<<18)
+#define LCD_DISPCTRL_VBLEV_LEVEL4 (4<<18)
+#define LCD_DISPCTRL_VBLEV_LEVEL5 (5<<18)
+#define LCD_DISPCTRL_VBLEV_LEVEL6 (6<<18)
+#define LCD_DISPCTRL_VBLEV_LEVEL7 (7<<18)
+#define LCD_DISPCTRL_VBLEV_MASK (0x7<<18)
+#define LCD_DISPCTRL_VLCDSEL_VDD (0<<16)
+#define LCD_DISPCTRL_VLCDSEL_VEXTBOOST (1<<16)
+#define LCD_DISPCTRL_VLCDSEL_MASK (0x1<<16)
+#define LCD_DISPCTRL_CONCONF_VLCD (0<<15)
+#define LCD_DISPCTRL_CONCONF_GND (1<<15)
+#define LCD_DISPCTRL_CONCONF_MASK (0x1<<15)
+/** By this parameter, the voltage V_LCD_OUT is interpolated linearly from
+ * 0.5V_LCD to V_LCD.
+ */
+#define LCD_DISPCTRL_CONLEV_MIN (0<<8)
+#define LCD_DISPCTRL_CONLEV_MAX (31<<8)
+#define LCD_DISPCTRL_CONLEV_MASK (0x1f<<8)
+#define LCD_DISPCTRL_WAVE_LOWPOWER (0<<4)
+#define LCD_DISPCTRL_WAVE_NORMAL (1<<4)
+#define LCD_DISPCTRL_WAVE_MASK (0x1<<4)
+#define LCD_DISPCTRL_BIAS_STATIC (0<<2)
+#define LCD_DISPCTRL_BIAS_ONEHALF (1<<2)
+#define LCD_DISPCTRL_BIAS_ONETHIRD (2<<2)
+#define LCD_DISPCTRL_BIAS_ONEFOURTH (3<<2)
+#define LCD_DISPCTRL_BIAS_MASK (0x3<<2)
+/** These definitions munge the MUX and the MUXE fields, as they are described
+ * in the documentation only together too.
+ */
+#define LCD_DISPCTRL_MUX_STATIC 0x00000000
+#define LCD_DISPCTRL_MUX_DUPLEX 0x00000001
+#define LCD_DISPCTRL_MUX_TRIPLEX 0x00000002
+#define LCD_DISPCTRL_MUX_QUADRUPLEX 0x00000003
+#define LCD_DISPCTRL_MUX_SEXTAPLEX 0x00400001
+#define LCD_DISPCTRL_MUX_OCTAPLEX 0x00400003
+#define LCD_DISPCTRL_MUX_MASK 0x00400003
+
+/** @} */
+
+/** Bit states for the LCD_BACTRL register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 29.5.4 for definitions.
+ *
+ * @defgroup EFM32TG_LCD_BACTRL_bits LCD BACTRL bits
+ * @{
+ */
+
+#define LCD_BACTRL_FCTOP_MASK (0x3f<<18)
+#define LCD_BACTRL_FCPRESC_DIV1 (0<<16)
+#define LCD_BACTRL_FCPRESC_DIV2 (1<<16)
+#define LCD_BACTRL_FCPRESC_DIV4 (2<<16)
+#define LCD_BACTRL_FCPRESC_DIV8 (3<<16)
+#define LCD_BACTRL_FCPRESC_MASK (0x3<<16)
+#define LCD_BACTRL_FCEN (1<<8)
+#define LCD_BACTRL_ALGOSEL_AND (0<<7)
+#define LCD_BACTRL_ALGOSEL_OR (1<<7)
+#define LCD_BACTRL_ALGOSEL_MASK (0x1<<7)
+#define LCD_BACTRL_AREGBSC_NOSHIFT (0<<5)
+#define LCD_BACTRL_AREGBSC_SHIFTLEFT (1<<5)
+#define LCD_BACTRL_AREGBSC_SHIFTRIGHT (2<<5)
+#define LCD_BACTRL_AREGBSC_MASK (0x3<<5)
+#define LCD_BACTRL_AREGASC_NOSHIFT (0<<3)
+#define LCD_BACTRL_AREGASC_SHIFTLEFT (1<<3)
+#define LCD_BACTRL_AREGASC_SHIFTRIGHT (2<<3)
+#define LCD_BACTRL_AREGASC_MASK (0x3<<3)
+#define LCD_BACTRL_AEN (1<<2)
+#define LCD_BACTRL_BLANK (1<<1)
+#define LCD_BACTRL_BLINKEN (1<<0)
+
+/** @} */
+
+/** Bit states for the LCD_STATUS register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 29.5.5 for definitions.
+ *
+ * @defgroup EFM32TG_LCD_STATUS_bits LCD STATUS bits
+ * @{
+ */
+
+#define LCD_STATUS_BLINK (1<<8)
+#define LCD_STATUS_ASTATE_MASK (0xf<<0)
+
+/** @} */
+
+/** Bit states for the LCD_FREEZE register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 29.5.16 for definitions.
+ *
+ * @defgroup EFM32TG_LCD_FREEZE_bits LCD FREEZE bits
+ * @{
+ */
+
+#define LCD_FREEZE_REGFREEZE_UPDATE (0<<0)
+#define LCD_FREEZE_REGFREEZE_FREEZE (1<<0)
+#define LCD_FREEZE_REGFREEZE_MASK (0x1<<0)
+
+/** @} */
+
+/** Bit states for the LCD_SYNCBUSY register
+ *
+ * See d0034_efm32tg_reference_manual.pdf section 29.5.17 for definitions.
+ *
+ * @defgroup EFM32TG_LCD_SYNCBUSY_bits LCD SYNCBUSY bits
+ * @{
+ */
+
+#define LCD_SYNCBUSY_SEGD7L (1<<19)
+#define LCD_SYNCBUSY_SEGD6L (1<<18)
+#define LCD_SYNCBUSY_SEGD5L (1<<17)
+#define LCD_SYNCBUSY_SEGD4L (1<<16)
+#define LCD_SYNCBUSY_SEGD3L (1<<7)
+#define LCD_SYNCBUSY_SEGD2L (1<<6)
+#define LCD_SYNCBUSY_SEGD1L (1<<5)
+#define LCD_SYNCBUSY_SEGD0L (1<<4)
+#define LCD_SYNCBUSY_AREGB (1<<3)
+#define LCD_SYNCBUSY_AREGA (1<<2)
+#define LCD_SYNCBUSY_BACTRL (1<<1)
+#define LCD_SYNCBUSY_CTRL (1<<0)
+
+/** @} */
+
+/** Bit states for the LCD "I" group of registers (IF, IFS, IFC, IEN)
+ *
+ * These registers use this:
+ *
+ * <ul>
+ *
+ * <li>The LCD_IF register; see d0034_efm32tg_reference_manual.pdf section
+ * 29.5.8 for definitions.</li>
+ *
+ * <li>The LCD_IFS register; see d0034_efm32tg_reference_manual.pdf section
+ * 29.5.9 for definitions.</li>
+ *
+ * <li>The LCD_IFC register; see d0034_efm32tg_reference_manual.pdf section
+ * 29.5.10 for definitions.</li>
+ *
+ * <li>The LCD_IEN register; see d0034_efm32tg_reference_manual.pdf section
+ * 29.5.11 for definitions.</li>
+ *
+ * </ul>
+ *
+ * @defgroup EFM32TG_LCD_I_bits LCD I bits group
+ * @{
+ */
+
+#define LCD_I_FC (1<<0)
+
+/** @} */
+
+/** Bit states for the LCD "SEG" group of registers (SEGD0L, SEGD1L, SEGD2L,
+ * SEGD3L, SEGD4L, SEGD5L, SEGD6L, SEGD7L)
+ *
+ * These values are used by the SEGDxL registers, as defined in
+ * d0034_efm32tg_reference_manual.pdf sections 29.5.12 to .15 and .18 to .21.
+ *
+ * @defgroup EFM32TG_LCD_SEG_bits LCD SEG bits group
+ * @{
+ */
+
+#define LCD_SEG_23 (1<<23)
+#define LCD_SEG_22 (1<<22)
+#define LCD_SEG_21 (1<<21)
+#define LCD_SEG_20 (1<<20)
+#define LCD_SEG_19 (1<<19)
+#define LCD_SEG_18 (1<<18)
+#define LCD_SEG_17 (1<<17)
+#define LCD_SEG_16 (1<<16)
+#define LCD_SEG_15 (1<<15)
+#define LCD_SEG_14 (1<<14)
+#define LCD_SEG_13 (1<<13)
+#define LCD_SEG_12 (1<<12)
+#define LCD_SEG_11 (1<<11)
+#define LCD_SEG_10 (1<<10)
+#define LCD_SEG_9 (1<<9)
+#define LCD_SEG_8 (1<<8)
+#define LCD_SEG_7 (1<<7)
+#define LCD_SEG_6 (1<<6)
+#define LCD_SEG_5 (1<<5)
+#define LCD_SEG_4 (1<<4)
+#define LCD_SEG_3 (1<<3)
+#define LCD_SEG_2 (1<<2)
+#define LCD_SEG_1 (1<<1)
+#define LCD_SEG_0 (1<<0)
+
+/** @} */
+
+/** @} */
+
+
+/** @} */
+
+#endif
diff --git a/include/libopencm3/efm32/tinygecko/lcd.yaml b/include/libopencm3/efm32/tinygecko/lcd.yaml
new file mode 100644
index 0000000..0e003bd
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/lcd.yaml
@@ -0,0 +1,241 @@
+copyright: "2012 chrysn <chrysn@fsfe.org>"
+license: lgpl-3+
+ingroup: EFM32TG
+shortdocname: EFM32TG_LCD
+shortname: LCD
+longname: Liquid Crystal Display driver
+baseref: d0034_efm32tg_reference_manual.pdf section 29
+registers_baserefext: ".4"
+templateregs:
+ - name: I
+ comment: Bits for the various LCD interrupt registers
+ fields:
+ - {name: FC, shift: 0}
+ - name: SEG
+ comment: Bits for the individual SEG pins
+ override_backref: These values are used by the SEGDxL registers, as defined in d0034_efm32tg_reference_manual.pdf sections 29.5.12 to .15 and .18 to .21.
+ fields:
+ - {name: 23, shift: 23}
+ - {name: 22, shift: 22}
+ - {name: 21, shift: 21}
+ - {name: 20, shift: 20}
+ - {name: 19, shift: 19}
+ - {name: 18, shift: 18}
+ - {name: 17, shift: 17}
+ - {name: 16, shift: 16}
+ - {name: 15, shift: 15}
+ - {name: 14, shift: 14}
+ - {name: 13, shift: 13}
+ - {name: 12, shift: 12}
+ - {name: 11, shift: 11}
+ - {name: 10, shift: 10}
+ - {name: 9, shift: 9}
+ - {name: 8, shift: 8}
+ - {name: 7, shift: 7}
+ - {name: 6, shift: 6}
+ - {name: 5, shift: 5}
+ - {name: 4, shift: 4}
+ - {name: 3, shift: 3}
+ - {name: 2, shift: 2}
+ - {name: 1, shift: 1}
+ - {name: 0, shift: 0}
+registers:
+ - name: CTRL
+ offset: 0x000
+ definition_baserefext: .5.1
+ fields:
+ - name: DSC
+ shift: 23
+ - name: UDCTRL
+ shift: 1
+ length: 2
+ values:
+ - {name: REGULAR, value: 0}
+ - {name: FCEVENT, value: 1}
+ - {name: FRAMESTART, value: 2}
+ - name: EN
+ shift: 0
+ - name: DISPCTRL
+ offset: 0x004
+ definition_baserefext: .5.2
+ fields:
+ # MUXE left out and defined manually at the end
+ - name: VBLEV
+ shift: 18
+ length: 3
+ values:
+ - {name: LEVEL0, value: 0}
+ - {name: LEVEL1, value: 1}
+ - {name: LEVEL2, value: 2}
+ - {name: LEVEL3, value: 3}
+ - {name: LEVEL4, value: 4}
+ - {name: LEVEL5, value: 5}
+ - {name: LEVEL6, value: 6}
+ - {name: LEVEL7, value: 7}
+ - name: VLCDSEL
+ shift: 16
+ values:
+ - {name: VDD, value: 0}
+ - {name: VEXTBOOST, value: 1}
+ - name: CONCONF
+ shift: 15
+ values:
+ - {value: 0, name: VLCD}
+ - {value: 1, name: GND}
+ - name: CONLEV
+ shift: 8
+ length: 5
+ type: uint
+ doc: "By this parameter, the voltage V_LCD_OUT is interpolated linearly from 0.5V_LCD to V_LCD."
+ values:
+ - {value: 0, name: MIN}
+ - {value: 31, name: MAX}
+ - name: WAVE
+ shift: 4
+ values:
+ - {value: 0, name: LOWPOWER}
+ - {value: 1, name: NORMAL}
+ - name: BIAS
+ shift: 2
+ length: 2
+ values:
+ - {value: 0, name: STATIC}
+ - {value: 1, name: ONEHALF}
+ - {value: 2, name: ONETHIRD}
+ - {value: 3, name: ONEFOURTH}
+ - name: MUX
+ mask: "0x00400003"
+ values:
+ - {value: "0x00000000", name: STATIC}
+ - {value: "0x00000001", name: DUPLEX}
+ - {value: "0x00000002", name: TRIPLEX}
+ - {value: "0x00000003", name: QUADRUPLEX}
+ - {value: "0x00400001", name: SEXTAPLEX}
+ - {value: "0x00400003", name: OCTAPLEX}
+ doc: These definitions munge the MUX and the MUXE fields, as they are described in the documentation only together too.
+ - name: SEGEN
+ offset: 0x008
+ definition_baserefext: .5.3
+ # FIXME how do we reperesent this best?
+ - name: BACTRL
+ offset: 0x00c
+ definition_baserefext: .5.4
+ fields:
+ - name: FCTOP
+ shift: 18
+ length: 6
+ type: uint
+ - name: FCPRESC
+ shift: 16
+ length: 2
+ values:
+ - {value: 0, name: DIV1}
+ - {value: 1, name: DIV2}
+ - {value: 2, name: DIV4}
+ - {value: 3, name: DIV8}
+ - name: FCEN
+ shift: 8
+ - name: ALGOSEL
+ shift: 7
+ values:
+ - {value: 0, name: AND}
+ - {value: 1, name: OR}
+ - name: AREGBSC
+ shift: 5
+ length: 2
+ values: &BACTRL_AREGBSC
+ - {value: 0, name: NOSHIFT}
+ - {value: 1, name: SHIFTLEFT}
+ - {value: 2, name: SHIFTRIGHT}
+ - name: AREGASC
+ shift: 3
+ length: 2
+ values: *BACTRL_AREGBSC
+ - name: AEN
+ shift: 2
+ - name: BLANK
+ shift: 1
+ - name: BLINKEN
+ shift: 0
+ - name: STATUS
+ offset: 0x010
+ definition_baserefext: .5.5
+ fields:
+ - name: BLINK
+ shift: 8
+ - name: ASTATE
+ shift: 0
+ length: 4
+ type: uint
+ - name: AREGA
+ offset: 0x014
+ # FIXME: how do we represent this in the header?
+ - name: AREGB
+ offset: 0x018
+ # FIXME: how do we represent this in the header?
+ - name: IF
+ offset: 0x01c
+ definition_baserefext: .5.8
+ fields: I
+ - name: IFS
+ offset: 0x020
+ definition_baserefext: .5.9
+ fields: I
+ - name: IFC
+ offset: 0x024
+ definition_baserefext: .5.10
+ fields: I
+ - name: IEN
+ offset: 0x028
+ definition_baserefext: .5.11
+ fields: I
+ - name: SEGD0L
+ offset: 0x040
+ fields: SEG
+ - name: SEGD1L
+ offset: 0x044
+ fields: SEG
+ - name: SEGD2L
+ offset: 0x048
+ fields: SEG
+ - name: SEGD3L
+ offset: 0x04c
+ fields: SEG
+ - name: FREEZE
+ offset: 0x060
+ definition_baserefext: .5.16
+ fields:
+ - name: REGFREEZE
+ shift: 0
+ values:
+ - {value: 0, name: UPDATE}
+ - {value: 1, name: FREEZE}
+ # FIXME: this seems to be a typical FREEZE register
+ - name: SYNCBUSY
+ offset: 0x064
+ definition_baserefext: .5.17
+ fields:
+ - {name: SEGD7L, shift: 19}
+ - {name: SEGD6L, shift: 18}
+ - {name: SEGD5L, shift: 17}
+ - {name: SEGD4L, shift: 16}
+ - {name: SEGD3L, shift: 7}
+ - {name: SEGD2L, shift: 6}
+ - {name: SEGD1L, shift: 5}
+ - {name: SEGD0L, shift: 4}
+ - {name: AREGB, shift: 3}
+ - {name: AREGA, shift: 2}
+ - {name: BACTRL, shift: 1}
+ - {name: CTRL, shift: 0}
+ - name: SEGD4L
+ offset: 0x0CC
+ fields: SEG
+ - name: SEGD5L
+ offset: 0x0D0
+ fields: SEG
+ - name: SEGD6L
+ offset: 0x0D4
+ fields: SEG
+ - name: SEGD7L
+ offset: 0x0D8
+ fields: SEG
diff --git a/include/libopencm3/efm32/tinygecko/memorymap.h b/include/libopencm3/efm32/tinygecko/memorymap.h
new file mode 100644
index 0000000..abf37ce
--- /dev/null
+++ b/include/libopencm3/efm32/tinygecko/memorymap.h
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ *
+ * Layout of the system address space of Tiny Gecko devices.
+ *
+ * This reflects d0034_efm32tg_reference_manual.pdf figure 5.2.
+ */
+
+/* The common cortex-m3 definitions were verified from
+ * d0034_efm32tg_reference_manual.pdf figure 5.2. The CM3 ROM Table seems to be
+ * missing there. The details (everything based on SCS_BASE) was verified from
+ * d0002_efm32_cortex-m3_reference_manual.pdf table 4.1, and seems to fit, but
+ * there are discrepancies. */
+#include <libopencm3/cm3/memorymap.h>
+
+#define CODE_BASE 0x00000000
+
+#define SRAM_BASE 0x20000000
+#define SRAM_BASE_BITBAND 0x22000000
+
+#define PERIPH_BASE 0x40000000
+#define PERIPH_BASE_BITBAND 0x42000000
+
+/* Details of the "Code" section */
+
+#define FLASH_BASE (CODE_BASE + 0x00000000)
+#define USERDATA_BASE (CODE_BASE + 0x0fe00000)
+#define LOCKBITS_BASE (CODE_BASE + 0x0fe04000)
+#define CHIPCONFIG_BASE (CODE_BASE + 0x0fe08000)
+#define CODESPACESRAM_BASE (CODE_BASE + 0x10000000)
+
+/* Tiny Gecko peripherial definitions */
+
+#define VCMP_BASE (PERIPH_BASE + 0x00000000)
+#define ACMP0_BASE (PERIPH_BASE + 0x00001000)
+#define ACMP1_BASE (PERIPH_BASE + 0x00001400)
+#define ADC_BASE (PERIPH_BASE + 0x00002000)
+#define DAC0_BASE (PERIPH_BASE + 0x00004000)
+#define GPIO_BASE (PERIPH_BASE + 0x00006000) /**< @see gpio.h */
+#define I2C0_BASE (PERIPH_BASE + 0x0000a000)
+#define USART0_BASE (PERIPH_BASE + 0x0000c000)
+#define USART1_BASE (PERIPH_BASE + 0x0000c400)
+#define TIMER0_BASE (PERIPH_BASE + 0x00010000)
+#define TIMER1_BASE (PERIPH_BASE + 0x00010400)
+#define RTC_BASE (PERIPH_BASE + 0x00080000)
+#define LETIMER0_BASE (PERIPH_BASE + 0x00082000)
+#define LEUART0_BASE (PERIPH_BASE + 0x00084000)
+#define PCNT0_BASE (PERIPH_BASE + 0x00086000)
+#define WDOG_BASE (PERIPH_BASE + 0x00088000)
+#define LCD_BASE (PERIPH_BASE + 0x0008a000)
+#define LESENSE_BASE (PERIPH_BASE + 0x0008c000)
+#define MSC_BASE (PERIPH_BASE + 0x000c0000)
+#define DMA_BASE (PERIPH_BASE + 0x000c2000)
+#define EMU_BASE (PERIPH_BASE + 0x000c6000)
+#define CMU_BASE (PERIPH_BASE + 0x000c8000) /**< @see cmu.h */
+#define RMU_BASE (PERIPH_BASE + 0x000ca000)
+#define PRS_BASE (PERIPH_BASE + 0x000cc000)
+#define AES_BASE (PERIPH_BASE + 0x000e0000)
diff --git a/include/libopencm3/efm32/vector.h b/include/libopencm3/efm32/vector.h
new file mode 100644
index 0000000..2ae55af
--- /dev/null
+++ b/include/libopencm3/efm32/vector.h
@@ -0,0 +1,66 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ *
+ * Definitions for handling vector tables.
+ *
+ * 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.
+ *
+ * The exact size of a vector interrupt table depends on the number of
+ * interrupts IRQ_COUNT, which is defined per family.
+ */
+
+#ifndef LIBOPENCM3_EFM32_VECTOR_H
+#define LIBOPENCM3_EFM32_VECTOR_H
+
+#include <libopencm3/cm3/common.h>
+
+#ifdef TINYGECKO
+# include <libopencm3/efm32/tinygecko/irq.h>
+#else
+# error "efm32 family not defined."
+#endif
+
+/** Type of an interrupt function. Only used to avoid hard-to-read function
+ * pointers in the efm32_vector_table_t struct. */
+typedef void (*efm32_vector_table_entry_t)(void);
+
+typedef struct {
+ 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;
+ 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[IRQ_COUNT];
+} efm32_vector_table_t;
+
+#endif
diff --git a/include/libopencmsis/core_cm3.h b/include/libopencmsis/core_cm3.h
new file mode 100644
index 0000000..5ad1327
--- /dev/null
+++ b/include/libopencmsis/core_cm3.h
@@ -0,0 +1,201 @@
+/* big fat FIXME: this should use a consistent structure, and reference
+ * functionality from libopencm3 instead of copypasting.
+ *
+ * particularly unimplemented features are FIXME'd extra
+ * */
+
+#ifndef OPENCMSIS_CORECM3_H
+#define OPENCMSIS_CORECM3_H
+
+/* needed in various places where we rather should include libopencm3 functionality */
+#define MMIO32(addr) (*(volatile uint32_t *)(addr))
+
+/* the original core_cm3.h is nonfree by arm; this provides libopencm3 variant of the symbols efm32lib needs of CMSIS. */
+#include <stdint.h>
+
+/* needed by system_efm32.h:196, guessing */
+#define __INLINE inline
+/* new since emlib 3.0 */
+#define __STATIC_INLINE static inline
+
+/* needed around efm32tg840f32.h:229. comparing the efm32lib definitions to the
+ * libopencm3 ones, "volatile" is all that's missing. */
+#define __IO volatile
+#define __O volatile
+#define __I volatile
+
+/* -> style access for what is defined in libopencm3/stm32/f1/scb.h /
+ * cm3/memorymap.h, as it's needed by efm32lib/inc/efm32_emu.h */
+
+/* from stm32/f1/scb.h */
+#define SCB_SCR_SLEEPDEEP_Msk (1 << 2)
+/* structure as in, for example,
+ * DeviceSupport/EnergyMicro/EFM32/efm32tg840f32.h, data from
+ * libopencm3/stm32/f1/scb.h. FIXME incomplete. */
+typedef struct
+{
+ __IO uint32_t CPUID;
+ __IO uint32_t ICSR;
+ __IO uint32_t VTOR;
+ __IO uint32_t AIRCR;
+ __IO uint32_t SCR;
+ __IO uint32_t CCR;
+ __IO uint8_t SHPR[12]; /* FIXME: how is this properly indexed? */
+ __IO uint32_t SHCSR;
+} SCB_TypeDef;
+#define SCB ((SCB_TypeDef *) SCB_BASE)
+/* from libopencm3/cm3/memorymap.h */
+#define PPBI_BASE 0xE0000000
+#define SCS_BASE (PPBI_BASE + 0xE000)
+#define SCB_BASE (SCS_BASE + 0x0D00)
+
+/* needed by efm32_emu.h, guessing and taking the implementation used in
+ * lightswitch-interrupt.c */
+#define __WFI() __asm__("wfi")
+
+/* needed by efm32_cmu.h, probably it's just what gcc provides anyway */
+#define __CLZ(div) __builtin_clz(div)
+
+/* needed by efm32_aes.c. __builtin_bswap32 does the same thing as the rev instruction according to https://bugzilla.mozilla.org/show_bug.cgi?id=600106 */
+#define __REV(x) __builtin_bswap32(x)
+
+/* stubs for efm32_dbg.h */
+typedef struct
+{
+ uint32_t DHCSR;
+ uint32_t DEMCR; /* needed by efm32tg stk trace.c */
+} CoreDebug_TypeDef;
+/* FIXME let's just hope writes to flash are protected */
+#define CoreDebug ((CoreDebug_TypeDef *) 0)
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk 0
+#define CoreDebug_DEMCR_TRCENA_Msk 0
+
+/* stubs for efm32_dma */
+
+/* also used by the clock example. code taken from stm32's nvic.[hc], FIXME until
+ * the generic cm3 functionality is moved out from stm32 and can be used here
+ * easily (nvic_clear_pending_irq, nvic_enable_irq, nvic_disable_irq). */
+#define NVIC_BASE (SCS_BASE + 0x0100)
+#define NVIC_ISER(iser_id) MMIO32(NVIC_BASE + 0x00 + (iser_id * 4))
+#define NVIC_ICER(icer_id) MMIO32(NVIC_BASE + 0x80 + (icer_id * 4))
+#define NVIC_ICPR(icpr_id) MMIO32(NVIC_BASE + 0x180 + (icpr_id * 4))
+static inline void NVIC_ClearPendingIRQ(uint8_t irqn)
+{
+ NVIC_ICPR(irqn / 32) = (1 << (irqn % 32));
+}
+static inline void NVIC_EnableIRQ(uint8_t irqn)
+{
+ NVIC_ISER(irqn / 32) = (1 << (irqn % 32));
+}
+static inline void NVIC_DisableIRQ(uint8_t irqn)
+{
+ NVIC_ICER(irqn / 32) = (1 << (irqn % 32));
+}
+
+/* stubs for efm32_int. FIXME: how do they do that? nvic documentation in the
+ * efm32 core manual doesn't tell anything of a global on/off switch */
+
+#define __enable_irq() 1
+#define __disable_irq() 1
+
+/* stubs for efm32_mpu FIXME */
+
+#define SCB_SHCSR_MEMFAULTENA_Msk 0
+
+typedef struct
+{
+ uint32_t CTRL;
+ uint32_t RNR;
+ uint32_t RBAR;
+ uint32_t RASR;
+} MPU_TypeDef;
+/* FIXME struct at NULL */
+#define MPU ((MPU_TypeDef *) 0)
+#define MPU_CTRL_ENABLE_Msk 0
+#define MPU_RASR_XN_Pos 0
+#define MPU_RASR_AP_Pos 0
+#define MPU_RASR_TEX_Pos 0
+#define MPU_RASR_S_Pos 0
+#define MPU_RASR_C_Pos 0
+#define MPU_RASR_B_Pos 0
+#define MPU_RASR_SRD_Pos 0
+#define MPU_RASR_SIZE_Pos 0
+#define MPU_RASR_ENABLE_Pos 0
+
+/* required for the blink example */
+
+/* if if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1) ;
+ * configures the sys ticks to 1ms, then the argument to SysTick_Config
+ * describes how many cycles to wait between two systicks.
+ *
+ * the endless loop part looks like an "if it returns an error condition,
+ * rather loop here than continue"; every other solution would involve things
+ * that are dark magic to my understanding.
+ *
+ * implementation more or less copypasted from lib/stm32/systick.c, FIXME until
+ * the generic cm3 functionality is moved out from stm32 and can be used here
+ * easily (systick_set_reload, systick_interrupt_enable, systick_counter_enable
+ * and systick_set_clocksource).
+ *
+ * modified for CMSIS style array as the powertest example needs it.
+ * */
+#define SYS_TICK_BASE (SCS_BASE + 0x0010)
+
+/* from d0002_efm32_cortex-m3_reference_manual.pdf section 4.4 */
+typedef struct
+{
+ uint32_t CTRL;
+ uint32_t LOAD;
+ uint32_t VAL;
+ uint32_t CALIB;
+} SysTick_TypeDef;
+#define SysTick ((SysTick_TypeDef *) SYS_TICK_BASE)
+
+#define STK_CTRL_TICKINT (1 << 1)
+#define STK_CTRL_ENABLE (1 << 0)
+
+#define STK_CTRL_CLKSOURCE_LSB 2
+#define STK_CTRL_CLKSOURCE_AHB 1
+static inline uint32_t SysTick_Config(uint32_t n_ticks)
+{
+ if (n_ticks & ~0x00FFFFFF) return 1;
+ SysTick->LOAD = n_ticks;
+
+ SysTick->CTRL |= (STK_CTRL_CLKSOURCE_AHB << STK_CTRL_CLKSOURCE_LSB);
+
+ SysTick->CTRL |= STK_CTRL_TICKINT;
+
+ SysTick->CTRL |= STK_CTRL_ENABLE;
+
+ return 0;
+}
+
+/* stubs for efm32tg stk trace.c */
+typedef struct
+{
+ uint32_t LAR;
+ uint32_t TCR;
+} ITM_TypeDef;
+/* FIXME struct at NULL */
+#define ITM ((ITM_TypeDef *) 0)
+
+/* blink.h expects the isr for systicks to be named SysTick_Handler. with this,
+ * its Systick_Handler function gets renamed to the weak symbol exported by
+ * vector.c */
+#define SysTick_Handler sys_tick_handler
+
+/* likewise, clock.c defines GPIO_ODD_IRQHandler and GPIO_EVEN_IRQHandler */
+#define GPIO_ODD_IRQHandler gpio_odd_isr
+#define GPIO_EVEN_IRQHandler gpio_even_isr
+#define RTC_IRQHandler rtc_isr
+
+/* for inttemp (i should really get a list and convert them all) */
+
+#define ADC0_IRQHandler adc0_isr
+
+/* for the lightsense example */
+
+#define LESENSE_IRQHandler lesense_isr
+#define PCNT0_IRQHandler pcnt0_isr
+
+#endif
diff --git a/lib/efm32/tinygecko/EFM32TG840F32.ld b/lib/efm32/tinygecko/EFM32TG840F32.ld
new file mode 100644
index 0000000..f7baa90
--- /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 0000000..b910509
--- /dev/null
+++ b/lib/efm32/tinygecko/Makefile
@@ -0,0 +1,60 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library 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 Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+LIBNAME = libopencm3_efm32tinygecko
+FAMILY = TINYGECKO
+
+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 -D$(FAMILY)
+# ARFLAGS = rcsv
+ARFLAGS = rcs
+OBJS = vector.o devicerevision.o gpio.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 0000000..0af3e90
--- /dev/null
+++ b/lib/efm32/tinygecko/devicerevision.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/efm32/tinygecko/devicerevision.h>
+
+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/gpio.c b/lib/efm32/tinygecko/gpio.c
new file mode 100644
index 0000000..839d1b8
--- /dev/null
+++ b/lib/efm32/tinygecko/gpio.c
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/efm32/tinygecko/gpio.h>
+
+void gpio_set_mode(u32 gpioport, u8 mode, u16 gpios)
+{
+ u8 i;
+ u32 modemaskl = 0, modesetl = 0, modemaskh = 0, modeseth = 0;
+
+ for (i = 0; i < 8; ++i)
+ {
+ if (gpios & (1<<i)) {
+ modemaskl |= GPIO_MODE_MASK << (i*4);
+ modesetl |= mode << (i*4);
+ }
+ if (gpios & (0x100<<i)) {
+ modemaskh |= GPIO_MODE_MASK << (i*4);
+ modeseth |= mode << (i*4);
+ }
+ }
+ GPIO_Px_MODEL(gpioport) &= ~modemaskl;
+ GPIO_Px_MODEL(gpioport) |= modesetl;
+ GPIO_Px_MODEH(gpioport) &= ~modemaskh;
+ GPIO_Px_MODEH(gpioport) |= modeseth;
+}
diff --git a/lib/efm32/tinygecko/tinygecko.ld b/lib/efm32/tinygecko/tinygecko.ld
new file mode 100644
index 0000000..92f4282
--- /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 <uwe@hermann-uwe.de>,
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* 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 0000000..264426b
--- /dev/null
+++ b/lib/efm32/tinygecko/vector.c
@@ -0,0 +1,159 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>,
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/efm32/tinygecko/irq.h>
+#include <libopencm3/efm32/vector.h>
+
+#define WEAK __attribute__ ((weak))
+
+/* Symbols exported by the linker script(s). */
+extern unsigned _etext, _data, _edata, _ebss, _stack;
+
+void main(void);
+void blocking_handler(void);
+
+void WEAK reset_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);
+
+void WEAK dma_isr(void);
+void WEAK gpio_even_isr(void);
+void WEAK timer0_isr(void);
+void WEAK usart0_rx_isr(void);
+void WEAK usart0_tx_isr(void);
+void WEAK acmp01_isr(void);
+void WEAK adc0_isr(void);
+void WEAK dac0_isr(void);
+void WEAK i2c0_isr(void);
+void WEAK gpio_odd_isr(void);
+void WEAK timer1_isr(void);
+void WEAK usart1_rx_isr(void);
+void WEAK usart1_tx_isr(void);
+void WEAK lesense_isr(void);
+void WEAK leuart0_isr(void);
+void WEAK letimer0_isr(void);
+void WEAK pcnt0_isr(void);
+void WEAK rtc_isr(void);
+void WEAK cmu_isr(void);
+void WEAK vcmp_isr(void);
+void WEAK lcd_isr(void);
+void WEAK msc_isr(void);
+void WEAK aes_isr(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,
+ .irq = {
+ [IRQ_DMA] = dma_isr,
+ [IRQ_GPIO_EVEN] = gpio_even_isr,
+ [IRQ_TIMER0] = timer0_isr,
+ [IRQ_USART0_RX] = usart0_rx_isr,
+ [IRQ_USART0_TX] = usart0_tx_isr,
+ [IRQ_ACMP01] = acmp01_isr,
+ [IRQ_ADC0] = adc0_isr,
+ [IRQ_DAC0] = dac0_isr,
+ [IRQ_I2C0] = i2c0_isr,
+ [IRQ_GPIO_ODD] = gpio_odd_isr,
+ [IRQ_TIMER1] = timer1_isr,
+ [IRQ_USART1_RX] = usart1_rx_isr,
+ [IRQ_USART1_TX] = usart1_tx_isr,
+ [IRQ_LESENSE] = lesense_isr,
+ [IRQ_LEUART0] = leuart0_isr,
+ [IRQ_LETIMER0] = letimer0_isr,
+ [IRQ_PCNT0] = pcnt0_isr,
+ [IRQ_RTC] = rtc_isr,
+ [IRQ_CMU] = cmu_isr,
+ [IRQ_VCMP] = vcmp_isr,
+ [IRQ_LCD] = lcd_isr,
+ [IRQ_MSC] = msc_isr,
+ [IRQ_AES] = aes_isr,
+ }
+};
+
+void WEAK 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) ;
+}
+
+#pragma weak nmi_handler = blocking_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 = blocking_handler
+#pragma weak debug_monitor_handler = blocking_handler
+#pragma weak pend_sv_handler = blocking_handler
+#pragma weak sys_tick_handler = blocking_handler
+
+#pragma weak dma_isr = blocking_handler
+#pragma weak gpio_even_isr = blocking_handler
+#pragma weak timer0_isr = blocking_handler
+#pragma weak usart0_rx_isr = blocking_handler
+#pragma weak usart0_tx_isr = blocking_handler
+#pragma weak acmp01_isr = blocking_handler
+#pragma weak adc0_isr = blocking_handler
+#pragma weak dac0_isr = blocking_handler
+#pragma weak i2c0_isr = blocking_handler
+#pragma weak gpio_odd_isr = blocking_handler
+#pragma weak timer1_isr = blocking_handler
+#pragma weak usart1_rx_isr = blocking_handler
+#pragma weak usart1_tx_isr = blocking_handler
+#pragma weak lesense_isr = blocking_handler
+#pragma weak leuart0_isr = blocking_handler
+#pragma weak letimer0_isr = blocking_handler
+#pragma weak pcnt0_isr = blocking_handler
+#pragma weak rtc_isr = blocking_handler
+#pragma weak cmu_isr = blocking_handler
+#pragma weak vcmp_isr = blocking_handler
+#pragma weak lcd_isr = blocking_handler
+#pragma weak msc_isr = blocking_handler
+#pragma weak aes_isr = blocking_handler