aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Ciesielski2012-11-13 11:06:21 -0800
committerJeff Ciesielski2012-11-13 13:13:40 -0800
commitdb35fbb7ba97a8a6d7481edf07cb82cae06aa834 (patch)
treec213211778736d5ce2f06b4cf186a6900f522b20
parent1768df7edae1cd430183c03f3d0ad7f7b4d13c90 (diff)
parent4691568ca476177dc338e8c62872ceca6b4b4999 (diff)
Merge branch 'master' of git://github.com/libopencm3/libopencm3 into upstream-merge
-rw-r--r--.gitignore12
-rw-r--r--Makefile56
-rw-r--r--README24
-rw-r--r--doc/Doxyfile_common6
-rw-r--r--examples/lm3s/Makefile.include2
-rw-r--r--examples/lpc13xx/Makefile.include2
-rw-r--r--examples/lpc17xx/Makefile.include2
-rw-r--r--examples/lpc43xx/Makefile.include2
-rw-r--r--examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c4
-rw-r--r--examples/stm32/f1/Makefile.include21
-rw-r--r--examples/stm32/f1/lisa-m-1/can/README4
-rw-r--r--examples/stm32/f1/lisa-m-1/can/can.c16
-rw-r--r--examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c28
-rw-r--r--examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c20
-rw-r--r--examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c33
-rw-r--r--examples/stm32/f1/lisa-m-2/adc_injec/Makefile1
-rw-r--r--examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile1
-rw-r--r--examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile1
-rw-r--r--examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c2
-rw-r--r--examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile1
-rw-r--r--examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c2
-rw-r--r--examples/stm32/f1/lisa-m-2/adc_regular/Makefile1
-rw-r--r--examples/stm32/f1/lisa-m-2/can/Makefile28
-rw-r--r--examples/stm32/f1/lisa-m-2/can/README4
-rw-r--r--examples/stm32/f1/lisa-m-2/can/can.c234
-rw-r--r--examples/stm32/f1/lisa-m-2/fancyblink/Makefile3
-rw-r--r--examples/stm32/f1/lisa-m-2/usart/Makefile3
-rw-r--r--examples/stm32/f1/lisa-m-2/usart_dma/Makefile3
-rw-r--r--examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c2
-rw-r--r--examples/stm32/f1/lisa-m-2/usart_irq/Makefile3
-rw-r--r--examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c2
-rw-r--r--examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile3
-rw-r--r--examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c4
-rw-r--r--examples/stm32/f1/lisa-m-2/usart_printf/Makefile3
-rw-r--r--examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c2
-rw-r--r--examples/stm32/f1/obldc-strip/can/Makefile25
-rw-r--r--examples/stm32/f1/obldc-strip/can/README4
-rw-r--r--examples/stm32/f1/obldc-strip/can/can.c202
-rw-r--r--examples/stm32/f1/obldc-strip/led/Makefile25
-rw-r--r--examples/stm32/f1/obldc-strip/led/led.c65
-rw-r--r--examples/stm32/f1/obldc-strip/obldc-strip.ld (renamed from lib/stm32/f2/scb.c)20
-rw-r--r--examples/stm32/f1/obldc-strip/systick/Makefile25
-rw-r--r--examples/stm32/f1/obldc-strip/systick/systick.c81
-rw-r--r--examples/stm32/f1/obldc/can/can.c4
-rw-r--r--examples/stm32/f1/obldc/systick/systick.c4
-rw-r--r--examples/stm32/f1/obldc/usart_irq/usart_irq.c2
-rw-r--r--examples/stm32/f1/other/dogm128/main.c2
-rw-r--r--examples/stm32/f1/other/rtc/rtc.c2
-rw-r--r--examples/stm32/f1/other/systick/systick.c4
-rw-r--r--examples/stm32/f1/other/timer_interrupt/timer.c2
-rw-r--r--examples/stm32/f1/other/usb_cdcacm/cdcacm.c28
-rw-r--r--examples/stm32/f1/other/usb_dfu/usbdfu.c20
-rw-r--r--examples/stm32/f1/other/usb_hid/usbhid.c34
-rw-r--r--examples/stm32/f1/stm32-h103/button/button.c2
-rw-r--r--examples/stm32/f1/stm32-h103/exti_both/exti_both.c2
-rw-r--r--examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c2
-rw-r--r--examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c2
-rw-r--r--examples/stm32/f1/stm32-h103/timer/timer.c2
-rw-r--r--examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c2
-rw-r--r--examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c4
-rw-r--r--examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c2
-rw-r--r--examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c36
-rw-r--r--examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c24
-rw-r--r--examples/stm32/f1/stm32-h103/usb_hid/usbhid.c36
-rw-r--r--examples/stm32/f1/stm32-h103/usb_iap/usbiap.c24
-rw-r--r--examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c14
-rw-r--r--examples/stm32/f1/stm32vl-discovery/rtc/rtc.c2
-rw-r--r--examples/stm32/f2/jobygps/spi_test/spi_test.c2
-rw-r--r--examples/stm32/f2/jobygps/usart_printf/usart_printf.c2
-rw-r--r--examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c32
-rw-r--r--examples/stm32/l1/Makefile.include164
-rw-r--r--examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile24
-rw-r--r--examples/stm32/l1/stm32l-discovery/button-irq-printf/README3
-rw-r--r--examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c117
-rw-r--r--examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h45
-rw-r--r--examples/stm32/l1/stm32l-discovery/miniblink/Makefile25
-rw-r--r--examples/stm32/l1/stm32l-discovery/miniblink/README9
-rw-r--r--examples/stm32/l1/stm32l-discovery/miniblink/miniblink.c72
-rw-r--r--examples/stm32/l1/stm32l-discovery/usart/Makefile25
-rw-r--r--examples/stm32/l1/stm32l-discovery/usart/README12
-rw-r--r--examples/stm32/l1/stm32l-discovery/usart/usart.c80
-rw-r--r--include/libopencm3/cm3/nvic.h (renamed from include/libopencm3/stm32/nvic.h)52
-rw-r--r--include/libopencm3/cm3/scb.h (renamed from include/libopencm3/stm32/f4/scb.h)2
-rw-r--r--include/libopencm3/cm3/systick.h (renamed from include/libopencm3/stm32/systick.h)36
-rw-r--r--include/libopencm3/cm3/vector.h64
-rw-r--r--include/libopencm3/dispatch/nvic.h34
-rw-r--r--include/libopencm3/efm32/efm32g/irq.yaml35
-rw-r--r--include/libopencm3/efm32/efm32gg/irq.yaml43
-rw-r--r--include/libopencm3/efm32/efm32lg/irq.yaml43
-rw-r--r--include/libopencm3/efm32/efm32tg/irq.yaml28
-rw-r--r--include/libopencm3/efm32/efm32tg/memorymap.h76
-rw-r--r--include/libopencm3/efm32/memorymap.h37
-rw-r--r--include/libopencm3/lm3s/irq.yaml120
-rw-r--r--include/libopencm3/lpc13xx/irq.yaml62
-rw-r--r--include/libopencm3/lpc17xx/irq.yaml39
-rw-r--r--include/libopencm3/lpc43xx/irq.yaml55
-rw-r--r--include/libopencm3/lpc43xx/nvic.h151
-rw-r--r--include/libopencm3/lpc43xx/systick.h88
-rw-r--r--include/libopencm3/stm32/can.h2
-rw-r--r--include/libopencm3/stm32/desig.h (renamed from include/libopencm3/stm32/f1/desig.h)0
-rw-r--r--include/libopencm3/stm32/exti.h3
-rw-r--r--include/libopencm3/stm32/f1/dma.h59
-rw-r--r--include/libopencm3/stm32/f1/gpio.h12
-rw-r--r--include/libopencm3/stm32/f1/irq.yaml72
-rw-r--r--include/libopencm3/stm32/f1/nvic_f1.h114
-rw-r--r--include/libopencm3/stm32/f1/scb.h307
-rw-r--r--include/libopencm3/stm32/f2/irq.yaml85
-rw-r--r--include/libopencm3/stm32/f2/nvic_f2.h112
-rw-r--r--include/libopencm3/stm32/f2/scb.h307
-rw-r--r--include/libopencm3/stm32/f4/adc.h873
-rw-r--r--include/libopencm3/stm32/f4/dma.h693
-rw-r--r--include/libopencm3/stm32/f4/irq.yaml85
-rw-r--r--include/libopencm3/stm32/f4/nvic_f4.h112
-rw-r--r--include/libopencm3/stm32/f4/syscfg.h46
-rw-r--r--include/libopencm3/stm32/l1/gpio.h241
-rw-r--r--include/libopencm3/stm32/l1/irq.yaml49
-rw-r--r--include/libopencm3/stm32/l1/memorymap.h108
-rw-r--r--include/libopencm3/stm32/l1/rcc.h408
-rw-r--r--include/libopencm3/stm32/memorymap.h2
-rw-r--r--include/libopencm3/stm32/otg_fs.h105
-rw-r--r--include/libopencm3/stm32/otg_hs.h396
-rw-r--r--include/libopencm3/stm32/syscfg.h (renamed from include/libopencm3/stm32/f2/syscfg.h)0
-rw-r--r--include/libopencm3/usb/cdc.h2
-rw-r--r--include/libopencm3/usb/usbd.h67
-rw-r--r--include/libopencm3/usb/usbstd.h3
-rw-r--r--include/libopencmsis/core_cm3.h177
-rw-r--r--include/libopencmsis/dispatch/irqhandlers.h23
-rw-r--r--lib/Makefile.include3
-rw-r--r--lib/cm3/nvic.c (renamed from lib/stm32/nvic.c)62
-rw-r--r--lib/cm3/scb.c (renamed from lib/stm32/f4/scb.c)2
-rw-r--r--lib/cm3/systick.c (renamed from lib/stm32/systick.c)52
-rw-r--r--lib/cm3/vector.c (renamed from lib/lpc17xx/vector.c)52
-rw-r--r--lib/dispatch/vector_chipset.c11
-rw-r--r--lib/dispatch/vector_nvic.c34
-rw-r--r--lib/efm32/efm32g/Makefile38
-rw-r--r--lib/efm32/efm32g/libopencm3_efm32g.ld79
-rw-r--r--lib/efm32/efm32g/libopencm3_efm32g880f128.ld15
-rw-r--r--lib/efm32/efm32gg/Makefile38
-rw-r--r--lib/efm32/efm32gg/libopencm3_efm32gg.ld79
-rw-r--r--lib/efm32/efm32lg/Makefile38
-rw-r--r--lib/efm32/efm32lg/libopencm3_efm32lg.ld79
-rw-r--r--lib/efm32/efm32tg/Makefile38
-rw-r--r--lib/efm32/efm32tg/libopencm3_efm32tg.ld79
-rw-r--r--lib/efm32/efm32tg/libopencm3_efm32tg840f32.ld15
-rw-r--r--lib/lm3s/Makefile2
-rw-r--r--lib/lm3s/vector.c454
-rw-r--r--lib/lpc13xx/Makefile4
-rw-r--r--lib/lpc17xx/Makefile4
-rw-r--r--lib/lpc43xx/Makefile5
-rw-r--r--lib/lpc43xx/nvic.c76
-rw-r--r--lib/lpc43xx/systick.c69
-rw-r--r--lib/lpc43xx/vector.c264
-rw-r--r--lib/lpc43xx/vector_chipset.c48
-rw-r--r--lib/stm32/can.c (renamed from lib/stm32/f1/can.c)13
-rw-r--r--lib/stm32/desig.c (renamed from lib/stm32/f1/desig.c)2
-rw-r--r--lib/stm32/exti2.c (renamed from lib/stm32/f2/exti.c)26
-rw-r--r--lib/stm32/f1/Makefile7
-rw-r--r--lib/stm32/f1/dma.c82
-rw-r--r--lib/stm32/f1/vector.c316
-rw-r--r--lib/stm32/f2/Makefile4
-rw-r--r--lib/stm32/f2/timer.c928
-rw-r--r--lib/stm32/f2/vector.c336
-rw-r--r--lib/stm32/f4/Makefile8
-rw-r--r--lib/stm32/f4/adc.c1027
-rw-r--r--lib/stm32/f4/dma.c772
-rw-r--r--lib/stm32/f4/exti.c146
-rw-r--r--lib/stm32/f4/gpio.c142
-rw-r--r--lib/stm32/f4/timer.c928
-rw-r--r--lib/stm32/f4/vector.c341
-rw-r--r--lib/stm32/f4/vector_chipset.c27
-rw-r--r--lib/stm32/gpio2.c (renamed from lib/stm32/f2/gpio.c)10
-rw-r--r--lib/stm32/l1/Makefile36
-rw-r--r--lib/stm32/l1/libopencm3_stm32l1.ld83
-rw-r--r--lib/stm32/l1/rcc.c357
-rw-r--r--lib/stm32/l1/stm32l15xx8.ld (renamed from lib/stm32/f1/scb.c)20
-rw-r--r--lib/stm32/l1/stm32l15xxb.ld31
-rw-r--r--lib/stm32/timer.c (renamed from lib/stm32/f1/timer.c)43
-rw-r--r--lib/stm32/usart.c2
-rw-r--r--lib/usb/usb.c108
-rw-r--r--lib/usb/usb_control.c196
-rw-r--r--lib/usb/usb_f103.c99
-rw-r--r--lib/usb/usb_f107.c338
-rw-r--r--lib/usb/usb_f207.c91
-rw-r--r--lib/usb/usb_fx07_common.c318
-rw-r--r--lib/usb/usb_fx07_common.h38
-rw-r--r--lib/usb/usb_private.h81
-rw-r--r--lib/usb/usb_standard.c128
-rwxr-xr-xscripts/irq2nvic_h176
188 files changed, 9884 insertions, 6294 deletions
diff --git a/.gitignore b/.gitignore
index 8625d7d..d5d1fd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,14 @@ lib/*.ld
html/
latex/
*.pdf
-
+# These are generated
+include/libopencm3/**/nvic.h
+include/libopencm3/**/**/nvic.h
+lib/**/vector_nvic.c
+lib/**/**/vector_nvic.c
+include/libopencmsis/efm32/
+include/libopencmsis/lm3s/
+include/libopencmsis/lpc13xx/
+include/libopencmsis/lpc17xx/
+include/libopencmsis/lpc43xx/
+include/libopencmsis/stm32/
diff --git a/Makefile b/Makefile
index 492b618..6c060bf 100644
--- a/Makefile
+++ b/Makefile
@@ -19,14 +19,20 @@
PREFIX ?= arm-none-eabi
#PREFIX ?= arm-elf
+
+ifeq ($(DETECT_TOOLCHAIN),)
DESTDIR ?= /usr/local
+else
+DESTDIR ?= $(shell dirname $(shell readlink -f $(shell which $(PREFIX)-gcc)))/..
+endif
+
INCDIR = $(DESTDIR)/$(PREFIX)/include
LIBDIR = $(DESTDIR)/$(PREFIX)/lib
SHAREDIR = $(DESTDIR)/$(PREFIX)/share/libopencm3/scripts
INSTALL = install
SRCLIBDIR = $(shell pwd)/lib
-TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lpc17xx lpc43xx lm3s
+TARGETS = stm32/f1 stm32/f2 stm32/f4 stm32/l1 lpc13xx lpc17xx lpc43xx lm3s efm32/efm32tg efm32/efm32g efm32/efm32lg efm32/efm32gg
# Be silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
@@ -39,41 +45,57 @@ all: build
build: lib examples
-lib:
- $(Q)for i in $(addprefix $@/,$(TARGETS)); do \
- if [ -d $$i ]; then \
- printf " BUILD $$i\n"; \
- $(MAKE) -C $$i SRCLIBDIR=$(SRCLIBDIR) || exit $?; \
- fi; \
+generatedheaders:
+ @printf " UPDATING HEADERS\n"
+ $(Q)for yamlfile in `find . -name 'irq.yaml'`; do \
+ ./scripts/irq2nvic_h $$yamlfile ; \
done
-examples: lib
- $(Q)for i in $(addsuffix /*/*,$(addprefix $@/,$(TARGETS))); do \
- if [ -d $$i ]; then \
- printf " BUILD $$i\n"; \
- $(MAKE) -C $$i || exit $?; \
- fi; \
+cleanheaders:
+ @printf " CLEANING HEADERS\n"
+ $(Q)for yamlfile in `find . -name 'irq.yaml'`; do \
+ ./scripts/irq2nvic_h --remove $$yamlfile ; \
done
+LIB_DIRS:=$(wildcard $(addprefix lib/,$(TARGETS)))
+$(LIB_DIRS): generatedheaders
+ @printf " BUILD $@\n";
+ $(Q)$(MAKE) --directory=$@ SRCLIBDIR=$(SRCLIBDIR)
+
+lib: $(LIB_DIRS)
+ $(Q)true
+
+EXAMPLE_DIRS:=$(sort $(dir $(wildcard $(addsuffix /*/*/Makefile,$(addprefix examples/,$(TARGETS))))))
+$(EXAMPLE_DIRS): lib
+ @printf " BUILD $@\n";
+ $(Q)$(MAKE) --directory=$@
+
+examples: $(EXAMPLE_DIRS)
+ $(Q)true
+
install: lib
@printf " INSTALL headers\n"
$(Q)$(INSTALL) -d $(INCDIR)/libopencm3
+ $(Q)$(INSTALL) -d $(INCDIR)/libopencmsis
$(Q)$(INSTALL) -d $(LIBDIR)
$(Q)$(INSTALL) -d $(SHAREDIR)
$(Q)cp -r include/libopencm3/* $(INCDIR)/libopencm3
+ $(Q)cp -r include/libopencmsis/* $(INCDIR)/libopencmsis
@printf " INSTALL libs\n"
$(Q)$(INSTALL) -m 0644 lib/*.a $(LIBDIR)
@printf " INSTALL ldscripts\n"
$(Q)$(INSTALL) -m 0644 lib/*.ld $(LIBDIR)
+ $(Q)$(INSTALL) -m 0644 lib/efm32/*/*.ld $(LIBDIR)
@printf " INSTALL scripts\n"
$(Q)$(INSTALL) -m 0644 scripts/* $(SHAREDIR)
doc:
$(Q)$(MAKE) -C doc doc
-clean:
- $(Q)for i in $(addprefix lib/,$(TARGETS)) \
- $(addsuffix /*/*,$(addprefix examples/,$(TARGETS))); do \
+# Bleh http://www.makelinux.net/make3/make3-CHP-6-SECT-1#make3-CHP-6-SECT-1
+clean: cleanheaders
+ $(Q)for i in $(LIB_DIRS) \
+ $(EXAMPLE_DIRS); do \
if [ -d $$i ]; then \
printf " CLEAN $$i\n"; \
$(MAKE) -C $$i clean SRCLIBDIR=$(SRCLIBDIR) || exit $?; \
@@ -82,5 +104,5 @@ clean:
@printf " CLEAN doxygen\n"
$(Q)$(MAKE) -C doc clean
-.PHONY: build lib examples install doc clean
+.PHONY: build lib $(LIB_DIRS) examples $(EXAMPLE_DIRS) install doc clean generatedheaders cleanheaders
diff --git a/README b/README
index 488da0f..5d3e064 100644
--- a/README
+++ b/README
@@ -48,7 +48,8 @@ Example projects
The library ships with a few small example projects which illustrate how
individual subsystems of the microcontrollers can be configured and used with
-libopencm3.
+libopencm3. The makefiles are generally useable for your own projects with
+only minimal changes for the libopencm3 install path (See Installation)
For flashing the 'miniblink' example (after you built libopencm3 and the
examples by typing 'make' at the top-level directory) onto the Olimex
@@ -79,16 +80,23 @@ Installation
$ make install
-This will install the library in /usr/local. If you want to install it
-elsewhere, use the following syntax:
+This will install the library into /usr/local. (permissions permitting)
- $ DESTDIR=/opt make install
+If you want to install it elsewhere, use the following syntax:
-The recommended location is to install into your toolchain directory, e.g.
-/home/someuser/sat for a toolchain built using the summon-arm-toolchain
-script from https://github.com/esden/summon-arm-toolchain.
+ $ make DESTDIR=/opt/libopencm3 install
- $ DESTDIR=~/sat make install
+If you want to attempt to install into your toolchain, use this:
+
+ $ make DETECT_TOOLCHAIN=1 install
+
+Note: If you install this into your toolchain, you don't need to pass
+any extra -L or -I flags into your projects. However, this also means
+you must NOT pass any -L or -I flags that point into the toolchain. This
+_will_ confuse the linker. (ie, for summon-arm-toolchain, do NOT pass
+-L/home/user/sat/lib) Common symptoms of confusing
+the linker are hard faults caused by branches into arm code.
+You can use objdump to check for this in your final elf.
Coding style and development guidelines
diff --git a/doc/Doxyfile_common b/doc/Doxyfile_common
index a0e9bf8..8182f1f 100644
--- a/doc/Doxyfile_common
+++ b/doc/Doxyfile_common
@@ -1491,13 +1491,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.
@@ -1525,7 +1525,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/examples/lm3s/Makefile.include b/examples/lm3s/Makefile.include
index f519063..c9bd33c 100644
--- a/examples/lm3s/Makefile.include
+++ b/examples/lm3s/Makefile.include
@@ -37,7 +37,7 @@ endif
endif
CFLAGS += -O0 -g3 -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \
- -mcpu=cortex-m3 -mthumb -MD
+ -mcpu=cortex-m3 -mthumb -MD -DLM3S
LDSCRIPT ?= $(BINARY).ld
LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections
diff --git a/examples/lpc13xx/Makefile.include b/examples/lpc13xx/Makefile.include
index d8aeff0..0b22063 100644
--- a/examples/lpc13xx/Makefile.include
+++ b/examples/lpc13xx/Makefile.include
@@ -37,7 +37,7 @@ endif
endif
CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \
- -mcpu=cortex-m3 -mthumb -MD
+ -mcpu=cortex-m3 -mthumb -MD -DLPC13XX
LDSCRIPT ?= $(BINARY).ld
LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections
diff --git a/examples/lpc17xx/Makefile.include b/examples/lpc17xx/Makefile.include
index 6d7bbfe..9c38a68 100644
--- a/examples/lpc17xx/Makefile.include
+++ b/examples/lpc17xx/Makefile.include
@@ -37,7 +37,7 @@ endif
endif
CFLAGS += -O0 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \
- -mcpu=cortex-m3 -mthumb -MD
+ -mcpu=cortex-m3 -mthumb -MD -DLPC17XX
LDSCRIPT ?= $(BINARY).ld
LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections
diff --git a/examples/lpc43xx/Makefile.include b/examples/lpc43xx/Makefile.include
index 15e523b..cf78538 100644
--- a/examples/lpc43xx/Makefile.include
+++ b/examples/lpc43xx/Makefile.include
@@ -41,7 +41,7 @@ endif
CFLAGS += -O2 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \
-mcpu=cortex-m4 -mthumb -MD \
- -mfloat-abi=hard -mfpu=fpv4-sp-d16
+ -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX
LDSCRIPT ?= $(BINARY).ld
LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections -Xlinker -Map=$(BINARY).map
diff --git a/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c b/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c
index 66c8e06..d38b0bc 100644
--- a/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c
+++ b/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c
@@ -20,8 +20,8 @@
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/cgu.h>
-#include <libopencm3/lpc43xx/nvic.h>
-#include <libopencm3/lpc43xx/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
#include <libopencm3/cm3/scs.h>
#include "../jellybean_conf.h"
diff --git a/examples/stm32/f1/Makefile.include b/examples/stm32/f1/Makefile.include
index 6b87b98..2ae9e27 100644
--- a/examples/stm32/f1/Makefile.include
+++ b/examples/stm32/f1/Makefile.include
@@ -45,6 +45,15 @@ LDFLAGS += --static -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group \
-L$(TOOLCHAIN_DIR)/lib \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
$(ARCH_FLAGS) -mfix-cortex-m3-ldrd
+
+ifneq ($(OPENCM3_DIR),)
+CFLAGS += -I$(OPENCM3_DIR)/include
+LDFLAGS += -L$(OPENCM3_DIR)/lib -L$(OPENCM3_DIR)/lib/stm32/f1
+SCRIPT_DIR = $(OPENCM3_DIR)/share
+else
+SCRIPT_DIR = $(shell dirname $(shell readlink -f $(shell which $(PREFIX)-gcc)))/../$(PREFIX)/share
+endif
+
OBJS += $(BINARY).o
OOCD ?= openocd
@@ -53,6 +62,9 @@ OOCD_BOARD ?= olimex_stm32_h103
# Black magic probe specific variables
# Set the BMP_PORT to a serial port and then BMP is used for flashing
BMP_PORT ?=
+# texane/stlink can be used by uncommenting this...
+# or defining it in your own makefiles
+#STLINK_PORT ?= :4242
# Be silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
@@ -107,6 +119,7 @@ clean:
$(Q)rm -f *.srec
$(Q)rm -f *.list
+ifeq ($(STLINK_PORT),)
ifeq ($(BMP_PORT),)
ifeq ($(OOCD_SERIAL),)
%.flash: %.hex
@@ -140,6 +153,14 @@ else
-x $(TOOLCHAIN_DIR)/scripts/black_magic_probe_flash.scr \
$(*).elf
endif
+else
+%.flash: %.elf
+ @echo " GDB $(*).elf (flash)"
+ $(Q)$(GDB) --batch \
+ -ex 'target extended-remote $(STLINK_PORT)' \
+ -x $(SCRIPT_DIR)/libopencm3/scripts/stlink_flash.scr \
+ $(*).elf
+endif
.PHONY: images clean
diff --git a/examples/stm32/f1/lisa-m-1/can/README b/examples/stm32/f1/lisa-m-1/can/README
new file mode 100644
index 0000000..3a14e3b
--- /dev/null
+++ b/examples/stm32/f1/lisa-m-1/can/README
@@ -0,0 +1,4 @@
+This test sets up the CAN interface on Lisa/M and transmits 8 bites every
+100ms. The first byte is being incremented in each cycle. The demo also
+receives messages and is displaing the first 4 bits of the first byte on the
+board LEDs.
diff --git a/examples/stm32/f1/lisa-m-1/can/can.c b/examples/stm32/f1/lisa-m-1/can/can.c
index 2630905..463d7fc 100644
--- a/examples/stm32/f1/lisa-m-1/can/can.c
+++ b/examples/stm32/f1/lisa-m-1/can/can.c
@@ -21,8 +21,8 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/nvic.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/can.h>
struct can_tx_msg {
@@ -106,15 +106,15 @@ void can_setup(void)
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CANEN);
- AFIO_MAPR = AFIO_MAPR_CAN1_REMAP_PORTB;
+ AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB;
/* Configure CAN pin: RX (input pull-up). */
- gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
+ gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX);
gpio_set(GPIOB, GPIO_CAN1_PB_RX);
/* Configure CAN pin: TX. */
- gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
+ gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX);
/* NVIC setup. */
@@ -167,8 +167,10 @@ void sys_tick_handler(void)
static int temp32 = 0;
static u8 data[8] = {0, 1, 2, 0, 0, 0, 0, 0};
- /* We call this handler every 1ms so 1000ms = 1s on/off. */
- if (++temp32 != 1000)
+ /* We call this handler every 1ms so 100ms = 1s
+ * Resulting in 100Hz message frequency.
+ */
+ if (++temp32 != 100)
return;
temp32 = 0;
diff --git a/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c b/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c
index 7ef9b62..08efa46 100644
--- a/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c
+++ b/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c
@@ -164,11 +164,12 @@ static const char *usb_strings[] = {
"DEMO",
};
-static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)complete;
(void)buf;
+ (void)usbd_dev;
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
@@ -200,15 +201,15 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
return 0;
}
-static void cdcacm_data_rx_cb(u8 ep)
+static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep)
{
(void)ep;
char buf[64];
- int len = usbd_ep_read_packet(0x01, buf, 64);
+ int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
if (len) {
- while (usbd_ep_write_packet(0x82, buf, len) == 0)
+ while (usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0)
;
buf[len] = 0;
}
@@ -216,15 +217,16 @@ static void cdcacm_data_rx_cb(u8 ep)
gpio_toggle(GPIOC, GPIO5);
}
-static void cdcacm_set_config(u16 wValue)
+static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue)
{
(void)wValue;
- usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
- usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
- usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
+ usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
+ usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
+ usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
cdcacm_control_request);
@@ -234,6 +236,8 @@ int main(void)
{
int i;
+ usbd_device *usbd_dev;
+
rcc_clock_setup_in_hsi_out_48mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
@@ -246,13 +250,13 @@ int main(void)
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO5);
- usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
- usbd_register_set_config_callback(cdcacm_set_config);
+ usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
+ usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
for (i = 0; i < 0x800000; i++)
__asm__("nop");
gpio_clear(GPIOC, GPIO2);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
diff --git a/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c b/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c
index 4ffc0a1..137beba 100644
--- a/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c
+++ b/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c
@@ -21,7 +21,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/f1/flash.h>
-#include <libopencm3/stm32/f1/scb.h>
+#include <libopencm3/cm3/scb.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/dfu.h>
@@ -130,10 +130,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout)
}
}
-static void usbdfu_getstatus_complete(struct usb_setup_data *req)
+static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
{
int i;
(void)req;
+ (void)usbd_dev;
switch (usbdfu_state) {
case STATE_DFU_DNBUSY:
@@ -166,9 +167,11 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
}
}
-static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
+ (void)usbd_dev;
+
if ((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request. */
@@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
int main(void)
{
+ usbd_device *usbd_dev;
+
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
if (!gpio_get(GPIOA, GPIO10)) {
@@ -245,9 +250,10 @@ int main(void)
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO2);
- usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
- usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
+ usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
+ usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer));
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
usbdfu_control_request);
@@ -255,5 +261,5 @@ int main(void)
gpio_clear(GPIOC, GPIO2);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
diff --git a/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c b/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c
index 8d83896..2863674 100644
--- a/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c
+++ b/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/otg_fs.h>
#include <libopencm3/usb/usbd.h>
@@ -32,10 +32,12 @@
#define INCLUDE_DFU_INTERFACE
#ifdef INCLUDE_DFU_INTERFACE
-#include <libopencm3/stm32/f1/scb.h>
+#include <libopencm3/cm3/scb.h>
#include <libopencm3/usb/dfu.h>
#endif
+static usbd_device *usbd_dev;
+
const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
@@ -173,10 +175,11 @@ static const char *usb_strings[] = {
"DEMO",
};
-static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
+static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len,
+ void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)complete;
+ (void)usbd_dev;
if((req->bmRequestType != 0x81) ||
(req->bRequest != USB_REQ_GET_DESCRIPTOR) ||
@@ -191,9 +194,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
}
#ifdef INCLUDE_DFU_INTERFACE
-static void dfu_detach_complete(struct usb_setup_data *req)
+static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
{
(void)req;
+ (void)usbd_dev;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
@@ -202,11 +206,12 @@ static void dfu_detach_complete(struct usb_setup_data *req)
scb_reset_core();
}
-static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
+static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len,
+ void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)buf;
(void)len;
+ (void)usbd_dev;
if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH))
return 0; /* Only accept class request. */
@@ -217,18 +222,20 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
}
#endif
-static void hid_set_config(u16 wValue)
+static void hid_set_config(usbd_device *usbd_dev, u16 wValue)
{
(void)wValue;
- usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
+ usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
hid_control_request);
#ifdef INCLUDE_DFU_INTERFACE
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
dfu_control_request);
@@ -329,8 +336,8 @@ int main(void)
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO2);
- usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
- usbd_register_set_config_callback(hid_set_config);
+ usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
+ usbd_register_set_config_callback(usbd_dev, hid_set_config);
/* Delay some seconds to show that pull-up switch works. */
for (i = 0; i < 0x800000; i++)
@@ -345,7 +352,7 @@ int main(void)
// OTG_FS_GCCFG &= ~OTG_FS_GCCFG_VBUSBSEN;
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
void sys_tick_handler(void)
@@ -357,5 +364,5 @@ void sys_tick_handler(void)
buf[1] = x >> 9;
buf[2] = y >> 9;
- usbd_ep_write_packet(0x81, buf, 4);
+ usbd_ep_write_packet(usbd_dev, 0x81, buf, 4);
}
diff --git a/examples/stm32/f1/lisa-m-2/adc_injec/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec/Makefile
index e50737b..666c393 100644
--- a/examples/stm32/f1/lisa-m-2/adc_injec/Makefile
+++ b/examples/stm32/f1/lisa-m-2/adc_injec/Makefile
@@ -18,6 +18,7 @@
##
BINARY = adc_injec
+
# Comment the following line if you _don't_ have luftboot flashed!
LDFLAGS += -Wl,-Ttext=0x8002000
CFLAGS += -std=c99
diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile
index af2e9e6..72eab49 100644
--- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile
+++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile
@@ -18,6 +18,7 @@
##
BINARY = adc_injec_timtrig
+
# Comment the following line if you _don't_ have luftboot flashed!
LDFLAGS += -Wl,-Ttext=0x8002000
CFLAGS += -std=c99
diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile
index c88152e..8ad47e2 100644
--- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile
+++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile
@@ -18,6 +18,7 @@
##
BINARY = adc_injec_timtrig_irq
+
# Comment the following line if you _don't_ have luftboot flashed!
LDFLAGS += -Wl,-Ttext=0x8002000
CFLAGS += -std=c99
diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c
index bda1d9d..674343d 100644
--- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c
+++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c
@@ -25,7 +25,7 @@
#include <libopencm3/stm32/f1/adc.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/timer.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
volatile u16 temperature = 0;
diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile
index d9a74a2..a3cccec 100644
--- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile
+++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile
@@ -18,6 +18,7 @@
##
BINARY = adc_injec_timtrig_irq_4ch
+
# Comment the following line if you _don't_ have luftboot flashed!
LDFLAGS += -Wl,-Ttext=0x8002000
CFLAGS += -std=c99
diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c
index 1334184..cbff97d 100644
--- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c
+++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c
@@ -25,7 +25,7 @@
#include <libopencm3/stm32/f1/adc.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/timer.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
volatile u16 temperature = 0;
volatile u16 v_refint = 0;
diff --git a/examples/stm32/f1/lisa-m-2/adc_regular/Makefile b/examples/stm32/f1/lisa-m-2/adc_regular/Makefile
index 20355ce..b61587f 100644
--- a/examples/stm32/f1/lisa-m-2/adc_regular/Makefile
+++ b/examples/stm32/f1/lisa-m-2/adc_regular/Makefile
@@ -18,6 +18,7 @@
##
BINARY = adc
+
# Comment the following line if you _don't_ have luftboot flashed!
LDFLAGS += -Wl,-Ttext=0x8002000
CFLAGS += -std=c99
diff --git a/examples/stm32/f1/lisa-m-2/can/Makefile b/examples/stm32/f1/lisa-m-2/can/Makefile
new file mode 100644
index 0000000..71a787a
--- /dev/null
+++ b/examples/stm32/f1/lisa-m-2/can/Makefile
@@ -0,0 +1,28 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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 = can
+
+# Comment the following line if you _don't_ have luftboot flashed!
+LDFLAGS += -Wl,-Ttext=0x8002000
+CFLAGS += -std=c99
+LDSCRIPT = ../lisa-m.ld
+
+include ../../Makefile.include
+
diff --git a/examples/stm32/f1/lisa-m-2/can/README b/examples/stm32/f1/lisa-m-2/can/README
new file mode 100644
index 0000000..3a14e3b
--- /dev/null
+++ b/examples/stm32/f1/lisa-m-2/can/README
@@ -0,0 +1,4 @@
+This test sets up the CAN interface on Lisa/M and transmits 8 bites every
+100ms. The first byte is being incremented in each cycle. The demo also
+receives messages and is displaing the first 4 bits of the first byte on the
+board LEDs.
diff --git a/examples/stm32/f1/lisa-m-2/can/can.c b/examples/stm32/f1/lisa-m-2/can/can.c
new file mode 100644
index 0000000..dd673ba
--- /dev/null
+++ b/examples/stm32/f1/lisa-m-2/can/can.c
@@ -0,0 +1,234 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
+ * Copyright (C) 2010-2011 Piotr Esden-Tempski <piotr@esden.net>
+ *
+ * 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/stm32/f1/rcc.h>
+#include <libopencm3/stm32/f1/flash.h>
+#include <libopencm3/stm32/f1/gpio.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
+#include <libopencm3/stm32/can.h>
+
+struct can_tx_msg {
+ u32 std_id;
+ u32 ext_id;
+ u8 ide;
+ u8 rtr;
+ u8 dlc;
+ u8 data[8];
+};
+
+struct can_rx_msg {
+ u32 std_id;
+ u32 ext_id;
+ u8 ide;
+ u8 rtr;
+ u8 dlc;
+ u8 data[8];
+ u8 fmi;
+};
+
+struct can_tx_msg can_tx_msg;
+struct can_rx_msg can_rx_msg;
+
+void gpio_setup(void)
+{
+ /* Enable Alternate Function clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
+
+ /* Enable GPIOA clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
+
+ /* Enable GPIOB clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
+
+ /* Enable GPIOC clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
+
+ /* Preconfigure LEDs. */
+ gpio_set(GPIOA, GPIO8); /* LED1 off */
+ gpio_set(GPIOB, GPIO4); /* LED2 off */
+ gpio_set(GPIOC, GPIO2); /* LED3 off */
+ gpio_set(GPIOC, GPIO5); /* LED4 off */
+ gpio_set(GPIOC, GPIO15); /* LED5 off */
+
+ /* Configure LED GPIOOs. */
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO8);
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO4);
+ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO2);
+ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO5);
+ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
+
+ /* Configure PB4 as GPIO. */
+ AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST;
+
+}
+
+void systick_setup(void)
+{
+ /* 72MHz / 8 => 9000000 counts per second */
+ systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
+
+ /* 9000000/9000 = 1000 overflows per second - every 1ms one interrupt */
+ systick_set_reload(9000);
+
+ systick_interrupt_enable();
+
+ /* Start counting. */
+ systick_counter_enable();
+}
+
+void can_setup(void)
+{
+ /* Enable peripheral clocks. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
+ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CAN1EN);
+
+ AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB;
+
+ /* Configure CAN pin: RX (input pull-up). */
+ gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT,
+ GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX);
+ gpio_set(GPIO_BANK_CAN1_PB_RX, GPIO_CAN1_PB_RX);
+
+ /* Configure CAN pin: TX. */
+ gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX);
+
+ /* NVIC setup. */
+ nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);
+ nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1);
+
+ /* Reset CAN. */
+ can_reset(CAN1);
+
+ /* CAN cell init. */
+ if (can_init(CAN1,
+ false, /* TTCM: Time triggered comm mode? */
+ true, /* ABOM: Automatic bus-off management? */
+ false, /* AWUM: Automatic wakeup mode? */
+ false, /* NART: No automatic retransmission? */
+ false, /* RFLM: Receive FIFO locked mode? */
+ false, /* TXFP: Transmit FIFO priority? */
+ CAN_BTR_SJW_1TQ,
+ CAN_BTR_TS1_3TQ,
+ CAN_BTR_TS2_4TQ,
+ 12)) /* BRP+1: Baud rate prescaler */
+ {
+ gpio_set(GPIOA, GPIO8); /* LED1 off */
+ gpio_set(GPIOB, GPIO4); /* LED2 off */
+ gpio_set(GPIOC, GPIO2); /* LED3 off */
+ gpio_clear(GPIOC, GPIO5); /* LED4 on */
+ gpio_set(GPIOC, GPIO15); /* LED5 off */
+
+ /* Die because we failed to initialize. */
+ while (1)
+ __asm__("nop");
+ }
+
+ /* CAN filter 0 init. */
+ can_filter_id_mask_32bit_init(CAN1,
+ 0, /* Filter ID */
+ 0, /* CAN ID */
+ 0, /* CAN ID mask */
+ 0, /* FIFO assignment (here: FIFO0) */
+ true); /* Enable the filter. */
+
+ /* Enable CAN RX interrupt. */
+ can_enable_irq(CAN1, CAN_IER_FMPIE0);
+}
+
+void sys_tick_handler(void)
+{
+ static int temp32 = 0;
+ static u8 data[8] = {0, 1, 2, 0, 0, 0, 0, 0};
+
+ /* We call this handler every 1ms so every 100ms = 0.1s
+ * resulting in 100Hz message rate.
+ */
+ if (++temp32 != 100)
+ return;
+
+ temp32 = 0;
+
+ /* Transmit CAN frame. */
+ data[0]++;
+ if (can_transmit(CAN1,
+ 0, /* (EX/ST)ID: CAN ID */
+ false, /* IDE: CAN ID extended? */
+ false, /* RTR: Request transmit? */
+ 8, /* DLC: Data length */
+ data) == -1)
+ {
+ gpio_set(GPIOA, GPIO8); /* LED1 off */
+ gpio_set(GPIOB, GPIO4); /* LED2 off */
+ gpio_set(GPIOC, GPIO2); /* LED3 off */
+ gpio_set(GPIOC, GPIO5); /* LED4 off */
+ gpio_clear(GPIOC, GPIO15); /* LED5 on */
+ }
+}
+
+void usb_lp_can_rx0_isr(void)
+{
+ u32 id, fmi;
+ bool ext, rtr;
+ u8 length, data[8];
+
+ can_receive(CAN1, 0, false, &id, &ext, &rtr, &fmi, &length, data);
+
+ if (data[0] & 1)
+ gpio_clear(GPIOA, GPIO8);
+ else
+ gpio_set(GPIOA, GPIO8);
+
+ if (data[0] & 2)
+ gpio_clear(GPIOB, GPIO4);
+ else
+ gpio_set(GPIOB, GPIO4);
+
+ if (data[0] & 4)
+ gpio_clear(GPIOC, GPIO2);
+ else
+ gpio_set(GPIOC, GPIO2);
+
+ if (data[0] & 8)
+ gpio_clear(GPIOC, GPIO5);
+ else
+ gpio_set(GPIOC, GPIO5);
+
+ can_fifo_release(CAN1, 0);
+}
+
+int main(void)
+{
+ rcc_clock_setup_in_hse_12mhz_out_72mhz();
+ gpio_setup();
+ can_setup();
+ systick_setup();
+
+ while (1); /* Halt. */
+
+ return 0;
+}
diff --git a/examples/stm32/f1/lisa-m-2/fancyblink/Makefile b/examples/stm32/f1/lisa-m-2/fancyblink/Makefile
index e453f84..90ce834 100644
--- a/examples/stm32/f1/lisa-m-2/fancyblink/Makefile
+++ b/examples/stm32/f1/lisa-m-2/fancyblink/Makefile
@@ -19,6 +19,9 @@
BINARY = fancyblink
+# Comment the following line if you _don't_ have luftboot flashed!
+LDFLAGS += -Wl,-Ttext=0x8002000
+CFLAGS += -std=c99
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include
diff --git a/examples/stm32/f1/lisa-m-2/usart/Makefile b/examples/stm32/f1/lisa-m-2/usart/Makefile
index 4ba7e9e..498cd83 100644
--- a/examples/stm32/f1/lisa-m-2/usart/Makefile
+++ b/examples/stm32/f1/lisa-m-2/usart/Makefile
@@ -19,6 +19,9 @@
BINARY = usart
+# Comment the following line if you _don't_ have luftboot flashed!
+LDFLAGS += -Wl,-Ttext=0x8002000
+CFLAGS += -std=c99
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include
diff --git a/examples/stm32/f1/lisa-m-2/usart_dma/Makefile b/examples/stm32/f1/lisa-m-2/usart_dma/Makefile
index 813cda9..5fa5c51 100644
--- a/examples/stm32/f1/lisa-m-2/usart_dma/Makefile
+++ b/examples/stm32/f1/lisa-m-2/usart_dma/Makefile
@@ -19,6 +19,9 @@
BINARY = usart_dma
+# Comment the following line if you _don't_ have luftboot flashed!
+LDFLAGS += -Wl,-Ttext=0x8002000
+CFLAGS += -std=c99
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include
diff --git a/examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c b/examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c
index ac3bb3c..369c539 100644
--- a/examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c
+++ b/examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c
@@ -21,7 +21,7 @@
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/f1/dma.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
void clock_setup(void)
{
diff --git a/examples/stm32/f1/lisa-m-2/usart_irq/Makefile b/examples/stm32/f1/lisa-m-2/usart_irq/Makefile
index 7baa2fe..dbab248 100644
--- a/examples/stm32/f1/lisa-m-2/usart_irq/Makefile
+++ b/examples/stm32/f1/lisa-m-2/usart_irq/Makefile
@@ -19,6 +19,9 @@
BINARY = usart_irq
+# Comment the following line if you _don't_ have luftboot flashed!
+LDFLAGS += -Wl,-Ttext=0x8002000
+CFLAGS += -std=c99
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include
diff --git a/examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c b/examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c
index dbe9140..e5d9e68 100644
--- a/examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c
+++ b/examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c
@@ -20,7 +20,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
void clock_setup(void)
{
diff --git a/examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile b/examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile
index 0b6fd3e..1cc2ed1 100644
--- a/examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile
+++ b/examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile
@@ -19,6 +19,9 @@
BINARY = usart_irq_printf
+# Comment the following line if you _don't_ have luftboot flashed!
+LDFLAGS += -Wl,-Ttext=0x8002000
+CFLAGS += -std=c99
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include
diff --git a/examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c b/examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c
index 6b1096e..dd2e221 100644
--- a/examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c
+++ b/examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c
@@ -21,8 +21,8 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
#include <stdio.h>
#include <errno.h>
diff --git a/examples/stm32/f1/lisa-m-2/usart_printf/Makefile b/examples/stm32/f1/lisa-m-2/usart_printf/Makefile
index 80ac033..6eaf005 100644
--- a/examples/stm32/f1/lisa-m-2/usart_printf/Makefile
+++ b/examples/stm32/f1/lisa-m-2/usart_printf/Makefile
@@ -19,6 +19,9 @@
BINARY = usart_printf
+# Comment the following line if you _don't_ have luftboot flashed!
+LDFLAGS += -Wl,-Ttext=0x8002000
+CFLAGS += -std=c99
LDSCRIPT = ../lisa-m.ld
include ../../Makefile.include
diff --git a/examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c b/examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c
index a66bcbc..bd245ff 100644
--- a/examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c
+++ b/examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c
@@ -21,7 +21,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <stdio.h>
#include <errno.h>
diff --git a/examples/stm32/f1/obldc-strip/can/Makefile b/examples/stm32/f1/obldc-strip/can/Makefile
new file mode 100644
index 0000000..ae14841
--- /dev/null
+++ b/examples/stm32/f1/obldc-strip/can/Makefile
@@ -0,0 +1,25 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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 = can
+
+LDSCRIPT = ../obldc-strip.ld
+
+include ../../Makefile.include
+
diff --git a/examples/stm32/f1/obldc-strip/can/README b/examples/stm32/f1/obldc-strip/can/README
new file mode 100644
index 0000000..3a14e3b
--- /dev/null
+++ b/examples/stm32/f1/obldc-strip/can/README
@@ -0,0 +1,4 @@
+This test sets up the CAN interface on Lisa/M and transmits 8 bites every
+100ms. The first byte is being incremented in each cycle. The demo also
+receives messages and is displaing the first 4 bits of the first byte on the
+board LEDs.
diff --git a/examples/stm32/f1/obldc-strip/can/can.c b/examples/stm32/f1/obldc-strip/can/can.c
new file mode 100644
index 0000000..82473e1
--- /dev/null
+++ b/examples/stm32/f1/obldc-strip/can/can.c
@@ -0,0 +1,202 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net>
+ *
+ * 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/stm32/f1/rcc.h>
+#include <libopencm3/stm32/f1/flash.h>
+#include <libopencm3/stm32/f1/gpio.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
+#include <libopencm3/stm32/can.h>
+
+struct can_tx_msg {
+ u32 std_id;
+ u32 ext_id;
+ u8 ide;
+ u8 rtr;
+ u8 dlc;
+ u8 data[8];
+};
+
+struct can_rx_msg {
+ u32 std_id;
+ u32 ext_id;
+ u8 ide;
+ u8 rtr;
+ u8 dlc;
+ u8 data[8];
+ u8 fmi;
+};
+
+struct can_tx_msg can_tx_msg;
+struct can_rx_msg can_rx_msg;
+
+void gpio_setup(void)
+{
+ /* Enable Alternate Function clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
+
+ /* Enable GPIOB clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
+
+ /* Preconfigure LEDs. */
+ gpio_set(GPIOB, GPIO4); /* LED green off */
+ gpio_set(GPIOB, GPIO5); /* LED red off */
+
+ /* Configure LED GPIOs. */
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO4);
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO5);
+
+ /* Configure PB4 as GPIO. */
+ AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST;
+
+}
+
+void systick_setup(void)
+{
+ /* 64MHz / 8 => 8000000 counts per second */
+ systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
+
+ /* 8000000/8000 = 1000 overflows per second - every 1ms one interrupt */
+ systick_set_reload(8000);
+
+ systick_interrupt_enable();
+
+ /* Start counting. */
+ systick_counter_enable();
+}
+
+void can_setup(void)
+{
+ /* Enable peripheral clocks. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
+ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CAN1EN);
+
+ AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB;
+
+ /* Configure CAN pin: RX (input pull-up). */
+ gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT,
+ GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX);
+ gpio_set(GPIO_BANK_CAN1_PB_RX, GPIO_CAN1_PB_RX);
+
+ /* Configure CAN pin: TX. */
+ gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX);
+
+ /* NVIC setup. */
+ nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);
+ nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1);
+
+ /* Reset CAN. */
+ can_reset(CAN1);
+
+ /* CAN cell init.
+ * Setting the bitrate to 1MBit. APB1 = 32MHz,
+ * prescaler = 2 -> 16MHz time quanta frequency.
+ * 1tq sync + 9tq bit segment1 (TS1) + 6tq bit segment2 (TS2) =
+ * 16time quanto per bit period, therefor 16MHz/16 = 1MHz
+ */
+ if (can_init(CAN1,
+ false, /* TTCM: Time triggered comm mode? */
+ true, /* ABOM: Automatic bus-off management? */
+ false, /* AWUM: Automatic wakeup mode? */
+ false, /* NART: No automatic retransmission? */
+ false, /* RFLM: Receive FIFO locked mode? */
+ false, /* TXFP: Transmit FIFO priority? */
+ CAN_BTR_SJW_1TQ,
+ CAN_BTR_TS1_9TQ,
+ CAN_BTR_TS2_6TQ,
+ 2)) /* BRP+1: Baud rate prescaler */
+ {
+ gpio_clear(GPIOB, GPIO4); /* LED green on */
+ gpio_set(GPIOB, GPIO5); /* LED red off */
+
+ /* Die because we failed to initialize. */
+ while (1)
+ __asm__("nop");
+ }
+
+ /* CAN filter 0 init. */
+ can_filter_id_mask_32bit_init(CAN1,
+ 0, /* Filter ID */
+ 0, /* CAN ID */
+ 0, /* CAN ID mask */
+ 0, /* FIFO assignment (here: FIFO0) */
+ true); /* Enable the filter. */
+
+ /* Enable CAN RX interrupt. */
+ can_enable_irq(CAN1, CAN_IER_FMPIE0);
+}
+
+void sys_tick_handler(void)
+{
+ static u8 data[8] = {0, 1, 2, 0, 0, 0, 0, 0};
+
+ /* We call this handler every 1ms so every 1ms = 0.001s
+ * resulting in 1000Hz message rate.
+ */
+
+ /* Transmit CAN frame. */
+ data[0]++;
+ if (can_transmit(CAN1,
+ 0, /* (EX/ST)ID: CAN ID */
+ false, /* IDE: CAN ID extended? */
+ false, /* RTR: Request transmit? */
+ 8, /* DLC: Data length */
+ data) == -1)
+ {
+ gpio_set(GPIOB, GPIO4); /* LED green off */
+ gpio_clear(GPIOB, GPIO5); /* LED red on */
+ }
+}
+
+void usb_lp_can_rx0_isr(void)
+{
+ u32 id, fmi;
+ bool ext, rtr;
+ u8 length, data[8];
+
+ can_receive(CAN1, 0, false, &id, &ext, &rtr, &fmi, &length, data);
+
+ if (data[0] & 0x40)
+ gpio_clear(GPIOB, GPIO4);
+ else
+ gpio_set(GPIOB, GPIO4);
+
+ if (data[0] & 0x80)
+ gpio_clear(GPIOB, GPIO5);
+ else
+ gpio_set(GPIOB, GPIO5);
+
+ can_fifo_release(CAN1, 0);
+}
+
+int main(void)
+{
+ rcc_clock_setup_in_hsi_out_64mhz();
+ gpio_setup();
+ can_setup();
+ systick_setup();
+
+ while (1); /* Halt. */
+
+ return 0;
+}
diff --git a/examples/stm32/f1/obldc-strip/led/Makefile b/examples/stm32/f1/obldc-strip/led/Makefile
new file mode 100644
index 0000000..f8ff540
--- /dev/null
+++ b/examples/stm32/f1/obldc-strip/led/Makefile
@@ -0,0 +1,25 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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 = led
+
+LDSCRIPT = ../obldc-strip.ld
+
+include ../../Makefile.include
+
diff --git a/examples/stm32/f1/obldc-strip/led/led.c b/examples/stm32/f1/obldc-strip/led/led.c
new file mode 100644
index 0000000..e9fb92f
--- /dev/null
+++ b/examples/stm32/f1/obldc-strip/led/led.c
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net>
+ *
+ * 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/stm32/f1/rcc.h>
+#include <libopencm3/stm32/f1/gpio.h>
+
+void clock_setup(void)
+{
+ /* Set STM32 to 64 MHz. */
+ rcc_clock_setup_in_hsi_out_64mhz();
+
+ /* Enable alternate function peripheral clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
+
+ /* Enable GPIOB clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
+}
+
+void gpio_setup(void)
+{
+
+ /* Configure PB4 as GPIO. */
+ AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST;
+
+ /* Set GPIO4 and 5 (in GPIO port B) to 'output push-pull'. */
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO4 | GPIO5);
+
+}
+
+int main(void)
+{
+ int i;
+
+ clock_setup();
+ gpio_setup();
+
+ /* Blink the LEDs on the board. */
+ while (1) {
+ gpio_toggle(GPIOB, GPIO4); /* LED on/off */
+ for (i = 0; i < 8000000; i++) /* Wait a bit. */
+ __asm__("nop");
+ gpio_toggle(GPIOB, GPIO5); /* LED on/off */
+ for (i = 0; i < 8000000; i++) /* Wait a bit. */
+ __asm__("nop");
+ }
+
+ return 0;
+}
diff --git a/lib/stm32/f2/scb.c b/examples/stm32/f1/obldc-strip/obldc-strip.ld
index abb7b44..9778070 100644
--- a/lib/stm32/f2/scb.c
+++ b/examples/stm32/f1/obldc-strip/obldc-strip.ld
@@ -1,7 +1,7 @@
/*
* This file is part of the libopencm3 project.
*
- * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
*
* 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
@@ -17,19 +17,15 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libopencm3/stm32/f2/scb.h>
+/* Linker script for Open-BLDC (STM32F103CBT6, 128K flash, 20K RAM). */
-void scb_reset_core(void)
+/* Define memory regions. */
+MEMORY
{
- SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_VECTRESET;
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}
-void scb_reset_system(void)
-{
- SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ;
-}
+/* Include the common ld script. */
+INCLUDE libopencm3_stm32f1.ld
-void scb_set_priority_grouping(u32 prigroup)
-{
- SCB_AIRCR = SCB_AIRCR_VECTKEY | prigroup;
-}
diff --git a/examples/stm32/f1/obldc-strip/systick/Makefile b/examples/stm32/f1/obldc-strip/systick/Makefile
new file mode 100644
index 0000000..d89dd3e
--- /dev/null
+++ b/examples/stm32/f1/obldc-strip/systick/Makefile
@@ -0,0 +1,25 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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 = systick
+
+LDSCRIPT = ../obldc-strip.ld
+
+include ../../Makefile.include
+
diff --git a/examples/stm32/f1/obldc-strip/systick/systick.c b/examples/stm32/f1/obldc-strip/systick/systick.c
new file mode 100644
index 0000000..8b94901
--- /dev/null
+++ b/examples/stm32/f1/obldc-strip/systick/systick.c
@@ -0,0 +1,81 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net>
+ *
+ * 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/stm32/f1/rcc.h>
+#include <libopencm3/stm32/f1/flash.h>
+#include <libopencm3/stm32/f1/gpio.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
+
+u32 temp32;
+
+void gpio_setup(void)
+{
+ /* Enable alternate function peripheral clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
+
+ /* Enable GPIOB clock. */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
+
+ gpio_clear(GPIOB, GPIO4); /* LED green on */
+ gpio_set(GPIOB, GPIO5); /* LED red off */
+
+ /* Set GPIO4/5 (in GPIO port B) to 'output push-pull' for the LEDs. */
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO4);
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO5);
+
+ AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST;
+}
+
+void sys_tick_handler(void)
+{
+ temp32++;
+
+ /* We call this handler every 1ms so 1000ms = 1s on/off. */
+ if (temp32 == 1000) {
+ gpio_toggle(GPIOB, GPIO4); /* LED green on/off */
+ gpio_toggle(GPIOB, GPIO5); /* LED red on/off */
+ temp32 = 0;
+ }
+}
+
+int main(void)
+{
+ rcc_clock_setup_in_hsi_out_64mhz();
+ gpio_setup();
+
+ temp32 = 0;
+
+ /* 64MHz / 8 => 8000000 counts per second */
+ systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
+
+ /* 8000000/8000 = 1000 overflows per second - every 1ms one interrupt */
+ systick_set_reload(8000);
+
+ systick_interrupt_enable();
+
+ /* Start counting. */
+ systick_counter_enable();
+
+ while (1); /* Halt. */
+
+ return 0;
+}
diff --git a/examples/stm32/f1/obldc/can/can.c b/examples/stm32/f1/obldc/can/can.c
index d26be50..281ab1d 100644
--- a/examples/stm32/f1/obldc/can/can.c
+++ b/examples/stm32/f1/obldc/can/can.c
@@ -21,8 +21,8 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/nvic.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/can.h>
struct can_tx_msg {
diff --git a/examples/stm32/f1/obldc/systick/systick.c b/examples/stm32/f1/obldc/systick/systick.c
index e854f85..1426793 100644
--- a/examples/stm32/f1/obldc/systick/systick.c
+++ b/examples/stm32/f1/obldc/systick/systick.c
@@ -21,8 +21,8 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/nvic.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
u32 temp32;
diff --git a/examples/stm32/f1/obldc/usart_irq/usart_irq.c b/examples/stm32/f1/obldc/usart_irq/usart_irq.c
index 3925565..e13dd81 100644
--- a/examples/stm32/f1/obldc/usart_irq/usart_irq.c
+++ b/examples/stm32/f1/obldc/usart_irq/usart_irq.c
@@ -20,7 +20,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
void clock_setup(void)
{
diff --git a/examples/stm32/f1/other/dogm128/main.c b/examples/stm32/f1/other/dogm128/main.c
index 5838af4..7889794 100644
--- a/examples/stm32/f1/other/dogm128/main.c
+++ b/examples/stm32/f1/other/dogm128/main.c
@@ -22,7 +22,7 @@
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/timer.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/spi.h>
#include "./dogm128.h"
diff --git a/examples/stm32/f1/other/rtc/rtc.c b/examples/stm32/f1/other/rtc/rtc.c
index ee2a427..41c5d89 100644
--- a/examples/stm32/f1/other/rtc/rtc.c
+++ b/examples/stm32/f1/other/rtc/rtc.c
@@ -22,7 +22,7 @@
#include <libopencm3/stm32/f1/rtc.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/pwr.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
void clock_setup(void)
{
diff --git a/examples/stm32/f1/other/systick/systick.c b/examples/stm32/f1/other/systick/systick.c
index b2df171..c04704d 100644
--- a/examples/stm32/f1/other/systick/systick.c
+++ b/examples/stm32/f1/other/systick/systick.c
@@ -20,8 +20,8 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/nvic.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
u32 temp32;
diff --git a/examples/stm32/f1/other/timer_interrupt/timer.c b/examples/stm32/f1/other/timer_interrupt/timer.c
index 21a0caa..9450548 100644
--- a/examples/stm32/f1/other/timer_interrupt/timer.c
+++ b/examples/stm32/f1/other/timer_interrupt/timer.c
@@ -21,7 +21,7 @@
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/timer.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
void gpio_setup(void)
{
diff --git a/examples/stm32/f1/other/usb_cdcacm/cdcacm.c b/examples/stm32/f1/other/usb_cdcacm/cdcacm.c
index 2038664..81250b5 100644
--- a/examples/stm32/f1/other/usb_cdcacm/cdcacm.c
+++ b/examples/stm32/f1/other/usb_cdcacm/cdcacm.c
@@ -164,11 +164,12 @@ static const char *usb_strings[] = {
"DEMO",
};
-static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)complete;
(void)buf;
+ (void)usbd_dev;
switch(req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
@@ -200,28 +201,29 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
return 0;
}
-static void cdcacm_data_rx_cb(u8 ep)
+static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep)
{
(void)ep;
char buf[64];
- int len = usbd_ep_read_packet(0x01, buf, 64);
+ int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
if (len) {
- usbd_ep_write_packet(0x82, buf, len);
+ usbd_ep_write_packet(usbd_dev, 0x82, buf, len);
buf[len] = 0;
}
}
-static void cdcacm_set_config(u16 wValue)
+static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue)
{
(void)wValue;
- usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
- usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
- usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
+ usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
+ usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
+ usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
cdcacm_control_request);
@@ -229,6 +231,8 @@ static void cdcacm_set_config(u16 wValue)
int main(void)
{
+ usbd_device *usbd_dev;
+
rcc_clock_setup_in_hsi_out_48mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
@@ -238,13 +242,13 @@ int main(void)
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
- usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
- usbd_register_set_config_callback(cdcacm_set_config);
+ usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
+ usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
gpio_set(GPIOA, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
diff --git a/examples/stm32/f1/other/usb_dfu/usbdfu.c b/examples/stm32/f1/other/usb_dfu/usbdfu.c
index f30783f..44dde16 100644
--- a/examples/stm32/f1/other/usb_dfu/usbdfu.c
+++ b/examples/stm32/f1/other/usb_dfu/usbdfu.c
@@ -21,7 +21,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/f1/flash.h>
-#include <libopencm3/stm32/f1/scb.h>
+#include <libopencm3/cm3/scb.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/dfu.h>
@@ -130,10 +130,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout)
}
}
-static void usbdfu_getstatus_complete(struct usb_setup_data *req)
+static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
{
int i;
(void)req;
+ (void)usbd_dev;
switch (usbdfu_state) {
case STATE_DFU_DNBUSY:
@@ -166,9 +167,11 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
}
}
-static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
+ (void)usbd_dev;
+
if ((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request. */
@@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
int main(void)
{
+ usbd_device *usbd_dev;
+
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
if (!gpio_get(GPIOA, GPIO10)) {
@@ -246,9 +251,10 @@ int main(void)
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
- usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
- usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
+ usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
+ usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer));
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
usbdfu_control_request);
@@ -258,5 +264,5 @@ int main(void)
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
diff --git a/examples/stm32/f1/other/usb_hid/usbhid.c b/examples/stm32/f1/other/usb_hid/usbhid.c
index dd3c57a..7db0d8f 100644
--- a/examples/stm32/f1/other/usb_hid/usbhid.c
+++ b/examples/stm32/f1/other/usb_hid/usbhid.c
@@ -20,7 +20,7 @@
#include <stdlib.h>
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/systick.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/hid.h>
@@ -28,10 +28,12 @@
#define INCLUDE_DFU_INTERFACE
#ifdef INCLUDE_DFU_INTERFACE
-#include <libopencm3/stm32/f1/scb.h>
+#include <libopencm3/cm3/scb.h>
#include <libopencm3/usb/dfu.h>
#endif
+static usbd_device *usbd_dev;
+
const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
@@ -169,10 +171,11 @@ static const char *usb_strings[] = {
"DEMO",
};
-static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
+static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len,
+ void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)complete;
+ (void)usbd_dev;
if((req->bmRequestType != 0x81) ||
(req->bRequest != USB_REQ_GET_DESCRIPTOR) ||
@@ -187,9 +190,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
}
#ifdef INCLUDE_DFU_INTERFACE
-static void dfu_detach_complete(struct usb_setup_data *req)
+static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
{
(void)req;
+ (void)usbd_dev;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
@@ -198,11 +202,12 @@ static void dfu_detach_complete(struct usb_setup_data *req)
scb_reset_core();
}
-static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
+static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len,
+ void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)buf;
(void)len;
+ (void)usbd_dev;
if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH))
return 0; /* Only accept class request. */
@@ -213,18 +218,21 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
}
#endif
-static void hid_set_config(u16 wValue)
+static void hid_set_config(usbd_device *usbd_dev, u16 wValue)
{
(void)wValue;
+ (void)usbd_dev;
- usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
+ usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
hid_control_request);
#ifdef INCLUDE_DFU_INTERFACE
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
dfu_control_request);
@@ -246,15 +254,15 @@ int main(void)
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
- usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
- usbd_register_set_config_callback(hid_set_config);
+ usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
+ usbd_register_set_config_callback(usbd_dev, hid_set_config);
gpio_set(GPIOA, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
void sys_tick_handler(void)
@@ -270,5 +278,5 @@ void sys_tick_handler(void)
if (x < -30)
dir = -dir;
- usbd_ep_write_packet(0x81, buf, 4);
+ usbd_ep_write_packet(usbd_dev, 0x81, buf, 4);
}
diff --git a/examples/stm32/f1/stm32-h103/button/button.c b/examples/stm32/f1/stm32-h103/button/button.c
index 814fbfb..9d9a5e9 100644
--- a/examples/stm32/f1/stm32-h103/button/button.c
+++ b/examples/stm32/f1/stm32-h103/button/button.c
@@ -20,7 +20,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/exti.h>
u16 exti_line_state;
diff --git a/examples/stm32/f1/stm32-h103/exti_both/exti_both.c b/examples/stm32/f1/stm32-h103/exti_both/exti_both.c
index 3bafcc9..c871c35 100644
--- a/examples/stm32/f1/stm32-h103/exti_both/exti_both.c
+++ b/examples/stm32/f1/stm32-h103/exti_both/exti_both.c
@@ -20,7 +20,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/exti.h>
u16 exti_line_state;
diff --git a/examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c b/examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c
index c5dfe3b..f847847 100644
--- a/examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c
+++ b/examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c
@@ -20,7 +20,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/exti.h>
#define FALLING 0
diff --git a/examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c b/examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c
index 65854ac..deb0ff0 100644
--- a/examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c
+++ b/examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c
@@ -20,7 +20,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/timer.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/exti.h>
#define FALLING 0
diff --git a/examples/stm32/f1/stm32-h103/timer/timer.c b/examples/stm32/f1/stm32-h103/timer/timer.c
index 07f668b..210e592 100644
--- a/examples/stm32/f1/stm32-h103/timer/timer.c
+++ b/examples/stm32/f1/stm32-h103/timer/timer.c
@@ -20,7 +20,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/timer.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/exti.h>
u16 frequency_sequence[18] = {
diff --git a/examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c b/examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c
index 009c6d7..ae95df8 100644
--- a/examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c
+++ b/examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c
@@ -20,7 +20,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
void clock_setup(void)
{
diff --git a/examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c b/examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c
index 2143461..b052dc3 100644
--- a/examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c
+++ b/examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c
@@ -21,8 +21,8 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/systick.h>
#include <stdio.h>
#include <errno.h>
diff --git a/examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c b/examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c
index bc9fbd3..a275d83 100644
--- a/examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c
+++ b/examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c
@@ -21,7 +21,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <stdio.h>
#include <errno.h>
diff --git a/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c b/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c
index 779f659..3d25c29 100644
--- a/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c
+++ b/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c
@@ -41,7 +41,7 @@ static const struct usb_device_descriptor dev = {
};
/*
- * This notification endpoint isn't implemented. According to CDC spec its
+ * This notification endpoint isn't implemented. According to CDC spec its
* optional, but its absence causes a NULL pointer dereference in Linux
* cdc_acm driver.
*/
@@ -83,7 +83,7 @@ static const struct {
.bcdCDC = 0x0110,
},
.call_mgmt = {
- .bFunctionLength =
+ .bFunctionLength =
sizeof(struct usb_cdc_call_management_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
@@ -101,7 +101,7 @@ static const struct {
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
.bControlInterface = 0,
- .bSubordinateInterface0 = 1,
+ .bSubordinateInterface0 = 1,
},
};
@@ -164,11 +164,12 @@ static const char *usb_strings[] = {
"DEMO",
};
-static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)complete;
(void)buf;
+ (void)usbd_dev;
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
@@ -199,28 +200,31 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
return 0;
}
-static void cdcacm_data_rx_cb(u8 ep)
+static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep)
{
(void)ep;
+ (void)usbd_dev;
char buf[64];
- int len = usbd_ep_read_packet(0x01, buf, 64);
+ int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
if (len) {
- usbd_ep_write_packet(0x82, buf, len);
+ usbd_ep_write_packet(usbd_dev, 0x82, buf, len);
buf[len] = 0;
}
}
-static void cdcacm_set_config(u16 wValue)
+static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue)
{
(void)wValue;
+ (void)usbd_dev;
- usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
- usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
- usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
+ usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
+ usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
+ usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
cdcacm_control_request);
@@ -230,6 +234,8 @@ int main(void)
{
int i;
+ usbd_device *usbd_dev;
+
rcc_clock_setup_in_hsi_out_48mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
@@ -238,13 +244,13 @@ int main(void)
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
- usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
- usbd_register_set_config_callback(cdcacm_set_config);
+ usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
+ usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
for (i = 0; i < 0x800000; i++)
__asm__("nop");
gpio_clear(GPIOC, GPIO11);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
diff --git a/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c b/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c
index 49f265b..80c9b5b 100644
--- a/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c
+++ b/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c
@@ -21,7 +21,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/f1/flash.h>
-#include <libopencm3/stm32/f1/scb.h>
+#include <libopencm3/cm3/scb.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/dfu.h>
@@ -114,8 +114,10 @@ static const char *usb_strings[] = {
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
};
-static u8 usbdfu_getstatus(u32 *bwPollTimeout)
+static u8 usbdfu_getstatus(usbd_device *usbd_dev, u32 *bwPollTimeout)
{
+ (void)usbd_dev;
+
switch (usbdfu_state) {
case STATE_DFU_DNLOAD_SYNC:
usbdfu_state = STATE_DFU_DNBUSY;
@@ -130,10 +132,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout)
}
}
-static void usbdfu_getstatus_complete(struct usb_setup_data *req)
+static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
{
int i;
(void)req;
+ (void)usbd_dev;
switch (usbdfu_state) {
case STATE_DFU_DNBUSY:
@@ -166,8 +169,8 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
}
}
-static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
if ((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request. */
@@ -199,7 +202,7 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
return 0;
case DFU_GETSTATUS: {
u32 bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
- (*buf)[0] = usbdfu_getstatus(&bwPollTimeout);
+ (*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout);
(*buf)[1] = bwPollTimeout & 0xFF;
(*buf)[2] = (bwPollTimeout >> 8) & 0xFF;
(*buf)[3] = (bwPollTimeout >> 16) & 0xFF;
@@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
int main(void)
{
+ usbd_device *usbd_dev;
+
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
if (!gpio_get(GPIOA, GPIO10)) {
@@ -244,9 +249,10 @@ int main(void)
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
gpio_set(GPIOC, GPIO11);
- usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
- usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
+ usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
+ usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer));
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
usbdfu_control_request);
@@ -254,5 +260,5 @@ int main(void)
gpio_clear(GPIOC, GPIO11);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
diff --git a/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c b/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c
index 9ed40d1..a4a9314 100644
--- a/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c
+++ b/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c
@@ -20,7 +20,7 @@
#include <stdlib.h>
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/systick.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/hid.h>
@@ -28,7 +28,7 @@
#define INCLUDE_DFU_INTERFACE
#ifdef INCLUDE_DFU_INTERFACE
-#include <libopencm3/stm32/f1/scb.h>
+#include <libopencm3/cm3/scb.h>
#include <libopencm3/usb/dfu.h>
#endif
@@ -169,10 +169,11 @@ static const char *usb_strings[] = {
"DEMO",
};
-static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
+static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len,
+ void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)complete;
+ (void)usbd_dev;
if ((req->bmRequestType != 0x81) ||
(req->bRequest != USB_REQ_GET_DESCRIPTOR) ||
@@ -187,9 +188,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
}
#ifdef INCLUDE_DFU_INTERFACE
-static void dfu_detach_complete(struct usb_setup_data *req)
+static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
{
(void)req;
+ (void)usbd_dev;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
@@ -198,11 +200,12 @@ static void dfu_detach_complete(struct usb_setup_data *req)
scb_reset_core();
}
-static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
+static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len,
+ void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)buf;
(void)len;
+ (void)usbd_dev;
if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH))
return 0; /* Only accept class request. */
@@ -213,18 +216,21 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
}
#endif
-static void hid_set_config(u16 wValue)
+static void hid_set_config(usbd_device *usbd_dev, u16 wValue)
{
(void)wValue;
+ (void)usbd_dev;
- usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
+ usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
hid_control_request);
#ifdef INCLUDE_DFU_INTERFACE
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
dfu_control_request);
@@ -240,6 +246,8 @@ int main(void)
{
int i;
+ usbd_device *usbd_dev;
+
rcc_clock_setup_in_hsi_out_48mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
@@ -248,8 +256,8 @@ int main(void)
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
- usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
- usbd_register_set_config_callback(hid_set_config);
+ usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
+ usbd_register_set_config_callback(usbd_dev, hid_set_config);
for (i = 0; i < 0x80000; i++)
__asm__("nop");
@@ -257,9 +265,10 @@ int main(void)
gpio_clear(GPIOC, GPIO11);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
+#if 0 /* is this used? */
void sys_tick_handler(void)
{
static int x = 0;
@@ -273,5 +282,6 @@ void sys_tick_handler(void)
if (x < -30)
dir = -dir;
- usbd_ep_write_packet(0x81, buf, 4);
+ usbd_ep_write_packet(usbd_dev, 0x81, buf, 4);
}
+#endif
diff --git a/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c b/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c
index c5cc8ba..72fc0fb 100644
--- a/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c
+++ b/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c
@@ -21,7 +21,7 @@
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/f1/flash.h>
-#include <libopencm3/stm32/f1/scb.h>
+#include <libopencm3/cm3/scb.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/dfu.h>
@@ -114,8 +114,10 @@ static const char *usb_strings[] = {
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
};
-static u8 usbdfu_getstatus(u32 *bwPollTimeout)
+static u8 usbdfu_getstatus(usbd_device *usbd_dev, u32 *bwPollTimeout)
{
+ (void)usbd_dev;
+
switch (usbdfu_state) {
case STATE_DFU_DNLOAD_SYNC:
usbdfu_state = STATE_DFU_DNBUSY;
@@ -130,10 +132,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout)
}
}
-static void usbdfu_getstatus_complete(struct usb_setup_data *req)
+static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
{
int i;
(void)req;
+ (void)usbd_dev;
switch (usbdfu_state) {
case STATE_DFU_DNBUSY:
@@ -166,8 +169,8 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
}
}
-static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
if ((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request. */
@@ -199,7 +202,7 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
return 0;
case DFU_GETSTATUS: {
u32 bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
- (*buf)[0] = usbdfu_getstatus(&bwPollTimeout);
+ (*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout);
(*buf)[1] = bwPollTimeout & 0xFF;
(*buf)[2] = (bwPollTimeout >> 8) & 0xFF;
(*buf)[3] = (bwPollTimeout >> 16) & 0xFF;
@@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
int main(void)
{
+ usbd_device *usbd_dev;
+
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
if (!gpio_get(GPIOA, GPIO10)) {
@@ -244,9 +249,10 @@ int main(void)
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
- usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
- usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
+ usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
+ usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer));
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
usbdfu_control_request);
@@ -256,5 +262,5 @@ int main(void)
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
diff --git a/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c b/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c
index e9a52b2..fc0aecd 100644
--- a/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c
+++ b/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c
@@ -75,16 +75,17 @@ const char *usb_strings[] = {
"1001",
};
-static int simple_control_callback(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int simple_control_callback(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)buf;
(void)len;
(void)complete;
+ (void)usbd_dev;
if (req->bmRequestType != 0x40)
return 0; /* Only accept vendor request. */
-
+
if (req->wValue & 1)
gpio_set(GPIOC, GPIO6);
else
@@ -95,6 +96,8 @@ static int simple_control_callback(struct usb_setup_data *req, u8 **buf,
int main(void)
{
+ usbd_device *usbd_dev;
+
rcc_clock_setup_in_hse_8mhz_out_72mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
@@ -105,13 +108,14 @@ int main(void)
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO6);
- usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
+ usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_VENDOR,
USB_REQ_TYPE_TYPE,
simple_control_callback);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
diff --git a/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c b/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c
index d447e9b..b3c698b 100644
--- a/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c
+++ b/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c
@@ -23,7 +23,7 @@
#include <libopencm3/stm32/f1/rtc.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/pwr.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
void clock_setup(void)
{
diff --git a/examples/stm32/f2/jobygps/spi_test/spi_test.c b/examples/stm32/f2/jobygps/spi_test/spi_test.c
index 8775db8..95ba021 100644
--- a/examples/stm32/f2/jobygps/spi_test/spi_test.c
+++ b/examples/stm32/f2/jobygps/spi_test/spi_test.c
@@ -22,7 +22,7 @@
#include <errno.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/f2/gpio.h>
#include <libopencm3/stm32/f2/rcc.h>
diff --git a/examples/stm32/f2/jobygps/usart_printf/usart_printf.c b/examples/stm32/f2/jobygps/usart_printf/usart_printf.c
index 67a7d7f..d490e39 100644
--- a/examples/stm32/f2/jobygps/usart_printf/usart_printf.c
+++ b/examples/stm32/f2/jobygps/usart_printf/usart_printf.c
@@ -22,7 +22,7 @@
#include <errno.h>
#include <libopencm3/stm32/f2/gpio.h>
#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/f2/rcc.h>
void clock_setup(void)
diff --git a/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c b/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c
index 4af1039..836bdfb 100644
--- a/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c
+++ b/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c
@@ -22,6 +22,7 @@
#include <libopencm3/stm32/f4/gpio.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
+#include <libopencm3/cm3/scb.h>
static const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE,
@@ -164,11 +165,12 @@ static const char *usb_strings[] = {
"DEMO",
};
-static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req))
+static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
{
(void)complete;
(void)buf;
+ (void)usbd_dev;
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
@@ -188,30 +190,31 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
return 0;
}
-static void cdcacm_data_rx_cb(u8 ep)
+static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep)
{
(void)ep;
char buf[64];
- int len = usbd_ep_read_packet(0x01, buf, 64);
+ int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
if (len) {
- while (usbd_ep_write_packet(0x82, buf, len) == 0)
+ while (usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0)
;
}
gpio_toggle(GPIOC, GPIO5);
}
-static void cdcacm_set_config(u16 wValue)
+static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue)
{
(void)wValue;
- usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
- usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
- usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
+ usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
+ usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
+ usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
usbd_register_control_callback(
+ usbd_dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
cdcacm_control_request);
@@ -219,19 +222,20 @@ static void cdcacm_set_config(u16 wValue)
int main(void)
{
+ usbd_device *usbd_dev;
+
rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_120MHZ]);
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN);
- gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
+ gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
GPIO9 | GPIO11 | GPIO12);
gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12);
- usbd_init(&otgfs_usb_driver, &dev, &config, usb_strings);
- usbd_register_set_config_callback(cdcacm_set_config);
+ usbd_dev = usbd_init(&otgfs_usb_driver, &dev, &config, usb_strings);
+ usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
while (1)
- usbd_poll();
+ usbd_poll(usbd_dev);
}
-
diff --git a/examples/stm32/l1/Makefile.include b/examples/stm32/l1/Makefile.include
new file mode 100644
index 0000000..57b7030
--- /dev/null
+++ b/examples/stm32/l1/Makefile.include
@@ -0,0 +1,164 @@
+##
+## 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>
+##
+## 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
+
+TOOLCHAIN_DIR ?= ../../../../..
+ifeq ($(wildcard ../../../../../lib/libopencm3_stm32l1.a),)
+ifneq ($(strip $(shell which $(CC))),)
+TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX)
+endif
+else
+ifeq ($(V),1)
+$(info We seem to be building the example in the source directory. Using local library!)
+endif
+endif
+
+ARCH_FLAGS = -mthumb -mcpu=cortex-m3 -msoft-float
+CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \
+ -fno-common $(ARCH_FLAGS) -MD -DSTM32L1
+LDSCRIPT ?= $(BINARY).ld
+LDFLAGS += --static -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group \
+ -L$(TOOLCHAIN_DIR)/lib \
+ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
+ $(ARCH_FLAGS) -mfix-cortex-m3-ldrd
+
+CFLAGS += -I$(TOOLCHAIN_DIR)/include
+LDFLAGS += -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/stm32/l1
+SCRIPT_DIR = $(TOOLCHAIN_DIR)/share
+
+OBJS += $(BINARY).o
+
+OOCD ?= openocd
+OOCD_INTERFACE ?= flossjtag
+OOCD_BOARD ?= olimex_stm32_h103
+# Black magic probe specific variables
+# Set the BMP_PORT to a serial port and then BMP is used for flashing
+BMP_PORT ?=
+# texane/stlink can be used by uncommenting this...
+# or defining it in your own makefiles
+#STLINK_PORT ?= :4242
+
+# 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/libopencm3_stm32l1.a
+ @#printf " LD $(subst $(shell pwd)/,,$(@))\n"
+ $(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32l1 $(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
+
+ifeq ($(STLINK_PORT),)
+ifeq ($(BMP_PORT),)
+ifeq ($(OOCD_SERIAL),)
+%.flash: %.hex
+ @printf " FLASH $<\n"
+ @# IMPORTANT: Don't use "resume", only "reset" will work correctly!
+ $(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \
+ -f board/$(OOCD_BOARD).cfg \
+ -c "init" -c "reset init" \
+ -c "stm32l1x mass_erase 0" \
+ -c "flash write_image $(*).hex" \
+ -c "reset" \
+ -c "shutdown" $(NULL)
+else
+%.flash: %.hex
+ @printf " FLASH $<\n"
+ @# IMPORTANT: Don't use "resume", only "reset" will work correctly!
+ $(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \
+ -f board/$(OOCD_BOARD).cfg \
+ -c "ft2232_serial $(OOCD_SERIAL)" \
+ -c "init" -c "reset init" \
+ -c "stm32l1x mass_erase 0" \
+ -c "flash write_image $(*).hex" \
+ -c "reset" \
+ -c "shutdown" $(NULL)
+endif
+else
+%.flash: %.elf
+ @echo " GDB $(*).elf (flash)"
+ $(Q)$(GDB) --batch \
+ -ex 'target extended-remote $(BMP_PORT)' \
+ -x $(TOOLCHAIN_DIR)/scripts/black_magic_probe_flash.scr \
+ $(*).elf
+endif
+else
+%.flash: %.elf
+ @echo " GDB $(*).elf (flash)"
+ $(Q)$(GDB) --batch \
+ -ex 'target extended-remote $(STLINK_PORT)' \
+ -x $(SCRIPT_DIR)/libopencm3/scripts/stlink_flash.scr \
+ $(*).elf
+endif
+
+.PHONY: images clean
+
+-include $(OBJS:.o=.d)
+
diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile b/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile
new file mode 100644
index 0000000..d57ea7a
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile
@@ -0,0 +1,24 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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 = main
+LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld
+
+include ../../Makefile.include
+
diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/README b/examples/stm32/l1/stm32l-discovery/button-irq-printf/README
new file mode 100644
index 0000000..63232ef
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/README
@@ -0,0 +1,3 @@
+* Prints to the screen when the button is pushed/released (irq driven)
+ 115200@8n1 console on PA2 (tx only)
+
diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c
new file mode 100644
index 0000000..1830c4d
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c
@@ -0,0 +1,117 @@
+/*
+ * Karl Palsson, 2012 <karlp@tweak.net.au
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/stm32/l1/rcc.h>
+#include <libopencm3/stm32/l1/gpio.h>
+#include <libopencm3/stm32/exti.h>
+#include <libopencm3/stm32/usart.h>
+
+#include "syscfg.h"
+
+static struct state_t state;
+
+void clock_setup(void) {
+ /* Lots of things on all ports... */
+ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN);
+ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN);
+
+ /* Enable clocks for USART2. */
+ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN);
+}
+
+void gpio_setup(void) {
+ gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN);
+
+ /* Setup GPIO pins for USART2 transmit. */
+ gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2);
+
+ /* Setup USART2 TX pin as alternate function. */
+ gpio_set_af(GPIOA, GPIO_AF7, GPIO2);
+}
+
+void usart_setup(void) {
+ usart_set_baudrate(USART_CONSOLE, 115200);
+ usart_set_databits(USART_CONSOLE, 8);
+ usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1);
+ usart_set_mode(USART_CONSOLE, USART_MODE_TX);
+ usart_set_parity(USART_CONSOLE, USART_PARITY_NONE);
+ usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE);
+
+ /* Finally enable the USART. */
+ usart_enable(USART_CONSOLE);
+}
+
+/**
+ * Use USART_CONSOLE as a console.
+ * @param file
+ * @param ptr
+ * @param len
+ * @return
+ */
+int _write(int file, char *ptr, int len) {
+ int i;
+
+ if (file == STDOUT_FILENO || file == STDERR_FILENO) {
+ for (i = 0; i < len; i++) {
+ if (ptr[i] == '\n') {
+ usart_send_blocking(USART_CONSOLE, '\r');
+ }
+ usart_send_blocking(USART_CONSOLE, ptr[i]);
+ }
+ return i;
+ }
+ errno = EIO;
+ return -1;
+}
+
+void BUTTON_DISCO_USER_isr(void) {
+ exti_reset_request(BUTTON_DISCO_USER_EXTI);
+ if (state.falling) {
+ state.falling = false;
+ exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING);
+ // ILOG("fell: %d\n", TIM_CNT(TIM7));
+ puts("fell!\n");
+ } else {
+ puts("Rose!\n");
+ // TIM_CNT(TIM7) = 0;
+ state.falling = true;
+ exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING);
+ }
+}
+
+void setup_buttons(void) {
+ /* Enable EXTI0 interrupt. */
+ nvic_enable_irq(BUTTON_DISCO_USER_NVIC);
+
+ gpio_mode_setup(BUTTON_DISCO_USER_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, BUTTON_DISCO_USER_PIN);
+
+ /* Configure the EXTI subsystem. */
+ exti_select_source(BUTTON_DISCO_USER_EXTI, BUTTON_DISCO_USER_PORT);
+ state.falling = false;
+ exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING);
+ exti_enable_request(BUTTON_DISCO_USER_EXTI);
+}
+
+int main(void) {
+ int i;
+ int j = 0;
+ clock_setup();
+ gpio_setup();
+ usart_setup();
+ puts("hi guys!\n");
+ setup_buttons();
+ while (1) {
+ puts("tick:");
+ putchar('a' + (j++ % 26));
+ gpio_toggle(GPIOB, GPIO7); /* LED on/off */
+ for (i = 0; i < 100000; i++) /* Wait a bit. */
+ __asm__("NOP");
+ }
+
+ return 0;
+}
diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h
new file mode 100644
index 0000000..32cf465
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h
@@ -0,0 +1,45 @@
+/*
+ * General configuration of the device
+ *
+ * Karl Palsson <karlp@tweak.net.au> 2012
+ */
+
+#ifndef SYSCFG_H
+#define SYSCFG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libopencm3/stm32/l1/gpio.h>
+#include <libopencm3/stm32/l1/nvic.h>
+#include <libopencm3/stm32/exti.h>
+#include <libopencm3/stm32/usart.h>
+
+
+#define USART_CONSOLE USART2
+#define USE_NASTYLOG 1
+
+#define LED_DISCO_GREEN_PORT GPIOB
+#define LED_DISCO_GREEN_PIN GPIO7
+#define LED_DISCO_BLUE_PORT GPIOB
+#define LED_DISCO_BLUE_PIN GPIO6
+
+#define BUTTON_DISCO_USER_PORT GPIOA
+#define BUTTON_DISCO_USER_PIN GPIO0
+#define BUTTON_DISCO_USER_EXTI EXTI0
+#define BUTTON_DISCO_USER_isr exti0_isr
+#define BUTTON_DISCO_USER_NVIC NVIC_EXTI0_IRQ
+
+
+ struct state_t {
+ bool falling;
+ };
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSCFG_H */
+
diff --git a/examples/stm32/l1/stm32l-discovery/miniblink/Makefile b/examples/stm32/l1/stm32l-discovery/miniblink/Makefile
new file mode 100644
index 0000000..b0586e5
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/miniblink/Makefile
@@ -0,0 +1,25 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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
+
+LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld
+
+include ../../Makefile.include
+
diff --git a/examples/stm32/l1/stm32l-discovery/miniblink/README b/examples/stm32/l1/stm32l-discovery/miniblink/README
new file mode 100644
index 0000000..8bdd314
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/miniblink/README
@@ -0,0 +1,9 @@
+------------------------------------------------------------------------------
+README
+------------------------------------------------------------------------------
+
+This is the smallest-possible example program using libopencm3.
+
+It's intended for the ST STM32L-DISCOVERY eval board. It should blink
+the blue LED on the board.
+
diff --git a/examples/stm32/l1/stm32l-discovery/miniblink/miniblink.c b/examples/stm32/l1/stm32l-discovery/miniblink/miniblink.c
new file mode 100644
index 0000000..2f5c70f
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/miniblink/miniblink.c
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
+ *
+ * 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/stm32/l1/rcc.h>
+#include <libopencm3/stm32/l1/gpio.h>
+
+#define PORT_LED GPIOB
+#define PIN_LED GPIO6
+
+void gpio_setup(void)
+{
+ /* Enable GPIOB clock. */
+ /* Manually: */
+ //RCC_AHBENR |= RCC_AHBENR_GPIOBEN;
+ /* Using API functions: */
+ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN);
+
+ /* Set GPIO6 (in GPIO port B) to 'output push-pull'. */
+ /* Using API functions: */
+ gpio_mode_setup(PORT_LED, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED);
+}
+
+int main(void)
+{
+ int i;
+
+ gpio_setup();
+
+ /* Blink the LED (PC8) on the board. */
+ while (1) {
+ /* Manually: */
+ // GPIOD_BSRR = GPIO12; /* LED off */
+ // for (i = 0; i < 1000000; i++) /* Wait a bit. */
+ // __asm__("nop");
+ // GPIOD_BRR = GPIO12; /* LED on */
+ // for (i = 0; i < 1000000; i++) /* Wait a bit. */
+ // __asm__("nop");
+
+ /* Using API functions gpio_set()/gpio_clear(): */
+ // gpio_set(GPIOD, GPIO12); /* LED off */
+ // for (i = 0; i < 1000000; i++) /* Wait a bit. */
+ // __asm__("nop");
+ // gpio_clear(GPIOD, GPIO12); /* LED on */
+ // for (i = 0; i < 1000000; i++) /* Wait a bit. */
+ // __asm__("nop");
+
+ /* Using API function gpio_toggle(): */
+ gpio_toggle(PORT_LED, PIN_LED); /* LED on/off */
+ for (i = 0; i < 1000000; i++) /* Wait a bit. */
+ __asm__("nop");
+ }
+
+ return 0;
+}
diff --git a/examples/stm32/l1/stm32l-discovery/usart/Makefile b/examples/stm32/l1/stm32l-discovery/usart/Makefile
new file mode 100644
index 0000000..ac088fe
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/usart/Makefile
@@ -0,0 +1,25 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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 = usart
+
+LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld
+
+include ../../Makefile.include
+
diff --git a/examples/stm32/l1/stm32l-discovery/usart/README b/examples/stm32/l1/stm32l-discovery/usart/README
new file mode 100644
index 0000000..dcbc5d9
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/usart/README
@@ -0,0 +1,12 @@
+------------------------------------------------------------------------------
+README
+------------------------------------------------------------------------------
+
+This example program sends some characters on USART2 on the
+ST STM32L DISCOVERY eval board. (USART2 TX on PA2)
+
+The terminal settings for the receiving device/PC are 38400 8n1.
+
+The sending is done in a blocking way in the code, see the usart_irq example
+for a more elaborate USART example.
+
diff --git a/examples/stm32/l1/stm32l-discovery/usart/usart.c b/examples/stm32/l1/stm32l-discovery/usart/usart.c
new file mode 100644
index 0000000..3335ca8
--- /dev/null
+++ b/examples/stm32/l1/stm32l-discovery/usart/usart.c
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
+ *
+ * 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/stm32/l1/rcc.h>
+#include <libopencm3/stm32/l1/gpio.h>
+#include <libopencm3/stm32/usart.h>
+
+void clock_setup(void) {
+ /* We are running on MSI after boot. */
+ /* Enable GPIOD clock for LED & USARTs. */
+ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN);
+ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN);
+
+ /* Enable clocks for USART2. */
+ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN);
+}
+
+void usart_setup(void) {
+ /* Setup USART2 parameters. */
+ usart_set_baudrate(USART2, 38400);
+ usart_set_databits(USART2, 8);
+ usart_set_stopbits(USART2, USART_STOPBITS_1);
+ usart_set_mode(USART2, USART_MODE_TX);
+ usart_set_parity(USART2, USART_PARITY_NONE);
+ usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
+
+ /* Finally enable the USART. */
+ usart_enable(USART2);
+}
+
+void gpio_setup(void) {
+ /* Setup GPIO pin GPIO7 on GPIO port B for Green LED. */
+ gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO7);
+
+ /* Setup GPIO pins for USART2 transmit. */
+ gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2);
+
+ /* Setup USART2 TX pin as alternate function. */
+ gpio_set_af(GPIOA, GPIO_AF7, GPIO2);
+}
+
+int main(void) {
+ int i, j = 0, c = 0;
+
+ clock_setup();
+ gpio_setup();
+ usart_setup();
+
+ /* Blink the LED (PD12) on the board with every transmitted byte. */
+ while (1) {
+ gpio_toggle(GPIOB, GPIO7); /* LED on/off */
+ usart_send_blocking(USART2, c + '0'); /* USART2: Send byte. */
+ c = (c == 9) ? 0 : c + 1; /* Increment c. */
+ if ((j++ % 80) == 0) { /* Newline after line full. */
+ usart_send_blocking(USART2, '\r');
+ usart_send_blocking(USART2, '\n');
+ }
+ for (i = 0; i < 100000; i++) /* Wait a bit. */
+ __asm__("NOP");
+ }
+
+ return 0;
+}
diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/cm3/nvic.h
index 694fab8..3f83285 100644
--- a/include/libopencm3/stm32/nvic.h
+++ b/include/libopencm3/cm3/nvic.h
@@ -1,21 +1,9 @@
-/** @defgroup STM32F_nvic_defines NVIC Defines
-
-@brief <b>libopencm3 STM32F Nested Vectored Interrupt Controller</b>
-
-@ingroup STM32F_defines
-
-@version 1.0.0
-
-@author @htmlonly &copy; @endhtmlonly 2010 Piotr Esden-Tempski <piotr@esden.net>
-
-@date 18 August 2012
-
-LGPL License Terms @ref lgpl_license
- */
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
+ * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
*
* 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
@@ -30,13 +18,27 @@ LGPL License Terms @ref lgpl_license
* 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/>.
*/
+/** @defgroup CM3_nvic_defines NVIC Defines
+
+@brief <b>libopencm3 Cortex Nested Vectored Interrupt Controller</b>
+
+@ingroup CM3_defines
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2010 Piotr Esden-Tempski <piotr@esden.net>
+
+@date 18 August 2012
+
+LGPL License Terms @ref lgpl_license
+ */
/**@{*/
#ifndef LIBOPENCM3_NVIC_H
#define LIBOPENCM3_NVIC_H
-#include <libopencm3/stm32/memorymap.h>
#include <libopencm3/cm3/common.h>
+#include <libopencm3/cm3/memorymap.h>
/* --- NVIC Registers ------------------------------------------------------ */
@@ -79,9 +81,9 @@ LGPL License Terms @ref lgpl_license
/* --- IRQ channel numbers-------------------------------------------------- */
-/* Cortex M3 System Interrupts */
-/** @defgroup nvic_sysint Cortex M3 System Interrupts
-@ingroup STM32F_nvic_defines
+/* Cortex M3 and M4 System Interrupts */
+/** @defgroup nvic_sysint Cortex M3/M4 System Interrupts
+@ingroup CM3_nvic_defines
IRQ numbers -3 and -6 to -9 are reserved
@{*/
@@ -98,21 +100,11 @@ IRQ numbers -3 and -6 to -9 are reserved
#define NVIC_SYSTICK_IRQ -1
/**@}*/
-
/* Note: User interrupts are family specific and are defined in a family
* specific header file in the corresponding subfolder.
*/
-#if defined(STM32F1)
-# include <libopencm3/stm32/f1/nvic_f1.h>
-#elif defined(STM32F2)
-# include <libopencm3/stm32/f2/nvic_f2.h>
-#elif defined(STM32F4)
-# include <libopencm3/stm32/f4/nvic_f4.h>
-#else
-# error "stm32 family not defined."
-#endif
-
+#include <libopencm3/dispatch/nvic.h>
/* --- NVIC functions ------------------------------------------------------ */
@@ -131,5 +123,3 @@ void nvic_generate_software_interrupt(u16 irqn);
END_DECLS
#endif
-/**@}*/
-
diff --git a/include/libopencm3/stm32/f4/scb.h b/include/libopencm3/cm3/scb.h
index 7187ca9..8e9c757 100644
--- a/include/libopencm3/stm32/f4/scb.h
+++ b/include/libopencm3/cm3/scb.h
@@ -21,7 +21,7 @@
#ifndef LIBOPENCM3_SCB_H
#define LIBOPENCM3_SCB_H
-#include <libopencm3/stm32/memorymap.h>
+#include <libopencm3/cm3/memorymap.h>
#include <libopencm3/cm3/common.h>
/* --- SCB: Registers ------------------------------------------------------ */
diff --git a/include/libopencm3/stm32/systick.h b/include/libopencm3/cm3/systick.h
index e42c4e6..5e7715b 100644
--- a/include/libopencm3/stm32/systick.h
+++ b/include/libopencm3/cm3/systick.h
@@ -1,22 +1,8 @@
-/** @defgroup STM32F_systick_defines SysTick Defines
-
-@brief <b>libopencm3 Defined Constants and Types for the STM32F SysTick </b>
-
-@ingroup STM32F_defines
-
-@version 1.0.0
-
-@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
-
-@date 19 August 2012
-
-LGPL License Terms @ref lgpl_license
- */
-
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
*
* 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
@@ -31,13 +17,27 @@ LGPL License Terms @ref lgpl_license
* 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/>.
*/
+/** @defgroup CM3_systick_defines SysTick Defines
+
+@brief <b>libopencm3 Defined Constants and Types for the Cortex SysTick </b>
+
+@ingroup CM3_defines
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
+
+@date 19 August 2012
+
+LGPL License Terms @ref lgpl_license
+ */
/**@{*/
#ifndef LIBOPENCM3_SYSTICK_H
#define LIBOPENCM3_SYSTICK_H
-#include <libopencm3/stm32/memorymap.h>
+#include <libopencm3/cm3/memorymap.h>
#include <libopencm3/cm3/common.h>
/* --- SYSTICK registers --------------------------------------------------- */
@@ -63,7 +63,7 @@ LGPL License Terms @ref lgpl_license
#define STK_CTRL_CLKSOURCE (1 << 2)
#define STK_CTRL_CLKSOURCE_LSB 2
/** @defgroup systick_clksource Clock source selection
-@ingroup STM32F_systick_defines
+@ingroup CM3_systick_defines
@{*/
#define STK_CTRL_CLKSOURCE_AHB_DIV8 0
@@ -104,6 +104,8 @@ void systick_counter_enable(void);
void systick_counter_disable(void);
u8 systick_get_countflag(void);
+u32 systick_get_calib(void);
+
END_DECLS
#endif
diff --git a/include/libopencm3/cm3/vector.h b/include/libopencm3/cm3/vector.h
new file mode 100644
index 0000000..f78e9d8
--- /dev/null
+++ b/include/libopencm3/cm3/vector.h
@@ -0,0 +1,64 @@
+/*
+ * 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
+ * (from the EFM32 documentation at
+ * http://www.energymicro.com/downloads/datasheets), and was seen analogously
+ * in other ARM implementations' libopencm3 files.
+ *
+ * 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_VECTOR_H
+#define LIBOPENCM3_VECTOR_H
+
+#include <libopencm3/cm3/common.h>
+#include <libopencm3/cm3/nvic.h>
+
+/** Type of an interrupt function. Only used to avoid hard-to-read function
+ * pointers in the efm32_vector_table_t struct. */
+typedef void (*vector_table_entry_t)(void);
+
+typedef struct {
+ unsigned int *initial_sp_value; /**< The value the stack pointer is set to initially */
+ vector_table_entry_t reset;
+ vector_table_entry_t nmi;
+ vector_table_entry_t hard_fault;
+ vector_table_entry_t memory_manage_fault;
+ vector_table_entry_t bus_fault;
+ vector_table_entry_t usage_fault;
+ vector_table_entry_t reserved_x001c[4];
+ vector_table_entry_t sv_call;
+ vector_table_entry_t debug_monitor;
+ vector_table_entry_t reserved_x0034;
+ vector_table_entry_t pend_sv;
+ vector_table_entry_t systick;
+ vector_table_entry_t irq[NVIC_IRQ_COUNT];
+} vector_table_t;
+
+#endif
diff --git a/include/libopencm3/dispatch/nvic.h b/include/libopencm3/dispatch/nvic.h
new file mode 100644
index 0000000..08074e3
--- /dev/null
+++ b/include/libopencm3/dispatch/nvic.h
@@ -0,0 +1,34 @@
+#if defined(STM32F1)
+# include <libopencm3/stm32/f1/nvic.h>
+#elif defined(STM32F2)
+# include <libopencm3/stm32/f2/nvic.h>
+#elif defined(STM32F4)
+# include <libopencm3/stm32/f4/nvic.h>
+#elif defined(STM32L1)
+# include <libopencm3/stm32/l1/nvic.h>
+
+#elif defined(EFM32TG)
+# include <libopencm3/efm32/efm32tg/nvic.h>
+#elif defined(EFM32G)
+# include <libopencm3/efm32/efm32g/nvic.h>
+#elif defined(EFM32LG)
+# include <libopencm3/efm32/efm32lg/nvic.h>
+#elif defined(EFM32GG)
+# include <libopencm3/efm32/efm32gg/nvic.h>
+
+#elif defined(LPC13XX)
+# include <libopencm3/lpc13xx/nvic.h>
+#elif defined(LPC17XX)
+# include <libopencm3/lpc17xx/nvic.h>
+#elif defined(LPC43XX)
+# include <libopencm3/lpc43xx/nvic.h>
+
+#elif defined(LM3S)
+# include <libopencm3/lm3s/nvic.h>
+
+#else
+# warning"no interrupts defined for chipset; NVIC_IRQ_COUNT = 0"
+
+#define NVIC_IRQ_COUNT 0
+
+#endif
diff --git a/include/libopencm3/efm32/efm32g/irq.yaml b/include/libopencm3/efm32/efm32g/irq.yaml
new file mode 100644
index 0000000..770f755
--- /dev/null
+++ b/include/libopencm3/efm32/efm32g/irq.yaml
@@ -0,0 +1,35 @@
+includeguard: LIBOPENCM3_EFM32G_NVIC_H
+partname_humanreadable: EFM32 Gecko series
+partname_doxygen: EFM32G
+# The names and sequence are taken from d0001_efm32g_reference_manual.pdf table 4.1.
+irqs:
+ - dma
+ - gpio_even
+ - timer0
+ - usart0_rx
+ - usart0_tx
+ - acmp01
+ - adc0
+ - dac0
+ - i2c0
+ - gpio_odd
+ - timer1
+ - timer2
+ - usart1_rx
+ - usart1_tx
+ - usart2_rx
+ - usart2_tx
+ - uart0_rx
+ - uart0_tx
+ - leuart0
+ - leuart1
+ - letimer0
+ - pcnt0
+ - pcnt1
+ - pcnt2
+ - rtc
+ - cmu
+ - vcmp
+ - lcd
+ - msc
+ - aes
diff --git a/include/libopencm3/efm32/efm32gg/irq.yaml b/include/libopencm3/efm32/efm32gg/irq.yaml
new file mode 100644
index 0000000..1cb4601
--- /dev/null
+++ b/include/libopencm3/efm32/efm32gg/irq.yaml
@@ -0,0 +1,43 @@
+includeguard: LIBOPENCM3_EFM32GG_NVIC_H
+partname_humanreadable: EFM32 Giant Gecko series
+partname_doxygen: EFM32GG
+# The names and sequence are taken from d0053_efm32gg_refreence_manual.pdf table 4.1.
+irqs:
+ - dma
+ - gpio_even
+ - timer0
+ - usart0_rx
+ - usart0_tx
+ - usb
+ - acmp01
+ - adc0
+ - dac0
+ - i2c0
+ - i2c1
+ - gpio_odd
+ - timer1
+ - timer2
+ - timer3
+ - usart1_rx
+ - usart1_tx
+ - lesense
+ - usart2_rx
+ - usart2_tx
+ - uart0_rx
+ - uart0_tx
+ - uart1_rx
+ - uart1_tx
+ - leuart0
+ - leuart1
+ - letimer0
+ - pcnt0
+ - pcnt1
+ - pcnt2
+ - rtc
+ - burtc
+ - cmu
+ - vcmp
+ - lcd
+ - msc
+ - aes
+ - ebi
diff --git a/include/libopencm3/efm32/efm32lg/irq.yaml b/include/libopencm3/efm32/efm32lg/irq.yaml
new file mode 100644
index 0000000..ec38bc1
--- /dev/null
+++ b/include/libopencm3/efm32/efm32lg/irq.yaml
@@ -0,0 +1,43 @@
+includeguard: LIBOPENCM3_EFM32LG_NVIC_H
+partname_humanreadable: EFM32 Leopard Gecko series
+partname_doxygen: EFM32LG
+# The names and sequence are taken from d0183_efm32lg_reference_manual.pdf table 4.1.
+irqs:
+ - dma
+ - gpio_even
+ - timer0
+ - usart0_rx
+ - usart0_tx
+ - usb
+ - acmp01
+ - adc0
+ - dac0
+ - i2c0
+ - i2c1
+ - gpio_odd
+ - timer1
+ - timer2
+ - timer3
+ - usart1_rx
+ - usart1_tx
+ - lesense
+ - usart2_rx
+ - usart2_tx
+ - uart0_rx
+ - uart0_tx
+ - uart1_rx
+ - uart1_tx
+ - leuart0
+ - leuart1
+ - letimer0
+ - pcnt0
+ - pcnt1
+ - pcnt2
+ - rtc
+ - burtc
+ - cmu
+ - vcmp
+ - lcd
+ - msc
+ - aes
+ - ebi
diff --git a/include/libopencm3/efm32/efm32tg/irq.yaml b/include/libopencm3/efm32/efm32tg/irq.yaml
new file mode 100644
index 0000000..f4aaba3
--- /dev/null
+++ b/include/libopencm3/efm32/efm32tg/irq.yaml
@@ -0,0 +1,28 @@
+includeguard: LIBOPENCM3_EFM32TG_NVIC_H
+partname_humanreadable: EFM32 Tiny Gecko series
+partname_doxygen: EFM32TG
+# The names and sequence are taken from d0034_efm32tg_reference_manual.pdf table 4.1.
+irqs:
+ - dma
+ - gpio_even
+ - timer0
+ - usart0_rx
+ - usart0_tx
+ - acmp01
+ - adc0
+ - dac0
+ - i2c0
+ - gpio_odd
+ - timer1
+ - usart1_rx
+ - usart1_tx
+ - lesense
+ - leuart0
+ - letimer0
+ - pcnt0
+ - rtc
+ - cmu
+ - vcmp
+ - lcd
+ - msc
+ - aes
diff --git a/include/libopencm3/efm32/efm32tg/memorymap.h b/include/libopencm3/efm32/efm32tg/memorymap.h
new file mode 100644
index 0000000..abf37ce
--- /dev/null
+++ b/include/libopencm3/efm32/efm32tg/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/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/lm3s/irq.yaml b/include/libopencm3/lm3s/irq.yaml
new file mode 100644
index 0000000..7d5ff3a
--- /dev/null
+++ b/include/libopencm3/lm3s/irq.yaml
@@ -0,0 +1,120 @@
+includeguard: LIBOPENCM3_LM3S_NVIC_H
+partname_humanreadable: LM3S series
+partname_doxygen: LM3S
+irqs:
+ 0: GPIOA
+ 1: GPIOB
+ 2: GPIOC
+ 3: GPIOD
+ 4: GPIOE
+ 5: UART0
+ 6: UART1
+ 7: SSI0
+ 8: I2C0
+ 9: PWM0_FAULT
+ 10: PWM0_0
+ 11: PWM0_1
+ 12: PWM0_2
+ 13: QEI0
+ 14: ADC0SS0
+ 15: ADC0SS1
+ 16: ADC0SS2
+ 17: ADC0SS3
+ 18: WATCHDOG
+ 19: TIMER0A
+ 20: TIMER0B
+ 21: TIMER1A
+ 22: TIMER1B
+ 23: TIMER2A
+ 24: TIMER2B
+ 25: COMP0
+ 26: COMP1
+ 27: COMP2
+ 28: SYSCTL
+ 29: FLASH
+ 30: GPIOF
+ 31: GPIOG
+ 32: GPIOH
+ 33: UART2
+ 34: SSI1
+ 35: TIMER3A
+ 36: TIMER3B
+ 37: I2C1
+ 38: QEI1
+ 39: CAN0
+ 40: CAN1
+ 41: CAN2
+ 42: ETH
+ 43: HIBERNATE
+ 44: USB0
+ 45: PWM0_3
+ 46: UDMA
+ 47: UDMAERR
+ 48: ADC1SS0
+ 49: ADC1SS1
+ 50: ADC1SS2
+ 51: ADC1SS3
+ 52: I2S0
+ 53: EPI0
+ 54: GPIOJ
+ 55: GPIOK
+ 56: GPIOL
+ 57: SSI2
+ 58: SSI3
+ 59: UART3
+ 60: UART4
+ 61: UART5
+ 62: UART6
+ 63: UART7
+# undefined: slot 64 - 67
+ 68: I2C2
+ 69: I2C3
+ 70: TIMER4A
+ 71: TIMER4B
+# undefined: slot 72 - 91
+ 92: TIMER5A
+ 93: TIMER5B
+ 94: WTIMER0A
+ 95: WTIMER0B
+ 96: WTIMER1A
+ 97: WTIMER1B
+ 98: WTIMER2A
+ 99: WTIMER2B
+ 100: WTIMER3A
+ 101: WTIMER3B
+ 102: WTIMER4A
+ 103: WTIMER4B
+ 104: WTIMER5A
+ 105: WTIMER5B
+ 106: SYSEXC
+ 107: PECI0
+ 108: LPC0
+ 109: I2C4
+ 110: I2C5
+ 111: GPIOM
+ 112: GPION
+# undefined: slot 113
+ 114: FAN0
+# undefined: slot 115
+ 116: GPIOP0
+ 117: GPIOP1
+ 118: GPIOP2
+ 119: GPIOP3
+ 120: GPIOP4
+ 121: GPIOP5
+ 122: GPIOP6
+ 123: GPIOP7
+ 124: GPIOQ0
+ 125: GPIOQ1
+ 126: GPIOQ2
+ 127: GPIOQ3
+ 128: GPIOQ4
+ 129: GPIOQ5
+ 130: GPIOQ6
+ 131: GPIOQ7
+# undefined: slot 132 - 133
+ 134: PWM1_0
+ 135: PWM1_1
+ 136: PWM1_2
+ 137: PWM1_3
+ 138: PWM1_FAULT
diff --git a/include/libopencm3/lpc13xx/irq.yaml b/include/libopencm3/lpc13xx/irq.yaml
new file mode 100644
index 0000000..5a372db
--- /dev/null
+++ b/include/libopencm3/lpc13xx/irq.yaml
@@ -0,0 +1,62 @@
+includeguard: LIBOPENCM3_LPC13xx_NVIC_H
+partname_humanreadable: LPC 13xx series
+partname_doxygen: LPC13xx
+irqs:
+ 0: pio0_0
+ 1: pio0_1
+ 2: pio0_2
+ 3: pio0_3
+ 4: pio0_4
+ 5: pio0_5
+ 6: pio0_6
+ 7: pio0_7
+ 8: pio0_8
+ 9: pio0_9
+ 10: pio0_10
+ 11: pio0_11
+ 12: pio1_0
+ 13: pio1_1
+ 14: pio1_2
+ 15: pio1_3
+ 16: pio1_4
+ 17: pio1_5
+ 18: pio1_6
+ 19: pio1_7
+ 20: pio1_8
+ 21: pio1_9
+ 22: pio1_10
+ 23: pio1_11
+ 24: pio2_0
+ 25: pio2_1
+ 26: pio2_2
+ 27: pio2_3
+ 28: pio2_4
+ 29: pio2_5
+ 30: pio2_6
+ 31: pio2_7
+ 32: pio2_8
+ 33: pio2_9
+ 34: pio2_10
+ 35: pio2_11
+ 36: pio3_0
+ 37: pio3_1
+ 38: pio3_2
+ 39: pio3_3
+ 40: i2c0
+ 41: ct16b0
+ 42: ct16b1
+ 43: ct32b0
+ 44: ct32b1
+ 45: ssp0
+ 46: uart
+ 47: usb
+ 48: usb_fiq
+ 49: adc
+ 50: wdt
+ 51: bod
+# 52: reserved
+ 53: pio3
+ 54: pio2
+ 55: pio1
+ 56: pio0
+ 56: ssp1
diff --git a/include/libopencm3/lpc17xx/irq.yaml b/include/libopencm3/lpc17xx/irq.yaml
new file mode 100644
index 0000000..faa140f
--- /dev/null
+++ b/include/libopencm3/lpc17xx/irq.yaml
@@ -0,0 +1,39 @@
+includeguard: LIBOPENCM3_LPC17xx_NVIC_H
+partname_humanreadable: LPC 17xx series
+partname_doxygen: LPC17xx
+irqs:
+ 0: wdt
+ 1: timer0
+ 2: timer1
+ 3: timer2
+ 4: timer3
+ 5: uart0
+ 6: uart1
+ 7: uart2
+ 8: uart3
+ 9: pwm
+ 10: i2c0
+ 11: i2c1
+ 12: i2c2
+ 13: spi
+ 14: ssp0
+ 15: ssp1
+ 16: pll0
+ 17: rtc
+ 18: eint0
+ 19: eint1
+ 20: eint2
+ 21: eint3
+ 22: adc
+ 23: bod
+ 24: usb
+ 25: can
+ 26: gpdma
+ 27: i2s
+ 28: ethernet
+ 29: rit
+ 30: motor_pwm
+ 31: qei
+ 32: pll1
+ 33: usb_act
+ 34: can_act
diff --git a/include/libopencm3/lpc43xx/irq.yaml b/include/libopencm3/lpc43xx/irq.yaml
new file mode 100644
index 0000000..bc9536b
--- /dev/null
+++ b/include/libopencm3/lpc43xx/irq.yaml
@@ -0,0 +1,55 @@
+includeguard: LIBOPENCM3_LPC43xx_NVIC_H
+partname_humanreadable: LPC 43xx series
+partname_doxygen: LPC43xx
+irqs:
+ 0: dac
+ 1: m0core
+ 2: dma
+# reserved: 3, 4
+ 5: ethernet
+ 6: sdio
+ 7: lcd
+ 8: usb0
+ 9: usb1
+ 10: sct
+ 11: ritimer
+ 12: timer0
+ 13: timer1
+ 14: timer2
+ 15: timer3
+ 16: mcpwm
+ 17: adc0
+ 18: i2c0
+ 19: i2c1
+ 20: spi
+ 21: adc1
+ 22: ssp0
+ 23: ssp1
+ 24: usart0
+ 25: uart1
+ 26: usart2
+ 27: usart3
+ 28: i2s0
+ 29: i2s1
+ 30: spifi
+ 31: sgpio
+ 32: pin_int0
+ 33: pin_int1
+ 34: pin_int2
+ 35: pin_int3
+ 36: pin_int4
+ 37: pin_int5
+ 38: pin_int6
+ 39: pin_int7
+ 40: gint0
+ 41: gint1
+ 42: eventrouter
+ 43: c_can1
+# reserved: 44, 45
+ 46: atimer
+ 47: rtc
+# reserved: 48
+ 49: wwdt
+# reserved: 50
+ 51: c_can0
+ 52: qei
diff --git a/include/libopencm3/lpc43xx/nvic.h b/include/libopencm3/lpc43xx/nvic.h
deleted file mode 100644
index cdbf070..0000000
--- a/include/libopencm3/lpc43xx/nvic.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
- * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
- * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
- *
- * 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/>.
- */
-
-#ifndef LPC43XX_NVIC_H
-#define LPC43XX_NVIC_H
-
-#include <libopencm3/cm3/common.h>
-#include <libopencm3/cm3/memorymap.h>
-#include <libopencm3/lpc43xx/memorymap.h>
-
-/* --- NVIC Registers ------------------------------------------------------ */
-
-/* ISER: Interrupt Set Enable Registers */
-/* Note: 8 32bit Registers */
-#define NVIC_ISER(iser_id) MMIO32(NVIC_BASE + 0x00 + (iser_id * 4))
-
-/* NVIC_BASE + 0x020 (0xE000 E120 - 0xE000 E17F): Reserved */
-
-/* ICER: Interrupt Clear Enable Registers */
-/* Note: 8 32bit Registers */
-#define NVIC_ICER(icer_id) MMIO32(NVIC_BASE + 0x80 + (icer_id * 4))
-
-/* NVIC_BASE + 0x0A0 (0xE000 E1A0 - 0xE000 E1FF): Reserved */
-
-/* ISPR: Interrupt Set Pending Registers */
-/* Note: 8 32bit Registers */
-#define NVIC_ISPR(ispr_id) MMIO32(NVIC_BASE + 0x100 + (ispr_id * 4))
-
-/* NVIC_BASE + 0x120 (0xE000 E220 - 0xE000 E27F): Reserved */
-
-/* ICPR: Interrupt Clear Pending Registers */
-/* Note: 8 32bit Registers */
-#define NVIC_ICPR(icpr_id) MMIO32(NVIC_BASE + 0x180 + (icpr_id * 4))
-
-/* NVIC_BASE + 0x1A0 (0xE000 E2A0 - 0xE00 E2FF): Reserved */
-
-/* IABR: Interrupt Active Bit Register */
-/* Note: 8 32bit Registers */
-#define NVIC_IABR(iabr_id) MMIO32(NVIC_BASE + 0x200 + (iabr_id * 4))
-
-/* NVIC_BASE + 0x220 (0xE000 E320 - 0xE000 E3FF): Reserved */
-
-/* IPR: Interrupt Priority Registers */
-/* Note: 240 8bit Registers */
-#define NVIC_IPR(ipr_id) MMIO8(NVIC_BASE + 0x300 + ipr_id)
-
-/* STIR: Software Trigger Interrupt Register */
-#define NVIC_STIR MMIO32(STIR_BASE)
-
-/* --- IRQ channel numbers-------------------------------------------------- */
-
-/* Cortex M4 System Interrupts */
-#define NVIC_NMI_IRQ -14
-#define NVIC_HARD_FAULT_IRQ -13
-#define NVIC_MEM_MANAGE_IRQ -12
-#define NVIC_BUS_FAULT_IRQ -11
-#define NVIC_USAGE_FAULT_IRQ -10
-/* irq numbers -6 to -9 are reserved */
-#define NVIC_SV_CALL_IRQ -5
-#define DEBUG_MONITOR_IRQ -4
-/* irq number -3 reserved */
-#define NVIC_PENDSV_IRQ -2
-#define NVIC_SYSTICK_IRQ -1
-
-/* LPC43xx M4 specific user interrupts */
-#define NVIC_M4_DAC_IRQ 0
-#define NVIC_M4_M0CORE_IRQ 1
-#define NVIC_M4_DMA_IRQ 2
-#define NVIC_M4_ETHERNET_IRQ 5
-#define NVIC_M4_SDIO_IRQ 6
-#define NVIC_M4_LCD_IRQ 7
-#define NVIC_M4_USB0_IRQ 8
-#define NVIC_M4_USB1_IRQ 9
-#define NVIC_M4_SCT_IRQ 10
-#define NVIC_M4_RITIMER_IRQ 11
-#define NVIC_M4_TIMER0_IRQ 12
-#define NVIC_M4_TIMER1_IRQ 13
-#define NVIC_M4_TIMER2_IRQ 14
-#define NVIC_M4_TIMER3_IRQ 15
-#define NVIC_M4_MCPWM_IRQ 16
-#define NVIC_M4_ADC0_IRQ 17
-#define NVIC_M4_I2C0_IRQ 18
-#define NVIC_M4_I2C1_IRQ 19
-#define NVIC_M4_SPI_IRQ 20
-#define NVIC_M4_ADC1_IRQ 21
-#define NVIC_M4_SSP0_IRQ 22
-#define NVIC_M4_SSP1_IRQ 23
-#define NVIC_M4_USART0_IRQ 24
-#define NVIC_M4_UART1_IRQ 25
-#define NVIC_M4_USART2_IRQ 26
-#define NVIC_M4_USART3_IRQ 27
-#define NVIC_M4_I2S0_IRQ 28
-#define NVIC_M4_I2S1_IRQ 29
-#define NVIC_M4_SPIFI_IRQ 30
-#define NVIC_M4_SGPIO_IRQ 31
-#define NVIC_M4_PIN_INT0_IRQ 32
-#define NVIC_M4_PIN_INT1_IRQ 33
-#define NVIC_M4_PIN_INT2_IRQ 34
-#define NVIC_M4_PIN_INT3_IRQ 35
-#define NVIC_M4_PIN_INT4_IRQ 36
-#define NVIC_M4_PIN_INT5_IRQ 37
-#define NVIC_M4_PIN_INT6_IRQ 38
-#define NVIC_M4_PIN_INT7_IRQ 39
-#define NVIC_M4_GINT0_IRQ 40
-#define NVIC_M4_GINT1_IRQ 41
-#define NVIC_M4_EVENTROUTER_IRQ 42
-#define NVIC_M4_C_CAN1_IRQ 43
-#define NVIC_M4_ATIMER_IRQ 46
-#define NVIC_M4_RTC_IRQ 47
-#define NVIC_M4_WWDT_IRQ 49
-#define NVIC_M4_C_CAN0_IRQ 51
-#define NVIC_M4_QEI_IRQ 52
-
-/* LPC43xx M0 specific user interrupts */
-//TODO
-
-/* --- NVIC functions ------------------------------------------------------ */
-
-BEGIN_DECLS
-
-void nvic_enable_irq(u8 irqn);
-void nvic_disable_irq(u8 irqn);
-u8 nvic_get_pending_irq(u8 irqn);
-void nvic_set_pending_irq(u8 irqn);
-void nvic_clear_pending_irq(u8 irqn);
-u8 nvic_get_active_irq(u8 irqn);
-u8 nvic_get_irq_enabled(u8 irqn);
-void nvic_set_priority(u8 irqn, u8 priority);
-void nvic_generate_software_interrupt(u8 irqn);
-
-END_DECLS
-
-#endif
diff --git a/include/libopencm3/lpc43xx/systick.h b/include/libopencm3/lpc43xx/systick.h
deleted file mode 100644
index 2ae52c2..0000000
--- a/include/libopencm3/lpc43xx/systick.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
- * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
- *
- * 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/>.
- */
-
-#ifndef LIBOPENCM3_SYSTICK_H
-#define LIBOPENCM3_SYSTICK_H
-
-#include <libopencm3/lpc43xx/memorymap.h>
-#include <libopencm3/cm3/memorymap.h>
-#include <libopencm3/cm3/common.h>
-
-/* --- SYSTICK registers --------------------------------------------------- */
-/* See also libopencm3\cm3\scs.h for details on SysTicks registers */
-
-/* Control and status register (STK_CTRL) */
-#define STK_CTRL MMIO32(SYS_TICK_BASE + 0x00)
-
-/* reload value register (STK_LOAD) */
-#define STK_LOAD MMIO32(SYS_TICK_BASE + 0x04)
-
-/* current value register (STK_VAL) */
-#define STK_VAL MMIO32(SYS_TICK_BASE + 0x08)
-
-/* calibration value register (STK_CALIB) */
-#define STK_CALIB MMIO32(SYS_TICK_BASE + 0x0C)
-
-/* --- STK_CTRL values ----------------------------------------------------- */
-/* Bits [31:17] Reserved, must be kept cleared. */
-/* COUNTFLAG: */
-#define STK_CTRL_COUNTFLAG (1 << 16)
-/* Bits [15:3] Reserved, must be kept cleared. */
-/* CLKSOURCE: Clock source selection */
-#define STK_CTRL_CLKSOURCE (1 << 2)
-/* TICKINT: SysTick exception request enable */
-#define STK_CTRL_TICKINT (1 << 1)
-/* ENABLE: Counter enable */
-#define STK_CTRL_ENABLE (1 << 0)
-
-/* --- STK_LOAD values ----------------------------------------------------- */
-/* Bits [31:24] Reserved, must be kept cleared. */
-/* RELOAD[23:0]: RELOAD value */
-
-/* --- STK_VAL values ------------------------------------------------------ */
-/* Bits [31:24] Reserved, must be kept cleared. */
-/* CURRENT[23:0]: Current counter value */
-
-/* --- STK_CALIB values ---------------------------------------------------- */
-/* NOREF: NOREF flag */
-#define STK_CALIB_NOREF (1 << 31)
-/* SKEW: SKEW flag */
-#define STK_CALIB_SKEW (1 << 30)
-/* Bits [29:24] Reserved, must be kept cleared. */
-/* TENMS[23:0]: Calibration value */
-
-/* --- Function Prototypes ------------------------------------------------- */
-
-BEGIN_DECLS
-
-void systick_set_reload(u32 value);
-u32 systick_get_value(void);
-void systick_set_clocksource(u8 clocksource);
-void systick_interrupt_enable(void);
-void systick_interrupt_disable(void);
-void systick_counter_enable(void);
-void systick_counter_disable(void);
-u8 systick_get_countflag(void);
-
-u32 systick_get_calib(void);
-
-END_DECLS
-
-#endif
diff --git a/include/libopencm3/stm32/can.h b/include/libopencm3/stm32/can.h
index 1919da4..c6c9d48 100644
--- a/include/libopencm3/stm32/can.h
+++ b/include/libopencm3/stm32/can.h
@@ -461,7 +461,7 @@
/* --- CAN_TIxR values ------------------------------------------------------ */
/* STID[10:0]: Standard identifier */
-#define CAN_TIxR_STID_MASK (0x3FF << 21)
+#define CAN_TIxR_STID_MASK (0x7FF << 21)
#define CAN_TIxR_STID_SHIFT 21
/* EXID[15:0]: Extended identifier */
diff --git a/include/libopencm3/stm32/f1/desig.h b/include/libopencm3/stm32/desig.h
index 6ceb665..6ceb665 100644
--- a/include/libopencm3/stm32/f1/desig.h
+++ b/include/libopencm3/stm32/desig.h
diff --git a/include/libopencm3/stm32/exti.h b/include/libopencm3/stm32/exti.h
index 7645825..48065b9 100644
--- a/include/libopencm3/stm32/exti.h
+++ b/include/libopencm3/stm32/exti.h
@@ -53,6 +53,9 @@
#define EXTI17 (1 << 17)
#define EXTI18 (1 << 18)
#define EXTI19 (1 << 19)
+#define EXTI20 (1 << 20)
+#define EXTI21 (1 << 21)
+#define EXTI22 (1 << 22)
/* Trigger types */
typedef enum trigger_e {
diff --git a/include/libopencm3/stm32/f1/dma.h b/include/libopencm3/stm32/f1/dma.h
index 8a2edba..6257394 100644
--- a/include/libopencm3/stm32/f1/dma.h
+++ b/include/libopencm3/stm32/f1/dma.h
@@ -141,9 +141,30 @@ LGPL License Terms @ref lgpl_license
/* --- DMA_ISR values ------------------------------------------------------ */
+/* --- DMA Interrupt Flag offset values ------------------------------------- */
+/* These are based on every interrupt flag and flag clear being at the same relative location */
+/** @defgroup dma_if_offset DMA Interrupt Flag Offsets within stream flag group.
+@ingroup STM32F1xx_dma_defines
+
+@{*/
+/** Transfer Error Interrupt Flag */
+#define DMA_TEIF (1 << 3)
+/** Half Transfer Interrupt Flag */
+#define DMA_HTIF (1 << 2)
+/** Transfer Complete Interrupt Flag */
+#define DMA_TCIF (1 << 1)
+/** Global Interrupt Flag */
+#define DMA_GIF (1 << 0)
+/**@}*/
+
+/* Offset within interrupt status register to start of stream interrupt flag field */
+#define DMA_FLAG_OFFSET(channel) (4*(channel - 1))
+#define DMA_FLAGS (DMA_TEIF | DMA_TCIF | DMA_HTIF | DMA_GIF)
+#define DMA_ISR_MASK(channel) DMA_FLAGS << DMA_FLAG_OFFSET(channel)
+
/* TEIF: Transfer error interrupt flag */
-#define DMA_ISR_TEIF_BIT (1 << 3)
-#define DMA_ISR_TEIF(channel) (DMA_ISR_TEIF_BIT << (4 * ((channel) -1)))
+#define DMA_ISR_TEIF_BIT DMA_ISR_TEIF
+#define DMA_ISR_TEIF(channel) (DMA_ISR_TEIF_BIT << DMA_FLAG_OFFSET(channel)))
#define DMA_ISR_TEIF1 DMA_ISR_TEIF(DMA_CHANNEL1)
#define DMA_ISR_TEIF2 DMA_ISR_TEIF(DMA_CHANNEL2)
@@ -154,8 +175,8 @@ LGPL License Terms @ref lgpl_license
#define DMA_ISR_TEIF7 DMA_ISR_TEIF(DMA_CHANNEL7)
/* HTIF: Half transfer interrupt flag */
-#define DMA_ISR_HTIF_BIT (1 << 2)
-#define DMA_ISR_HTIF(channel) (DMA_ISR_HTIF_BIT << (4 * ((channel) -1)))
+#define DMA_ISR_HTIF_BIT DMA_HTIF
+#define DMA_ISR_HTIF(channel) (DMA_ISR_HTIF_BIT << DMA_FLAG_OFFSET(channel)))
#define DMA_ISR_HTIF1 DMA_ISR_HTIF(DMA_CHANNEL1)
#define DMA_ISR_HTIF2 DMA_ISR_HTIF(DMA_CHANNEL2)
@@ -166,8 +187,8 @@ LGPL License Terms @ref lgpl_license
#define DMA_ISR_HTIF7 DMA_ISR_HTIF(DMA_CHANNEL7)
/* TCIF: Transfer complete interrupt flag */
-#define DMA_ISR_TCIF_BIT (1 << 1)
-#define DMA_ISR_TCIF(channel) (DMA_ISR_TCIF_BIT << (4 * ((channel) -1)))
+#define DMA_ISR_TCIF_BIT DMA_TCIF
+#define DMA_ISR_TCIF(channel) (DMA_ISR_TCIF_BIT << (DMA_FLAG_OFFSET(channel)))
#define DMA_ISR_TCIF1 DMA_ISR_TCIF(DMA_CHANNEL1)
#define DMA_ISR_TCIF2 DMA_ISR_TCIF(DMA_CHANNEL2)
@@ -178,8 +199,8 @@ LGPL License Terms @ref lgpl_license
#define DMA_ISR_TCIF7 DMA_ISR_TCIF(DMA_CHANNEL7)
/* GIF: Global interrupt flag */
-#define DMA_ISR_GIF_BIT (1 << 0)
-#define DMA_ISR_GIF(channel) (DMA_ISR_GIF_BIT << (4 * ((channel) -1)))
+#define DMA_ISR_GIF_BIT DMA_GIF
+#define DMA_ISR_GIF(channel) (DMA_ISR_GIF_BIT << (DMA_FLAG_OFFSET(channel)))
#define DMA_ISR_GIF1 DMA_ISR_GIF(DMA_CHANNEL1)
#define DMA_ISR_GIF2 DMA_ISR_GIF(DMA_CHANNEL2)
@@ -192,8 +213,8 @@ LGPL License Terms @ref lgpl_license
/* --- DMA_IFCR values ----------------------------------------------------- */
/* CTEIF: Transfer error clear */
-#define DMA_IFCR_CTEIF_BIT (1 << 3)
-#define DMA_IFCR_CTEIF(channel) (DMA_IFCR_CTEIF_BIT << (4 * ((channel) -1)))
+#define DMA_IFCR_CTEIF_BIT DMA_TEIF
+#define DMA_IFCR_CTEIF(channel) (DMA_IFCR_CTEIF_BIT << (DMA_FLAG_OFFSET(channel)))
#define DMA_IFCR_CTEIF1 DMA_IFCR_CTEIF(DMA_CHANNEL1)
#define DMA_IFCR_CTEIF2 DMA_IFCR_CTEIF(DMA_CHANNEL2)
@@ -204,8 +225,8 @@ LGPL License Terms @ref lgpl_license
#define DMA_IFCR_CTEIF7 DMA_IFCR_CTEIF(DMA_CHANNEL7)
/* CHTIF: Half transfer clear */
-#define DMA_IFCR_CHTIF_BIT (1 << 2)
-#define DMA_IFCR_CHTIF(channel) (DMA_IFCR_CHTIF_BIT << (4 * ((channel) -1)))
+#define DMA_IFCR_CHTIF_BIT DMA_HTIF
+#define DMA_IFCR_CHTIF(channel) (DMA_IFCR_CHTIF_BIT << (DMA_FLAG_OFFSET(channel)))
#define DMA_IFCR_CHTIF1 DMA_IFCR_CHTIF(DMA_CHANNEL1)
#define DMA_IFCR_CHTIF2 DMA_IFCR_CHTIF(DMA_CHANNEL2)
@@ -216,8 +237,8 @@ LGPL License Terms @ref lgpl_license
#define DMA_IFCR_CHTIF7 DMA_IFCR_CHTIF(DMA_CHANNEL7)
/* CTCIF: Transfer complete clear */
-#define DMA_IFCR_CTCIF_BIT (1 << 1)
-#define DMA_IFCR_CTCIF(channel) (DMA_IFCR_CTCIF_BIT << (4 * ((channel) -1)))
+#define DMA_IFCR_CTCIF_BIT DMA_TCIF
+#define DMA_IFCR_CTCIF(channel) (DMA_IFCR_CTCIF_BIT << (DMA_FLAG_OFFSET(channel)))
#define DMA_IFCR_CTCIF1 DMA_IFCR_CTCIF(DMA_CHANNEL1)
#define DMA_IFCR_CTCIF2 DMA_IFCR_CTCIF(DMA_CHANNEL2)
@@ -228,8 +249,8 @@ LGPL License Terms @ref lgpl_license
#define DMA_IFCR_CTCIF7 DMA_IFCR_CTCIF(DMA_CHANNEL7)
/* CGIF: Global interrupt clear */
-#define DMA_IFCR_CGIF_BIT (1 << 0)
-#define DMA_IFCR_CGIF(channel) (DMA_IFCR_CGIF_BIT << (4 * ((channel) -1)))
+#define DMA_IFCR_CGIF_BIT DMA_GIF
+#define DMA_IFCR_CGIF(channel) (DMA_IFCR_CGIF_BIT << (DMA_FLAG_OFFSET(channel)))
#define DMA_IFCR_CGIF1 DMA_IFCR_CGIF(DMA_CHANNEL1)
#define DMA_IFCR_CGIF2 DMA_IFCR_CGIF(DMA_CHANNEL2)
@@ -241,7 +262,7 @@ LGPL License Terms @ref lgpl_license
/* Clear interrupts mask */
#define DMA_IFCR_CIF_BIT 0xF
-#define DMA_IFCR_CIF(channel) (DMA_IFCR_CIF_BIT << (4 * ((channel) - 1)))
+#define DMA_IFCR_CIF(channel) (DMA_IFCR_CIF_BIT << (DMA_FLAG_OFFSET(channel)))
#define DMA_IFCR_CIF1 DMA_IFCR_CIF(DMA_CHANNEL1)
#define DMA_IFCR_CIF2 DMA_IFCR_CIF(DMA_CHANNEL2)
@@ -349,12 +370,16 @@ LGPL License Terms @ref lgpl_license
BEGIN_DECLS
void dma_channel_reset(u32 dma, u8 channel);
+void dma_clear_interrupt_flags(u32 dma, u8 channel, u32 interrupts);
+bool dma_get_interrupt_flag(u32 dma, u8 channel, u32 interrupts);
void dma_enable_mem2mem_mode(u32 dma, u8 channel);
void dma_set_priority(u32 dma, u8 channel, u32 prio);
void dma_set_memory_size(u32 dma, u8 channel, u32 mem_size);
void dma_set_peripheral_size(u32 dma, u8 channel, u32 peripheral_size);
void dma_enable_memory_increment_mode(u32 dma, u8 channel);
+void dma_disable_memory_increment_mode(u32 dma, u8 channel);
void dma_enable_peripheral_increment_mode(u32 dma, u8 channel);
+void dma_disable_peripheral_increment_mode(u32 dma, u8 channel);
void dma_enable_circular_mode(u32 dma, u8 channel);
void dma_set_read_from_peripheral(u32 dma, u8 channel);
void dma_set_read_from_memory(u32 dma, u8 channel);
diff --git a/include/libopencm3/stm32/f1/gpio.h b/include/libopencm3/stm32/f1/gpio.h
index a1e74cc..f342504 100644
--- a/include/libopencm3/stm32/f1/gpio.h
+++ b/include/libopencm3/stm32/f1/gpio.h
@@ -103,18 +103,18 @@ LGPL License Terms @ref lgpl_license
/* CAN1 / CAN BANK */
#define GPIO_BANK_CAN1_RX GPIOA /* PA11 */
#define GPIO_BANK_CAN1_TX GPIOA /* PA12 */
-#define GPIO_BANK_CAN_RX GPIO_CAN1_RX /* Alias */
-#define GPIO_BANK_CAN_TX GPIO_CAN1_TX /* Alias */
+#define GPIO_BANK_CAN_RX GPIO_BANK_CAN1_RX /* Alias */
+#define GPIO_BANK_CAN_TX GPIO_BANK_CAN1_TX /* Alias */
#define GPIO_BANK_CAN_PB_RX GPIOB /* PB8 */
#define GPIO_BANK_CAN_PB_TX GPIOB /* PB9 */
-#define GPIO_BANK_CAN1_PB_RX GPIO_CAN_PB_RX /* Alias */
-#define GPIO_BANK_CAN1_PB_TX GPIO_CAN_PB_TX /* Alias */
+#define GPIO_BANK_CAN1_PB_RX GPIO_BANK_CAN_PB_RX /* Alias */
+#define GPIO_BANK_CAN1_PB_TX GPIO_BANK_CAN_PB_TX /* Alias */
#define GPIO_BANK_CAN_PD_RX GPIOD /* PD0 */
#define GPIO_BANK_CAN_PD_TX GPIOD /* PD1 */
-#define GPIO_BANK_CAN1_PD_RX GPIO_CAN_PD_RX /* Alias */
-#define GPIO_BANK_CAN1_PD_TX GPIO_CAN_PD_TX /* Alias */
+#define GPIO_BANK_CAN1_PD_RX GPIO_BANK_CAN_PD_RX /* Alias */
+#define GPIO_BANK_CAN1_PD_TX GPIO_BANK_CAN_PD_TX /* Alias */
/* CAN2 GPIO */
#define GPIO_CAN2_RX GPIO12 /* PB12 */
diff --git a/include/libopencm3/stm32/f1/irq.yaml b/include/libopencm3/stm32/f1/irq.yaml
new file mode 100644
index 0000000..14cbcc0
--- /dev/null
+++ b/include/libopencm3/stm32/f1/irq.yaml
@@ -0,0 +1,72 @@
+includeguard: LIBOPENCM3_STM32_F1_NVIC_H
+partname_humanreadable: STM32 F1 series
+partname_doxygen: STM32F1
+irqs:
+ - wwdg
+ - pvd
+ - tamper
+ - rtc
+ - flash
+ - rcc
+ - exti0
+ - exti1
+ - exti2
+ - exti3
+ - exti4
+ - dma1_channel1
+ - dma1_channel2
+ - dma1_channel3
+ - dma1_channel4
+ - dma1_channel5
+ - dma1_channel6
+ - dma1_channel7
+ - adc1_2
+ - usb_hp_can_tx
+ - usb_lp_can_rx0
+ - can_rx1
+ - can_sce
+ - exti9_5
+ - tim1_brk
+ - tim1_up
+ - tim1_trg_com
+ - tim1_cc
+ - tim2
+ - tim3
+ - tim4
+ - i2c1_ev
+ - i2c1_er
+ - i2c2_ev
+ - i2c2_er
+ - spi1
+ - spi2
+ - usart1
+ - usart2
+ - usart3
+ - exti15_10
+ - rtc_alarm
+ - usb_wakeup
+ - tim8_brk
+ - tim8_up
+ - tim8_trg_com
+ - tim8_cc
+ - adc3
+ - fsmc
+ - sdio
+ - tim5
+ - spi3
+ - uart4
+ - uart5
+ - tim6
+ - tim7
+ - dma2_channel1
+ - dma2_channel2
+ - dma2_channel3
+ - dma2_channel4_5
+ - dma2_channel5
+ - eth
+ - eth_wkup
+ - can2_tx
+ - can2_rx0
+ - can2_rx1
+ - can2_sce
+ - otg_fs
diff --git a/include/libopencm3/stm32/f1/nvic_f1.h b/include/libopencm3/stm32/f1/nvic_f1.h
deleted file mode 100644
index 5223bb6..0000000
--- a/include/libopencm3/stm32/f1/nvic_f1.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/** @brief <b>Defined Constants and Types for the STM32F1xx Nested Vectored Interrupt Controller</b>
-
-@version 1.0.0
-
-@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
-
-@date 18 August 2012
-
-LGPL License Terms @ref lgpl_license
- */
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
- *
- * 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/>.
- */
-
-#ifndef LIBOPENCM3_NVIC_F1_H
-#define LIBOPENCM3_NVIC_F1_H
-
-/* --- IRQ channel numbers-------------------------------------------------- */
-
-/* Note: These F1 specific user interrupt definitions supplement the
- * general NVIC definitions in ../nvic.h
- */
-
-/* User Interrupts */
-/** @defgroup nvic_stm32f1_userint STM32F1xx User Interrupts
-@ingroup STM32F_nvic_defines
-
-@{*/
-#define NVIC_WWDG_IRQ 0
-#define NVIC_PVD_IRQ 1
-#define NVIC_TAMPER_IRQ 2
-#define NVIC_RTC_IRQ 3
-#define NVIC_FLASH_IRQ 4
-#define NVIC_RCC_IRQ 5
-#define NVIC_EXTI0_IRQ 6
-#define NVIC_EXTI1_IRQ 7
-#define NVIC_EXTI2_IRQ 8
-#define NVIC_EXTI3_IRQ 9
-#define NVIC_EXTI4_IRQ 10
-#define NVIC_DMA1_CHANNEL1_IRQ 11
-#define NVIC_DMA1_CHANNEL2_IRQ 12
-#define NVIC_DMA1_CHANNEL3_IRQ 13
-#define NVIC_DMA1_CHANNEL4_IRQ 14
-#define NVIC_DMA1_CHANNEL5_IRQ 15
-#define NVIC_DMA1_CHANNEL6_IRQ 16
-#define NVIC_DMA1_CHANNEL7_IRQ 17
-#define NVIC_ADC1_2_IRQ 18
-#define NVIC_USB_HP_CAN_TX_IRQ 19
-#define NVIC_USB_LP_CAN_RX0_IRQ 20
-#define NVIC_CAN_RX1_IRQ 21
-#define NVIC_CAN_SCE_IRQ 22
-#define NVIC_EXTI9_5_IRQ 23
-#define NVIC_TIM1_BRK_IRQ 24
-#define NVIC_TIM1_UP_IRQ 25
-#define NVIC_TIM1_TRG_COM_IRQ 26
-#define NVIC_TIM1_CC_IRQ 27
-#define NVIC_TIM2_IRQ 28
-#define NVIC_TIM3_IRQ 29
-#define NVIC_TIM4_IRQ 30
-#define NVIC_I2C1_EV_IRQ 31
-#define NVIC_I2C1_ER_IRQ 32
-#define NVIC_I2C2_EV_IRQ 33
-#define NVIC_I2C2_ER_IRQ 34
-#define NVIC_SPI1_IRQ 35
-#define NVIC_SPI2_IRQ 36
-#define NVIC_USART1_IRQ 37
-#define NVIC_USART2_IRQ 38
-#define NVIC_USART3_IRQ 39
-#define NVIC_EXTI15_10_IRQ 40
-#define NVIC_RTC_ALARM_IRQ 41
-#define NVIC_USB_WAKEUP_IRQ 42
-#define NVIC_TIM8_BRK_IRQ 43
-#define NVIC_TIM8_UP_IRQ 44
-#define NVIC_TIM8_TRG_COM_IRQ 45
-#define NVIC_TIM8_CC_IRQ 46
-#define NVIC_ADC3_IRQ 47
-#define NVIC_FSMC_IRQ 48
-#define NVIC_SDIO_IRQ 49
-#define NVIC_TIM5_IRQ 50
-#define NVIC_SPI3_IRQ 51
-#define NVIC_UART4_IRQ 52
-#define NVIC_UART5_IRQ 53
-#define NVIC_TIM6_IRQ 54
-#define NVIC_TIM7_IRQ 55
-#define NVIC_DMA2_CHANNEL1_IRQ 56
-#define NVIC_DMA2_CHANNEL2_IRQ 57
-#define NVIC_DMA2_CHANNEL3_IRQ 58
-#define NVIC_DMA2_CHANNEL4_5_IRQ 59
-#define NVIC_DMA2_CHANNEL5_IRQ 60
-#define NVIC_ETH_IRQ 61
-#define NVIC_ETH_WKUP_IRQ 62
-#define NVIC_CAN2_TX_IRQ 63
-#define NVIC_CAN2_RX0_IRQ 64
-#define NVIC_CAN2_RX1_IRQ 65
-#define NVIC_CAN2_SCE_IRQ 66
-#define NVIC_OTG_FS_IRQ 67
-/**@}*/
-
-#endif
diff --git a/include/libopencm3/stm32/f1/scb.h b/include/libopencm3/stm32/f1/scb.h
deleted file mode 100644
index 181aa7a..0000000
--- a/include/libopencm3/stm32/f1/scb.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
- * Copyright (C) 2010 Thomas Otto <tommi@viadmin.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/>.
- */
-
-#ifndef LIBOPENCM3_SCB_H
-#define LIBOPENCM3_SCB_H
-
-#include <libopencm3/stm32/memorymap.h>
-#include <libopencm3/cm3/common.h>
-
-/* --- SCB: Registers ------------------------------------------------------ */
-
-/* CPUID: CPUID base register */
-#define SCB_CPUID MMIO32(SCB_BASE + 0x00)
-
-/* ICSR: Interrupt Control State Register */
-#define SCB_ICSR MMIO32(SCB_BASE + 0x04)
-
-/* VTOR: Vector Table Offset Register */
-#define SCB_VTOR MMIO32(SCB_BASE + 0x08)
-
-/* AIRCR: Application Interrupt and Reset Control Register */
-#define SCB_AIRCR MMIO32(SCB_BASE + 0x0C)
-
-/* SCR: System Control Register */
-#define SCB_SCR MMIO32(SCB_BASE + 0x10)
-
-/* CCR: Configuration Control Register */
-#define SCB_CCR MMIO32(SCB_BASE + 0x14)
-
-/* SHP: System Handler Priority Registers */
-/* Note: 12 8bit registers */
-#define SCB_SHPR(shpr_id) MMIO8(SCB_BASE + 0x18 + shpr_id)
-#define SCB_SHPR1 MMIO8(SCB_BASE + 0x18 + 1)
-#define SCB_SHPR2 MMIO8(SCB_BASE + 0x18 + 2)
-#define SCB_SHPR3 MMIO8(SCB_BASE + 0x18 + 3)
-
-/* SHCSR: System Handler Control and State Register */
-#define SCB_SHCSR MMIO32(SCB_BASE + 0x24)
-
-/* CFSR: Configurable Fault Status Registers */
-#define SCB_CFSR MMIO32(SCB_BASE + 0x28)
-
-/* HFSR: Hard Fault Status Register */
-#define SCB_HFSR MMIO32(SCB_BASE + 0x2C)
-
-/* DFSR: Debug Fault Status Register */
-#define SCB_DFSR MMIO32(SCB_BASE + 0x30)
-
-/* MMFAR: Memory Manage Fault Address Register */
-#define SCB_MMFAR MMIO32(SCB_BASE + 0x34)
-
-/* BFAR: Bus Fault Address Register */
-#define SCB_BFAR MMIO32(SCB_BASE + 0x38)
-
-/* AFSR: Auxiliary Fault Status Register */
-#define SCB_AFSR MMIO32(SCB_BASE + 0x3C)
-
-/* --- SCB values ---------------------------------------------------------- */
-
-/* --- SCB_CPUID values ---------------------------------------------------- */
-
-/* Implementer[31:24]: Implementer code */
-#define SCP_CPUID_IMPLEMENTER_LSB 24
-/* Variant[23:20]: Variant number */
-#define SCP_CPUID_VARIANT_LSB 20
-/* Constant[19:16]: Reads as 0xF */
-#define SCP_CPUID_CONSTANT_LSB 16
-/* PartNo[15:4]: Part number of the processor */
-#define SCP_CPUID_PARTNO_LSB 4
-/* Revision[3:0]: Revision number */
-#define SCP_CPUID_REVISION_LSB 0
-
-/* --- SCB_ICSR values ----------------------------------------------------- */
-
-/* NMIPENDSET: NMI set-pending bit */
-#define SCB_ICSR_NMIPENDSET (1 << 31)
-/* Bits [30:29]: reserved - must be kept cleared */
-/* PENDSVSET: PendSV set-pending bit */
-#define SCB_ICSR_PENDSVSET (1 << 28)
-/* PENDSVCLR: PendSV clear-pending bit */
-#define SCB_ICSR_PENDSVCLR (1 << 27)
-/* PENDSTSET: SysTick exception set-pending bit */
-#define SCB_ICSR_PENDSTSET (1 << 26)
-/* PENDSTCLR: SysTick exception clear-pending bit */
-#define SCB_ICSR_PENDSTCLR (1 << 25)
-/* Bit 24: reserved - must be kept cleared */
-/* Bit 23: reserved for debug - reads as 0 when not in debug mode */
-/* ISRPENDING: Interrupt pending flag, excluding NMI and Faults */
-#define SCB_ICSR_ISRPENDING (1 << 22)
-/* VECTPENDING[21:12] Pending vector */
-#define SCB_ICSR_VECTPENDING_LSB 12
-/* RETOBASE: Return to base level */
-#define SCB_ICSR_RETOBASE (1 << 11)
-/* Bits [10:9]: reserved - must be kept cleared */
-/* VECTACTIVE[8:0] Active vector */
-#define SCB_ICSR_VECTACTIVE_LSB 0
-
-/* --- SCB_VTOR values ----------------------------------------------------- */
-
-/* Bits [31:30]: reserved - must be kept cleared */
-/* TBLOFF[29:9]: Vector table base offset field */
-#define SCB_VTOR_TBLOFF_LSB 9 /* inconsistent datasheet - LSB could be 11 */
-
-/* --- SCB_AIRCR values ---------------------------------------------------- */
-
-/* VECTKEYSTAT[31:16]/ VECTKEY[31:16] Register key */
-#define SCB_AIRCR_VECTKEYSTAT_LSB 16
-#define SCB_AIRCR_VECTKEY 0x05FA0000
-/* ENDIANESS Data endianness bit */
-#define SCB_AIRCR_ENDIANESS (1 << 15)
-/* Bits [14:11]: reserved - must be kept cleared */
-/* PRIGROUP[10:8]: Interrupt priority grouping field */
-#define SCB_AIRCR_PRIGROUP_GROUP16_NOSUB (0x3 << 8)
-#define SCB_AIRCR_PRIGROUP_GROUP8_SUB2 (0x4 << 8)
-#define SCB_AIRCR_PRIGROUP_GROUP4_SUB4 (0x5 << 8)
-#define SCB_AIRCR_PRIGROUP_GROUP2_SUB8 (0x6 << 8)
-#define SCB_AIRCR_PRIGROUP_NOGROUP_SUB16 (0x7 << 8)
-#define SCB_AIRCR_PRIGROUP_MASK (0x7 << 8)
-#define SCB_AIRCR_PRIGROUP_SHIFT 8
-/* Bits [7:3]: reserved - must be kept cleared */
-/* SYSRESETREQ System reset request */
-#define SCB_AIRCR_SYSRESETREQ (1 << 2)
-/* VECTCLRACTIVE */
-#define SCB_AIRCR_VECTCLRACTIVE (1 << 1)
-/* VECTRESET */
-#define SCB_AIRCR_VECTRESET (1 << 0)
-
-/* --- SCB_SCR values ------------------------------------------------------ */
-
-/* Bits [31:5]: reserved - must be kept cleared */
-/* SEVEONPEND Send Event on Pending bit */
-#define SCB_SCR_SEVEONPEND (1 << 4)
-/* Bit 3: reserved - must be kept cleared */
-/* SLEEPDEEP */
-#define SCB_SCR_SLEEPDEEP (1 << 2)
-/* SLEEPONEXIT */
-#define SCB_SCR_SLEEPONEXIT (1 << 1)
-/* Bit 0: reserved - must be kept cleared */
-
-/* --- SCB_CCR values ------------------------------------------------------ */
-
-/* Bits [31:10]: reserved - must be kept cleared */
-/* STKALIGN */
-#define SCB_CCR_STKALIGN (1 << 9)
-/* BFHFNMIGN */
-#define SCB_CCR_BFHFNMIGN (1 << 8)
-/* Bits [7:5]: reserved - must be kept cleared */
-/* DIV_0_TRP */
-#define SCB_CCR_DIV_0_TRP (1 << 4)
-/* UNALIGN_TRP */
-#define SCB_CCR_UNALIGN_TRP (1 << 3)
-/* Bit 2: reserved - must be kept cleared */
-/* USERSETMPEND */
-#define SCB_CCR_USERSETMPEND (1 << 1)
-/* NONBASETHRDENA */
-#define SCB_CCR_NONBASETHRDENA (1 << 0)
-
-/* --- SCB_SHPR1 values ---------------------------------------------------- */
-
-/* Bits [31:24]: reserved - must be kept cleared */
-/* PRI_6[23:16]: Priority of system handler 6, usage fault */
-#define SCB_SHPR1_PRI_6_LSB 16
-/* PRI_5[15:8]: Priority of system handler 5, bus fault */
-#define SCB_SHPR1_PRI_5_LSB 8
-/* PRI_4[7:0]: Priority of system handler 4, memory management fault */
-#define SCB_SHPR1_PRI_4_LSB 0
-
-/* --- SCB_SHPR2 values ---------------------------------------------------- */
-
-/* PRI_11[31:24]: Priority of system handler 11, SVCall */
-#define SCB_SHPR2_PRI_11_LSB 24
-/* Bits [23:0]: reserved - must be kept cleared */
-
-/* --- SCB_SHPR3 values ---------------------------------------------------- */
-
-/* PRI_15[31:24]: Priority of system handler 15, SysTick exception */
-#define SCB_SHPR3_PRI_15_LSB 24
-/* PRI_14[23:16]: Priority of system handler 14, PendSV */
-#define SCB_SHPR3_PRI_14_LSB 16
-/* Bits [15:0]: reserved - must be kept cleared */
-
-/* --- SCB_SHCSR values ---------------------------------------------------- */
-
-/* Bits [31:19]: reserved - must be kept cleared */
-/* USGFAULTENA: Usage fault enable */
-#define SCB_SHCSR_USGFAULTENA (1 << 18)
-/* BUSFAULTENA: Bus fault enable */
-#define SCB_SHCSR_BUSFAULTENA (1 << 17)
-/* MEMFAULTENA: Memory management fault enable */
-#define SCB_SHCSR_MEMFAULTENA (1 << 16)
-/* SVCALLPENDED: SVC call pending */
-#define SCB_SHCSR_SVCALLPENDED (1 << 15)
-/* BUSFAULTPENDED: Bus fault exception pending */
-#define SCB_SHCSR_BUSFAULTPENDED (1 << 14)
-/* MEMFAULTPENDED: Memory management fault exception pending */
-#define SCB_SHCSR_MEMFAULTPENDED (1 << 13)
-/* USGFAULTPENDED: Usage fault exception pending */
-#define SCB_SHCSR_USGFAULTPENDED (1 << 12)
-/* SYSTICKACT: SysTick exception active */
-#define SCB_SHCSR_SYSTICKACT (1 << 11)
-/* PENDSVACT: PendSV exception active */
-#define SCB_SHCSR_PENDSVACT (1 << 10)
-/* Bit 9: reserved - must be kept cleared */
-/* MONITORACT: Debug monitor active */
-#define SCB_SHCSR_MONITORACT (1 << 8)
-/* SVCALLACT: SVC call active */
-#define SCB_SHCSR_SVCALLACT (1 << 7)
-/* Bits [6:4]: reserved - must be kept cleared */
-/* USGFAULTACT: Usage fault exception active */
-#define SCB_SHCSR_USGFAULTACT (1 << 3)
-/* Bit 2: reserved - must be kept cleared */
-/* BUSFAULTACT: Bus fault exception active */
-#define SCB_SHCSR_BUSFAULTACT (1 << 1)
-/* MEMFAULTACT: Memory management fault exception active */
-#define SCB_SHCSR_MEMFAULTACT (1 << 0)
-
-/* --- SCB_CFSR values ----------------------------------------------------- */
-
-/* Bits [31:26]: reserved - must be kept cleared */
-/* DIVBYZERO: Divide by zero usage fault */
-#define SCB_CFSR_DIVBYZERO (1 << 25)
-/* UNALIGNED: Unaligned access usage fault */
-#define SCB_CFSR_UNALIGNED (1 << 24)
-/* Bits [23:20]: reserved - must be kept cleared */
-/* NOCP: No coprocessor usage fault */
-#define SCB_CFSR_NOCP (1 << 19)
-/* INVPC: Invalid PC load usage fault */
-#define SCB_CFSR_INVPC (1 << 18)
-/* INVSTATE: Invalid state usage fault */
-#define SCB_CFSR_INVSTATE (1 << 17)
-/* UNDEFINSTR: Undefined instruction usage fault */
-#define SCB_CFSR_UNDEFINSTR (1 << 16)
-/* BFARVALID: Bus Fault Address Register (BFAR) valid flag */
-#define SCB_CFSR_BFARVALID (1 << 15)
-/* Bits [14:13]: reserved - must be kept cleared */
-/* STKERR: Bus fault on stacking for exception entry */
-#define SCB_CFSR_STKERR (1 << 12)
-/* UNSTKERR: Bus fault on unstacking for a return from exception */
-#define SCB_CFSR_UNSTKERR (1 << 11)
-/* IMPRECISERR: Imprecise data bus error */
-#define SCB_CFSR_IMPRECISERR (1 << 10)
-/* PRECISERR: Precise data bus error */
-#define SCB_CFSR_PRECISERR (1 << 9)
-/* IBUSERR: Instruction bus error */
-#define SCB_CFSR_IBUSERR (1 << 8)
-/* MMARVALID: Memory Management Fault Address Register (MMAR) valid flag */
-#define SCB_CFSR_MMARVALID (1 << 7)
-/* Bits [6:5]: reserved - must be kept cleared */
-/* MSTKERR: Memory manager fault on stacking for exception entry */
-#define SCB_CFSR_MSTKERR (1 << 4)
-/* MUNSTKERR: Memory manager fault on unstacking for a return from exception */
-#define SCB_CFSR_MUNSTKERR (1 << 3)
-/* Bit 2: reserved - must be kept cleared */
-/* DACCVIOL: Data access violation flag */
-#define SCB_CFSR_DACCVIOL (1 << 1)
-/* IACCVIOL: Instruction access violation flag */
-#define SCB_CFSR_IACCVIOL (1 << 0)
-
-/* --- SCB_HFSR values ----------------------------------------------------- */
-
-/* DEBUG_VT: reserved for debug use */
-#define SCB_HFSR_DEBUG_VT (1 << 31)
-/* FORCED: Forced hard fault */
-#define SCB_HFSR_FORCED (1 << 30)
-/* Bits [29:2]: reserved - must be kept cleared */
-/* VECTTBL: Vector table hard fault */
-#define SCB_HFSR_VECTTBL (1 << 1)
-/* Bit 0: reserved - must be kept cleared */
-
-/* --- SCB_MMFAR values ---------------------------------------------------- */
-
-/* MMFAR [31:0]: Memory management fault address */
-
-/* --- SCB_BFAR values ----------------------------------------------------- */
-
-/* BFAR [31:0]: Bus fault address */
-
-/* --- SCB functions ------------------------------------------------------- */
-
-BEGIN_DECLS
-
-void scb_reset_core(void);
-void scb_reset_system(void);
-void scb_set_priority_grouping(u32 prigroup);
-
-/* TODO: */
-
-END_DECLS
-
-#endif
diff --git a/include/libopencm3/stm32/f2/irq.yaml b/include/libopencm3/stm32/f2/irq.yaml
new file mode 100644
index 0000000..c3600b3
--- /dev/null
+++ b/include/libopencm3/stm32/f2/irq.yaml
@@ -0,0 +1,85 @@
+includeguard: LIBOPENCM3_STM32_F2_NVIC_H
+partname_humanreadable: STM32 F2 series
+partname_doxygen: STM32F2
+irqs:
+ - nvic_wwdg
+ - pvd
+ - tamp_stamp
+ - rtc_wkup
+ - flash
+ - rcc
+ - exti0
+ - exti1
+ - exti2
+ - exti3
+ - exti4
+ - dma1_stream0
+ - dma1_stream1
+ - dma1_stream2
+ - dma1_stream3
+ - dma1_stream4
+ - dma1_stream5
+ - dma1_stream6
+ - adc
+ - can1_tx
+ - can1_rx0
+ - can1_rx1
+ - can1_sce
+ - exti9_5
+ - tim1_brk_tim9
+ - tim1_up_tim10
+ - tim1_trg_com_tim11
+ - tim1_cc
+ - tim2
+ - tim3
+ - tim4
+ - i2c1_ev
+ - i2c1_er
+ - i2c2_ev
+ - i2c2_er
+ - spi1
+ - spi2
+ - usart1
+ - usart2
+ - usart3
+ - exti15_10
+ - rtc_alarm
+ - usb_fs_wkup
+ - tim8_brk_tim12
+ - tim8_up_tim13
+ - tim8_trg_com_tim14
+ - tim8_cc
+ - dma1_stream7
+ - fsmc
+ - sdio
+ - tim5
+ - spi3
+ - uart4
+ - uart5
+ - tim6_dac
+ - tim7
+ - dma2_stream0
+ - dma2_stream1
+ - dma2_stream2
+ - dma2_stream3
+ - dma2_stream4
+ - eth
+ - eth_wkup
+ - can2_tx
+ - can2_rx0
+ - can2_rx1
+ - can2_sce
+ - otg_fs
+ - dma2_stream5
+ - dma2_stream6
+ - dma2_stream7
+ - usart6
+ - i2c3_ev
+ - i2c3_er
+ - otg_hs_ep1_out
+ - otg_hs_ep1_in
+ - otg_hs_wkup
+ - otg_hs
+ - dcmi
+ - cryp
+ - hash_rng
diff --git a/include/libopencm3/stm32/f2/nvic_f2.h b/include/libopencm3/stm32/f2/nvic_f2.h
deleted file mode 100644
index 2bf2997..0000000
--- a/include/libopencm3/stm32/f2/nvic_f2.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
- *
- * 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/>.
- */
-
-#ifndef LIBOPENCM3_NVIC_F2_H
-#define LIBOPENCM3_NVIC_F2_H
-
-/* --- IRQ channel numbers-------------------------------------------------- */
-
-/* Note: These F2 specific user interrupt definitions supplement the
- * general NVIC definitions in ../nvic.h
- */
-
-/* User Interrupts */
-#define NVIC_NVIC_WWDG_IRQ 0
-#define NVIC_PVD_IRQ 1
-#define NVIC_TAMP_STAMP_IRQ 2
-#define NVIC_RTC_WKUP_IRQ 3
-#define NVIC_FLASH_IRQ 4
-#define NVIC_RCC_IRQ 5
-#define NVIC_EXTI0_IRQ 6
-#define NVIC_EXTI1_IRQ 7
-#define NVIC_EXTI2_IRQ 8
-#define NVIC_EXTI3_IRQ 9
-#define NVIC_EXTI4_IRQ 10
-#define NVIC_DMA1_STREAM0_IRQ 11
-#define NVIC_DMA1_STREAM1_IRQ 12
-#define NVIC_DMA1_STREAM2_IRQ 13
-#define NVIC_DMA1_STREAM3_IRQ 14
-#define NVIC_DMA1_STREAM4_IRQ 15
-#define NVIC_DMA1_STREAM5_IRQ 16
-#define NVIC_DMA1_STREAM6_IRQ 17
-#define NVIC_ADC_IRQ 18
-#define NVIC_CAN1_TX_IRQ 19
-#define NVIC_CAN1_RX0_IRQ 20
-#define NVIC_CAN1_RX1_IRQ 21
-#define NVIC_CAN1_SCE_IRQ 22
-#define NVIC_EXTI9_5_IRQ 23
-#define NVIC_TIM1_BRK_TIM9_IRQ 24
-#define NVIC_TIM1_UP_TIM10_IRQ 25
-#define NVIC_TIM1_TRG_COM_TIM11_IRQ 26
-#define NVIC_TIM1_CC_IRQ 27
-#define NVIC_TIM2_IRQ 28
-#define NVIC_TIM3_IRQ 29
-#define NVIC_TIM4_IRQ 30
-#define NVIC_I2C1_EV_IRQ 31
-#define NVIC_I2C1_ER_IRQ 32
-#define NVIC_I2C2_EV_IRQ 33
-#define NVIC_I2C2_ER_IRQ 34
-#define NVIC_SPI1_IRQ 35
-#define NVIC_SPI2_IRQ 36
-#define NVIC_USART1_IRQ 37
-#define NVIC_USART2_IRQ 38
-#define NVIC_USART3_IRQ 39
-#define NVIC_EXTI15_10_IRQ 40
-#define NVIC_RTC_ALARM_IRQ 41
-#define NVIC_USB_FS_WKUP_IRQ 42
-#define NVIC_TIM8_BRK_TIM12_IRQ 43
-#define NVIC_TIM8_UP_TIM13_IRQ 44
-#define NVIC_TIM8_TRG_COM_TIM14_IRQ 45
-#define NVIC_TIM8_CC_IRQ 46
-#define NVIC_DMA1_STREAM7_IRQ 47
-#define NVIC_FSMC_IRQ 48
-#define NVIC_SDIO_IRQ 49
-#define NVIC_TIM5_IRQ 50
-#define NVIC_SPI3_IRQ 51
-#define NVIC_UART4_IRQ 52
-#define NVIC_UART5_IRQ 53
-#define NVIC_TIM6_DAC_IRQ 54
-#define NVIC_TIM7_IRQ 55
-#define NVIC_DMA2_STREAM0_IRQ 56
-#define NVIC_DMA2_STREAM1_IRQ 57
-#define NVIC_DMA2_STREAM2_IRQ 58
-#define NVIC_DMA2_STREAM3_IRQ 59
-#define NVIC_DMA2_STREAM4_IRQ 60
-#define NVIC_ETH_IRQ 61
-#define NVIC_ETH_WKUP_IRQ 62
-#define NVIC_CAN2_TX_IRQ 63
-#define NVIC_CAN2_RX0_IRQ 64
-#define NVIC_CAN2_RX1_IRQ 65
-#define NVIC_CAN2_SCE_IRQ 66
-#define NVIC_OTG_FS_IRQ 67
-#define NVIC_DMA2_STREAM5_IRQ 68
-#define NVIC_DMA2_STREAM6_IRQ 69
-#define NVIC_DMA2_STREAM7_IRQ 70
-#define NVIC_USART6_IRQ 71
-#define NVIC_I2C3_EV_IRQ 72
-#define NVIC_I2C3_ER_IRQ 73
-#define NVIC_OTG_HS_EP1_OUT_IRQ 74
-#define NVIC_OTG_HS_EP1_IN_IRQ 75
-#define NVIC_OTG_HS_WKUP_IRQ 76
-#define NVIC_OTG_HS_IRQ 77
-#define NVIC_DCMI_IRQ 78
-#define NVIC_CRYP_IRQ 79
-#define NVIC_HASH_RNG_IRQ 80
-
-#endif
diff --git a/include/libopencm3/stm32/f2/scb.h b/include/libopencm3/stm32/f2/scb.h
deleted file mode 100644
index 181aa7a..0000000
--- a/include/libopencm3/stm32/f2/scb.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
- * Copyright (C) 2010 Thomas Otto <tommi@viadmin.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/>.
- */
-
-#ifndef LIBOPENCM3_SCB_H
-#define LIBOPENCM3_SCB_H
-
-#include <libopencm3/stm32/memorymap.h>
-#include <libopencm3/cm3/common.h>
-
-/* --- SCB: Registers ------------------------------------------------------ */
-
-/* CPUID: CPUID base register */
-#define SCB_CPUID MMIO32(SCB_BASE + 0x00)
-
-/* ICSR: Interrupt Control State Register */
-#define SCB_ICSR MMIO32(SCB_BASE + 0x04)
-
-/* VTOR: Vector Table Offset Register */
-#define SCB_VTOR MMIO32(SCB_BASE + 0x08)
-
-/* AIRCR: Application Interrupt and Reset Control Register */
-#define SCB_AIRCR MMIO32(SCB_BASE + 0x0C)
-
-/* SCR: System Control Register */
-#define SCB_SCR MMIO32(SCB_BASE + 0x10)
-
-/* CCR: Configuration Control Register */
-#define SCB_CCR MMIO32(SCB_BASE + 0x14)
-
-/* SHP: System Handler Priority Registers */
-/* Note: 12 8bit registers */
-#define SCB_SHPR(shpr_id) MMIO8(SCB_BASE + 0x18 + shpr_id)
-#define SCB_SHPR1 MMIO8(SCB_BASE + 0x18 + 1)
-#define SCB_SHPR2 MMIO8(SCB_BASE + 0x18 + 2)
-#define SCB_SHPR3 MMIO8(SCB_BASE + 0x18 + 3)
-
-/* SHCSR: System Handler Control and State Register */
-#define SCB_SHCSR MMIO32(SCB_BASE + 0x24)
-
-/* CFSR: Configurable Fault Status Registers */
-#define SCB_CFSR MMIO32(SCB_BASE + 0x28)
-
-/* HFSR: Hard Fault Status Register */
-#define SCB_HFSR MMIO32(SCB_BASE + 0x2C)
-
-/* DFSR: Debug Fault Status Register */
-#define SCB_DFSR MMIO32(SCB_BASE + 0x30)
-
-/* MMFAR: Memory Manage Fault Address Register */
-#define SCB_MMFAR MMIO32(SCB_BASE + 0x34)
-
-/* BFAR: Bus Fault Address Register */
-#define SCB_BFAR MMIO32(SCB_BASE + 0x38)
-
-/* AFSR: Auxiliary Fault Status Register */
-#define SCB_AFSR MMIO32(SCB_BASE + 0x3C)
-
-/* --- SCB values ---------------------------------------------------------- */
-
-/* --- SCB_CPUID values ---------------------------------------------------- */
-
-/* Implementer[31:24]: Implementer code */
-#define SCP_CPUID_IMPLEMENTER_LSB 24
-/* Variant[23:20]: Variant number */
-#define SCP_CPUID_VARIANT_LSB 20
-/* Constant[19:16]: Reads as 0xF */
-#define SCP_CPUID_CONSTANT_LSB 16
-/* PartNo[15:4]: Part number of the processor */
-#define SCP_CPUID_PARTNO_LSB 4
-/* Revision[3:0]: Revision number */
-#define SCP_CPUID_REVISION_LSB 0
-
-/* --- SCB_ICSR values ----------------------------------------------------- */
-
-/* NMIPENDSET: NMI set-pending bit */
-#define SCB_ICSR_NMIPENDSET (1 << 31)
-/* Bits [30:29]: reserved - must be kept cleared */
-/* PENDSVSET: PendSV set-pending bit */
-#define SCB_ICSR_PENDSVSET (1 << 28)
-/* PENDSVCLR: PendSV clear-pending bit */
-#define SCB_ICSR_PENDSVCLR (1 << 27)
-/* PENDSTSET: SysTick exception set-pending bit */
-#define SCB_ICSR_PENDSTSET (1 << 26)
-/* PENDSTCLR: SysTick exception clear-pending bit */
-#define SCB_ICSR_PENDSTCLR (1 << 25)
-/* Bit 24: reserved - must be kept cleared */
-/* Bit 23: reserved for debug - reads as 0 when not in debug mode */
-/* ISRPENDING: Interrupt pending flag, excluding NMI and Faults */
-#define SCB_ICSR_ISRPENDING (1 << 22)
-/* VECTPENDING[21:12] Pending vector */
-#define SCB_ICSR_VECTPENDING_LSB 12
-/* RETOBASE: Return to base level */
-#define SCB_ICSR_RETOBASE (1 << 11)
-/* Bits [10:9]: reserved - must be kept cleared */
-/* VECTACTIVE[8:0] Active vector */
-#define SCB_ICSR_VECTACTIVE_LSB 0
-
-/* --- SCB_VTOR values ----------------------------------------------------- */
-
-/* Bits [31:30]: reserved - must be kept cleared */
-/* TBLOFF[29:9]: Vector table base offset field */
-#define SCB_VTOR_TBLOFF_LSB 9 /* inconsistent datasheet - LSB could be 11 */
-
-/* --- SCB_AIRCR values ---------------------------------------------------- */
-
-/* VECTKEYSTAT[31:16]/ VECTKEY[31:16] Register key */
-#define SCB_AIRCR_VECTKEYSTAT_LSB 16
-#define SCB_AIRCR_VECTKEY 0x05FA0000
-/* ENDIANESS Data endianness bit */
-#define SCB_AIRCR_ENDIANESS (1 << 15)
-/* Bits [14:11]: reserved - must be kept cleared */
-/* PRIGROUP[10:8]: Interrupt priority grouping field */
-#define SCB_AIRCR_PRIGROUP_GROUP16_NOSUB (0x3 << 8)
-#define SCB_AIRCR_PRIGROUP_GROUP8_SUB2 (0x4 << 8)
-#define SCB_AIRCR_PRIGROUP_GROUP4_SUB4 (0x5 << 8)
-#define SCB_AIRCR_PRIGROUP_GROUP2_SUB8 (0x6 << 8)
-#define SCB_AIRCR_PRIGROUP_NOGROUP_SUB16 (0x7 << 8)
-#define SCB_AIRCR_PRIGROUP_MASK (0x7 << 8)
-#define SCB_AIRCR_PRIGROUP_SHIFT 8
-/* Bits [7:3]: reserved - must be kept cleared */
-/* SYSRESETREQ System reset request */
-#define SCB_AIRCR_SYSRESETREQ (1 << 2)
-/* VECTCLRACTIVE */
-#define SCB_AIRCR_VECTCLRACTIVE (1 << 1)
-/* VECTRESET */
-#define SCB_AIRCR_VECTRESET (1 << 0)
-
-/* --- SCB_SCR values ------------------------------------------------------ */
-
-/* Bits [31:5]: reserved - must be kept cleared */
-/* SEVEONPEND Send Event on Pending bit */
-#define SCB_SCR_SEVEONPEND (1 << 4)
-/* Bit 3: reserved - must be kept cleared */
-/* SLEEPDEEP */
-#define SCB_SCR_SLEEPDEEP (1 << 2)
-/* SLEEPONEXIT */
-#define SCB_SCR_SLEEPONEXIT (1 << 1)
-/* Bit 0: reserved - must be kept cleared */
-
-/* --- SCB_CCR values ------------------------------------------------------ */
-
-/* Bits [31:10]: reserved - must be kept cleared */
-/* STKALIGN */
-#define SCB_CCR_STKALIGN (1 << 9)
-/* BFHFNMIGN */
-#define SCB_CCR_BFHFNMIGN (1 << 8)
-/* Bits [7:5]: reserved - must be kept cleared */
-/* DIV_0_TRP */
-#define SCB_CCR_DIV_0_TRP (1 << 4)
-/* UNALIGN_TRP */
-#define SCB_CCR_UNALIGN_TRP (1 << 3)
-/* Bit 2: reserved - must be kept cleared */
-/* USERSETMPEND */
-#define SCB_CCR_USERSETMPEND (1 << 1)
-/* NONBASETHRDENA */
-#define SCB_CCR_NONBASETHRDENA (1 << 0)
-
-/* --- SCB_SHPR1 values ---------------------------------------------------- */
-
-/* Bits [31:24]: reserved - must be kept cleared */
-/* PRI_6[23:16]: Priority of system handler 6, usage fault */
-#define SCB_SHPR1_PRI_6_LSB 16
-/* PRI_5[15:8]: Priority of system handler 5, bus fault */
-#define SCB_SHPR1_PRI_5_LSB 8
-/* PRI_4[7:0]: Priority of system handler 4, memory management fault */
-#define SCB_SHPR1_PRI_4_LSB 0
-
-/* --- SCB_SHPR2 values ---------------------------------------------------- */
-
-/* PRI_11[31:24]: Priority of system handler 11, SVCall */
-#define SCB_SHPR2_PRI_11_LSB 24
-/* Bits [23:0]: reserved - must be kept cleared */
-
-/* --- SCB_SHPR3 values ---------------------------------------------------- */
-
-/* PRI_15[31:24]: Priority of system handler 15, SysTick exception */
-#define SCB_SHPR3_PRI_15_LSB 24
-/* PRI_14[23:16]: Priority of system handler 14, PendSV */
-#define SCB_SHPR3_PRI_14_LSB 16
-/* Bits [15:0]: reserved - must be kept cleared */
-
-/* --- SCB_SHCSR values ---------------------------------------------------- */
-
-/* Bits [31:19]: reserved - must be kept cleared */
-/* USGFAULTENA: Usage fault enable */
-#define SCB_SHCSR_USGFAULTENA (1 << 18)
-/* BUSFAULTENA: Bus fault enable */
-#define SCB_SHCSR_BUSFAULTENA (1 << 17)
-/* MEMFAULTENA: Memory management fault enable */
-#define SCB_SHCSR_MEMFAULTENA (1 << 16)
-/* SVCALLPENDED: SVC call pending */
-#define SCB_SHCSR_SVCALLPENDED (1 << 15)
-/* BUSFAULTPENDED: Bus fault exception pending */
-#define SCB_SHCSR_BUSFAULTPENDED (1 << 14)
-/* MEMFAULTPENDED: Memory management fault exception pending */
-#define SCB_SHCSR_MEMFAULTPENDED (1 << 13)
-/* USGFAULTPENDED: Usage fault exception pending */
-#define SCB_SHCSR_USGFAULTPENDED (1 << 12)
-/* SYSTICKACT: SysTick exception active */
-#define SCB_SHCSR_SYSTICKACT (1 << 11)
-/* PENDSVACT: PendSV exception active */
-#define SCB_SHCSR_PENDSVACT (1 << 10)
-/* Bit 9: reserved - must be kept cleared */
-/* MONITORACT: Debug monitor active */
-#define SCB_SHCSR_MONITORACT (1 << 8)
-/* SVCALLACT: SVC call active */
-#define SCB_SHCSR_SVCALLACT (1 << 7)
-/* Bits [6:4]: reserved - must be kept cleared */
-/* USGFAULTACT: Usage fault exception active */
-#define SCB_SHCSR_USGFAULTACT (1 << 3)
-/* Bit 2: reserved - must be kept cleared */
-/* BUSFAULTACT: Bus fault exception active */
-#define SCB_SHCSR_BUSFAULTACT (1 << 1)
-/* MEMFAULTACT: Memory management fault exception active */
-#define SCB_SHCSR_MEMFAULTACT (1 << 0)
-
-/* --- SCB_CFSR values ----------------------------------------------------- */
-
-/* Bits [31:26]: reserved - must be kept cleared */
-/* DIVBYZERO: Divide by zero usage fault */
-#define SCB_CFSR_DIVBYZERO (1 << 25)
-/* UNALIGNED: Unaligned access usage fault */
-#define SCB_CFSR_UNALIGNED (1 << 24)
-/* Bits [23:20]: reserved - must be kept cleared */
-/* NOCP: No coprocessor usage fault */
-#define SCB_CFSR_NOCP (1 << 19)
-/* INVPC: Invalid PC load usage fault */
-#define SCB_CFSR_INVPC (1 << 18)
-/* INVSTATE: Invalid state usage fault */
-#define SCB_CFSR_INVSTATE (1 << 17)
-/* UNDEFINSTR: Undefined instruction usage fault */
-#define SCB_CFSR_UNDEFINSTR (1 << 16)
-/* BFARVALID: Bus Fault Address Register (BFAR) valid flag */
-#define SCB_CFSR_BFARVALID (1 << 15)
-/* Bits [14:13]: reserved - must be kept cleared */
-/* STKERR: Bus fault on stacking for exception entry */
-#define SCB_CFSR_STKERR (1 << 12)
-/* UNSTKERR: Bus fault on unstacking for a return from exception */
-#define SCB_CFSR_UNSTKERR (1 << 11)
-/* IMPRECISERR: Imprecise data bus error */
-#define SCB_CFSR_IMPRECISERR (1 << 10)
-/* PRECISERR: Precise data bus error */
-#define SCB_CFSR_PRECISERR (1 << 9)
-/* IBUSERR: Instruction bus error */
-#define SCB_CFSR_IBUSERR (1 << 8)
-/* MMARVALID: Memory Management Fault Address Register (MMAR) valid flag */
-#define SCB_CFSR_MMARVALID (1 << 7)
-/* Bits [6:5]: reserved - must be kept cleared */
-/* MSTKERR: Memory manager fault on stacking for exception entry */
-#define SCB_CFSR_MSTKERR (1 << 4)
-/* MUNSTKERR: Memory manager fault on unstacking for a return from exception */
-#define SCB_CFSR_MUNSTKERR (1 << 3)
-/* Bit 2: reserved - must be kept cleared */
-/* DACCVIOL: Data access violation flag */
-#define SCB_CFSR_DACCVIOL (1 << 1)
-/* IACCVIOL: Instruction access violation flag */
-#define SCB_CFSR_IACCVIOL (1 << 0)
-
-/* --- SCB_HFSR values ----------------------------------------------------- */
-
-/* DEBUG_VT: reserved for debug use */
-#define SCB_HFSR_DEBUG_VT (1 << 31)
-/* FORCED: Forced hard fault */
-#define SCB_HFSR_FORCED (1 << 30)
-/* Bits [29:2]: reserved - must be kept cleared */
-/* VECTTBL: Vector table hard fault */
-#define SCB_HFSR_VECTTBL (1 << 1)
-/* Bit 0: reserved - must be kept cleared */
-
-/* --- SCB_MMFAR values ---------------------------------------------------- */
-
-/* MMFAR [31:0]: Memory management fault address */
-
-/* --- SCB_BFAR values ----------------------------------------------------- */
-
-/* BFAR [31:0]: Bus fault address */
-
-/* --- SCB functions ------------------------------------------------------- */
-
-BEGIN_DECLS
-
-void scb_reset_core(void);
-void scb_reset_system(void);
-void scb_set_priority_grouping(u32 prigroup);
-
-/* TODO: */
-
-END_DECLS
-
-#endif
diff --git a/include/libopencm3/stm32/f4/adc.h b/include/libopencm3/stm32/f4/adc.h
new file mode 100644
index 0000000..272c4c2
--- /dev/null
+++ b/include/libopencm3/stm32/f4/adc.h
@@ -0,0 +1,873 @@
+/** @defgroup STM32F4xx_adc_defines ADC Defines
+
+@brief <b>Defined Constants and Types for the STM32F4xx Analog to Digital Converters</b>
+
+@ingroup STM32F4xx_defines
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2012 Matthew Lai <m@matthewlai.ca>
+@author @htmlonly &copy; @endhtmlonly 2009 Edward Cheeseman <evbuilder@users.sourceforge.net>
+
+@date 31 August 2012
+
+LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Matthew Lai <m@matthewlai.ca>
+ * Copyright (C) 2009 Edward Cheeseman <evbuilder@users.sourceforge.net>
+ *
+ * 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/>.
+ */
+
+#ifndef LIBOPENCM3_ADC_H
+#define LIBOPENCM3_ADC_H
+
+#include <libopencm3/stm32/f4/memorymap.h>
+#include <libopencm3/cm3/common.h>
+
+/* --- Convenience macros -------------------------------------------------- */
+
+/* ADC port base addresses (for convenience) */
+/****************************************************************************/
+/** @defgroup adc_reg_base ADC register base addresses
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC1 ADC1_BASE
+#define ADC2 ADC2_BASE
+#define ADC3 ADC3_BASE
+/**@}*/
+
+/* --- ADC registers ------------------------------------------------------- */
+
+/* ADC status register (ADC_SR) */
+#define ADC_SR(block) MMIO32(block + 0x00)
+#define ADC1_SR ADC_SR(ADC1)
+#define ADC2_SR ADC_SR(ADC2)
+#define ADC3_SR ADC_SR(ADC3)
+
+/* ADC control register 1 (ADC_CR1) */
+#define ADC_CR1(block) MMIO32(block + 0x04)
+#define ADC1_CR1 ADC_CR1(ADC1)
+#define ADC2_CR1 ADC_CR1(ADC2)
+#define ADC3_CR1 ADC_CR1(ADC3)
+
+/* ADC control register 2 (ADC_CR2) */
+#define ADC_CR2(block) MMIO32(block + 0x08)
+#define ADC1_CR2 ADC_CR2(ADC1)
+#define ADC2_CR2 ADC_CR2(ADC2)
+#define ADC3_CR2 ADC_CR2(ADC3)
+
+/* ADC sample time register 1 (ADC_SMPR1) */
+#define ADC_SMPR1(block) MMIO32(block + 0x0c)
+#define ADC1_SMPR1 ADC_SMPR1(ADC1)
+#define ADC2_SMPR1 ADC_SMPR1(ADC2)
+#define ADC3_SMPR1 ADC_SMPR1(ADC3)
+
+/* ADC sample time register 2 (ADC_SMPR2) */
+#define ADC_SMPR2(block) MMIO32(block + 0x10)
+#define ADC1_SMPR2 ADC_SMPR2(ADC1)
+#define ADC2_SMPR2 ADC_SMPR2(ADC2)
+#define ADC3_SMPR2 ADC_SMPR2(ADC3)
+
+/* ADC injected channel data offset register x (ADC_JOFRx) (x=1..4) */
+#define ADC_JOFR1(block) MMIO32(block + 0x14)
+#define ADC_JOFR2(block) MMIO32(block + 0x18)
+#define ADC_JOFR3(block) MMIO32(block + 0x1c)
+#define ADC_JOFR4(block) MMIO32(block + 0x20)
+#define ADC1_JOFR1 ADC_JOFR1(ADC1)
+#define ADC2_JOFR1 ADC_JOFR1(ADC2)
+#define ADC3_JOFR1 ADC_JOFR1(ADC3)
+#define ADC1_JOFR2 ADC_JOFR2(ADC1)
+#define ADC2_JOFR2 ADC_JOFR2(ADC2)
+#define ADC3_JOFR2 ADC_JOFR2(ADC3)
+#define ADC1_JOFR3 ADC_JOFR3(ADC1)
+#define ADC2_JOFR3 ADC_JOFR3(ADC2)
+#define ADC3_JOFR3 ADC_JOFR3(ADC3)
+#define ADC1_JOFR4 ADC_JOFR4(ADC1)
+#define ADC2_JOFR4 ADC_JOFR4(ADC2)
+#define ADC3_JOFR4 ADC_JOFR4(ADC3)
+
+/* ADC watchdog high threshold register (ADC_HTR) */
+#define ADC_HTR(block) MMIO32(block + 0x24)
+#define ADC1_HTR ADC_HTR(ADC1)
+#define ADC2_HTR ADC_HTR(ADC2)
+#define ADC3_HTR ADC_HTR(ADC3)
+
+/* ADC watchdog low threshold register (ADC_LTR) */
+#define ADC_LTR(block) MMIO32(block + 0x28)
+#define ADC1_LTR ADC_LTR(ADC1_BASE)
+#define ADC2_LTR ADC_LTR(ADC2_BASE)
+#define ADC3_LTR ADC_LTR(ADC3_BASE)
+
+/* ADC regular sequence register 1 (ADC_SQR1) */
+#define ADC_SQR1(block) MMIO32(block + 0x2c)
+#define ADC1_SQR1 ADC_SQR1(ADC1)
+#define ADC2_SQR1 ADC_SQR1(ADC2)
+#define ADC3_SQR1 ADC_SQR1(ADC3)
+
+/* ADC regular sequence register 2 (ADC_SQR2) */
+#define ADC_SQR2(block) MMIO32(block + 0x30)
+#define ADC1_SQR2 ADC_SQR2(ADC1)
+#define ADC2_SQR2 ADC_SQR2(ADC2)
+#define ADC3_SQR2 ADC_SQR2(ADC3)
+
+/* ADC regular sequence register 3 (ADC_SQR3) */
+#define ADC_SQR3(block) MMIO32(block + 0x34)
+#define ADC1_SQR3 ADC_SQR3(ADC1)
+#define ADC2_SQR3 ADC_SQR3(ADC2)
+#define ADC3_SQR3 ADC_SQR3(ADC3)
+
+/* ADC injected sequence register (ADC_JSQR) */
+#define ADC_JSQR(block) MMIO32(block + 0x38)
+#define ADC1_JSQR ADC_JSQR(ADC1_BASE)
+#define ADC2_JSQR ADC_JSQR(ADC2_BASE)
+#define ADC3_JSQR ADC_JSQR(ADC3_BASE)
+
+/* ADC injected data register x (ADC_JDRx) (x=1..4) */
+#define ADC_JDR1(block) MMIO32(block + 0x3c)
+#define ADC_JDR2(block) MMIO32(block + 0x40)
+#define ADC_JDR3(block) MMIO32(block + 0x44)
+#define ADC_JDR4(block) MMIO32(block + 0x48)
+#define ADC1_JDR1 ADC_JDR1(ADC1)
+#define ADC2_JDR1 ADC_JDR1(ADC2)
+#define ADC3_JDR1 ADC_JDR1(ADC3)
+#define ADC1_JDR2 ADC_JDR2(ADC1)
+#define ADC2_JDR2 ADC_JDR2(ADC2)
+#define ADC3_JDR2 ADC_JDR2(ADC3)
+#define ADC1_JDR3 ADC_JDR3(ADC1)
+#define ADC2_JDR3 ADC_JDR3(ADC2)
+#define ADC3_JDR3 ADC_JDR3(ADC3)
+#define ADC1_JDR4 ADC_JDR4(ADC1)
+#define ADC2_JDR4 ADC_JDR4(ADC2)
+#define ADC3_JDR4 ADC_JDR4(ADC3)
+
+/* ADC regular data register (ADC_DR) */
+#define ADC_DR(block) MMIO32(block + 0x4c)
+#define ADC1_DR ADC_DR(ADC1)
+#define ADC2_DR ADC_DR(ADC2)
+#define ADC3_DR ADC_DR(ADC3)
+
+/* ADC common (shared) registers */
+#define ADC_COMMON_REGISTERS_BASE (ADC1_BASE+0x300)
+#define ADC_CSR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x0)
+#define ADC_CCR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x4)
+#define ADC_CDR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x8)
+
+/* --- ADC Channels ------------------------------------------------------- */
+
+/****************************************************************************/
+/** @defgroup adc_channel ADC Channel Numbers
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CHANNEL0 0x00
+#define ADC_CHANNEL1 0x01
+#define ADC_CHANNEL2 0x02
+#define ADC_CHANNEL3 0x03
+#define ADC_CHANNEL4 0x04
+#define ADC_CHANNEL5 0x05
+#define ADC_CHANNEL6 0x06
+#define ADC_CHANNEL7 0x07
+#define ADC_CHANNEL8 0x08
+#define ADC_CHANNEL9 0x09
+#define ADC_CHANNEL10 0x0A
+#define ADC_CHANNEL11 0x0B
+#define ADC_CHANNEL12 0x0C
+#define ADC_CHANNEL13 0x0D
+#define ADC_CHANNEL14 0x0E
+#define ADC_CHANNEL15 0x0F
+#define ADC_CHANNEL16 0x10
+#define ADC_CHANNEL17 0x11
+#define ADC_CHANNEL18 0x12
+/**@}*/
+#define ADC_MASK 0x1F
+#define ADC_SHIFT 0
+
+/* --- ADC_SR values ------------------------------------------------------- */
+
+#define ADC_SR_OVR (1 << 5)
+#define ADC_SR_STRT (1 << 4)
+#define ADC_SR_JSTRT (1 << 3)
+#define ADC_SR_JEOC (1 << 2)
+#define ADC_SR_EOC (1 << 1)
+#define ADC_SR_AWD (1 << 0)
+
+/* --- ADC_CR1 values specific to STM32F2,4------------------------------------ */
+
+/* OVRIE: Overrun interrupt enable */
+#define ADC_CR1_OVRIE (1 << 26)
+
+/* RES[1:0]: Resolution */
+/****************************************************************************/
+/** @defgroup adc_cr1_res ADC Resolution.
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CR1_RES_12BIT (0x0 << 24)
+#define ADC_CR1_RES_10BIT (0x1 << 24)
+#define ADC_CR1_RES_8BIT (0x2 << 24)
+#define ADC_CR1_RES_6BIT (0x3 << 24)
+/**@}*/
+#define ADC_CR1_RES_MASK (0x3 << 24)
+#define ADC_CR1_RES_SHIFT 24
+
+/* Note: Bits [21:16] are reserved, and must be kept at reset value. */
+
+/* --- ADC_CR1 values (note some of these are defined elsewhere) ----------- */
+
+/* AWDEN: Analog watchdog enable on regular channels */
+#define ADC_CR1_AWDEN (1 << 23)
+
+/* JAWDEN: Analog watchdog enable on injected channels */
+#define ADC_CR1_JAWDEN (1 << 22)
+
+/* DISCNUM[2:0]: Discontinuous mode channel count. */
+/****************************************************************************/
+/** @defgroup adc_cr1_discnum ADC Number of channels in discontinuous mode.
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CR1_DISCNUM_1CHANNELS (0x0 << 13)
+#define ADC_CR1_DISCNUM_2CHANNELS (0x1 << 13)
+#define ADC_CR1_DISCNUM_3CHANNELS (0x2 << 13)
+#define ADC_CR1_DISCNUM_4CHANNELS (0x3 << 13)
+#define ADC_CR1_DISCNUM_5CHANNELS (0x4 << 13)
+#define ADC_CR1_DISCNUM_6CHANNELS (0x5 << 13)
+#define ADC_CR1_DISCNUM_7CHANNELS (0x6 << 13)
+#define ADC_CR1_DISCNUM_8CHANNELS (0x7 << 13)
+/**@}*/
+#define ADC_CR1_DISCNUM_MASK (0x7 << 13)
+#define ADC_CR1_DISCNUM_SHIFT 13
+
+/* JDISCEN: */ /** Discontinuous mode on injected channels. */
+#define ADC_CR1_JDISCEN (1 << 12)
+
+/* DISCEN: */ /** Discontinuous mode on regular channels. */
+#define ADC_CR1_DISCEN (1 << 11)
+
+/* JAUTO: */ /** Automatic Injection Group conversion. */
+#define ADC_CR1_JAUTO (1 << 10)
+
+/* AWDSGL: */ /** Enable the watchdog on a single channel in scan mode. */
+#define ADC_CR1_AWDSGL (1 << 9)
+
+/* SCAN: */ /** Scan mode. */
+#define ADC_CR1_SCAN (1 << 8)
+
+/* JEOCIE: */ /** Interrupt enable for injected channels. */
+#define ADC_CR1_JEOCIE (1 << 7)
+
+/* AWDIE: */ /** Analog watchdog interrupt enable. */
+#define ADC_CR1_AWDIE (1 << 6)
+
+/* EOCIE: */ /** Interrupt enable EOC. */
+#define ADC_CR1_EOCIE (1 << 5)
+
+/* AWDCH[4:0]: Analog watchdog channel bits. (Up to 17 other values reserved) */
+/* Notes:
+ * ADC1: Analog channel 16 and 17 are internally connected to the temperature
+ * sensor and V_REFINT, respectively.
+ * ADC2: Analog channel 16 and 17 are internally connected to V_SS.
+ * ADC3: Analog channel 9, 14, 15, 16 and 17 are internally connected to V_SS.
+ */
+/****************************************************************************/
+/* ADC_CR1 AWDCH[4:0] ADC watchdog channel */
+/** @defgroup adc_watchdog_channel ADC watchdog channel
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CR1_AWDCH_CHANNEL0 (0x00 << 0)
+#define ADC_CR1_AWDCH_CHANNEL1 (0x01 << 0)
+#define ADC_CR1_AWDCH_CHANNEL2 (0x02 << 0)
+#define ADC_CR1_AWDCH_CHANNEL3 (0x03 << 0)
+#define ADC_CR1_AWDCH_CHANNEL4 (0x04 << 0)
+#define ADC_CR1_AWDCH_CHANNEL5 (0x05 << 0)
+#define ADC_CR1_AWDCH_CHANNEL6 (0x06 << 0)
+#define ADC_CR1_AWDCH_CHANNEL7 (0x07 << 0)
+#define ADC_CR1_AWDCH_CHANNEL8 (0x08 << 0)
+#define ADC_CR1_AWDCH_CHANNEL9 (0x09 << 0)
+#define ADC_CR1_AWDCH_CHANNEL10 (0x0A << 0)
+#define ADC_CR1_AWDCH_CHANNEL11 (0x0B << 0)
+#define ADC_CR1_AWDCH_CHANNEL12 (0x0C << 0)
+#define ADC_CR1_AWDCH_CHANNEL13 (0x0D << 0)
+#define ADC_CR1_AWDCH_CHANNEL14 (0x0E << 0)
+#define ADC_CR1_AWDCH_CHANNEL15 (0x0F << 0)
+#define ADC_CR1_AWDCH_CHANNEL16 (0x10 << 0)
+#define ADC_CR1_AWDCH_CHANNEL17 (0x11 << 0)
+/**@}*/
+#define ADC_CR1_AWDCH_MASK (0x1F << 0)
+#define ADC_CR1_AWDCH_SHIFT 0
+
+/* --- ADC_CR2 values ------------------------------------------------------ */
+
+/* SWSTART: Start conversion of regular channels. */
+#define ADC_CR2_SWSTART (1 << 30)
+
+/* EXTEN[1:0]: External trigger enable for regular channels. */
+/****************************************************************************/
+/** @defgroup adc_trigger_polarity_regular ADC Trigger Polarity
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CR2_EXTEN_DISABLED (0x0 << 28)
+#define ADC_CR2_EXTEN_RISING_EDGE (0x1 << 28)
+#define ADC_CR2_EXTEN_FALLING_EDGE (0x2 << 28)
+#define ADC_CR2_EXTEN_BOTH_EDGES (0x3 << 28)
+/**@}*/
+#define ADC_CR2_EXTEN_MASK (0x3 << 28)
+#define ADC_CR2_EXTEN_SHIFT 28
+
+/* EXTSEL[3:0]: External event selection for regular group. */
+/****************************************************************************/
+/** @defgroup adc_trigger_regular ADC Trigger Identifier for Regular group
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+/** Timer 1 Compare Output 1 */
+#define ADC_CR2_EXTSEL_TIM1_CC1 (0x0 << 24)
+/** Timer 1 Compare Output 2 */
+#define ADC_CR2_EXTSEL_TIM1_CC2 (0x1 << 24)
+/** Timer 1 Compare Output 3 */
+#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 24)
+/** Timer 2 Compare Output 2 */
+#define ADC_CR2_EXTSEL_TIM2_CC2 (0x3 << 24)
+/** Timer 2 Compare Output 3 */
+#define ADC_CR2_EXTSEL_TIM2_CC3 (0x4 << 24)
+/** Timer 2 Compare Output 4 */
+#define ADC_CR2_EXTSEL_TIM2_CC4 (0x5 << 24)
+/** Timer 2 TRGO Event */
+#define ADC_CR2_EXTSEL_TIM2_TRGO (0x6 << 24)
+/** Timer 3 Compare Output 1 */
+#define ADC_CR2_EXTSEL_TIM3_CC1 (0x7 << 24)
+/** Timer 3 TRGO Event */
+#define ADC_CR2_EXTSEL_TIM3_TRGO (0x8 << 24)
+/** Timer 4 Compare Output 4 */
+#define ADC_CR2_EXTSEL_TIM4_CC4 (0x9 << 24)
+/** Timer 5 Compare Output 1 */
+#define ADC_CR2_EXTSEL_TIM5_CC1 (0xA << 24)
+/** Timer 5 Compare Output 2 */
+#define ADC_CR2_EXTSEL_TIM5_CC2 (0xB << 24)
+/** Timer 5 Compare Output 3 */
+#define ADC_CR2_EXTSEL_TIM5_CC3 (0xC << 24)
+/** Timer 8 Compare Output 1 */
+#define ADC_CR2_EXTSEL_TIM8_CC1 (0xD << 24)
+/** Timer 8 TRGO Event */
+#define ADC_CR2_EXTSEL_TIM8_TRGO (0xE << 24)
+/** EXTI Line 11 Event */
+#define ADC_CR2_EXTSEL_EXTI_LINE_11 (0xF << 24)
+/**@}*/
+#define ADC_CR2_EXTSEL_MASK (0xF << 24)
+#define ADC_CR2_EXTSEL_SHIFT 24
+
+/* Bit 23 is reserved */
+
+/* JSWSTART: Start conversion of injected channels. */
+#define ADC_CR2_JSWSTART (1 << 22)
+
+/* JEXTEN[1:0]: External trigger enable for injected channels. */
+/****************************************************************************/
+/** @defgroup adc_trigger_polarity_injected ADC Injected Trigger Polarity
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CR2_JEXTEN_DISABLED (0x0 << 20)
+#define ADC_CR2_JEXTEN_RISING_EDGE (0x1 << 20)
+#define ADC_CR2_JEXTEN_FALLING_EDGE (0x2 << 20)
+#define ADC_CR2_JEXTEN_BOTH_EDGES (0x3 << 20)
+/**@}*/
+#define ADC_CR2_JEXTEN_MASK (0x3 << 20)
+#define ADC_CR2_JEXTEN_SHIFT 20
+
+/* JEXTSEL[3:0]: External event selection for injected group. */
+/****************************************************************************/
+/** @defgroup adc_trigger_injected ADC Trigger Identifier for Injected group
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x0 << 16)
+#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x1 << 16)
+#define ADC_CR2_JEXTSEL_TIM2_CC1 (0x2 << 16)
+#define ADC_CR2_JEXTSEL_TIM2_TRGO (0x3 << 16)
+#define ADC_CR2_JEXTSEL_TIM3_CC2 (0x4 << 16)
+#define ADC_CR2_JEXTSEL_TIM3_CC4 (0x5 << 16)
+#define ADC_CR2_JEXTSEL_TIM4_CC1 (0x6 << 16)
+#define ADC_CR2_JEXTSEL_TIM4_CC2 (0x7 << 16)
+#define ADC_CR2_JEXTSEL_TIM4_CC3 (0x8 << 16)
+#define ADC_CR2_JEXTSEL_TIM4_TRGO (0x9 << 16)
+#define ADC_CR2_JEXTSEL_TIM5_CC4 (0xA << 16)
+#define ADC_CR2_JEXTSEL_TIM5_TRGO (0xB << 16)
+#define ADC_CR2_JEXTSEL_TIM8_CC2 (0xC << 16)
+#define ADC_CR2_JEXTSEL_TIM8_CC3 (0xD << 16)
+#define ADC_CR2_JEXTSEL_TIM8_CC4 (0xE << 16)
+#define ADC_CR2_JEXTSEL_EXTI_LINE_15 (0xF << 16)
+/**@}*/
+#define ADC_CR2_JEXTSEL_MASK (0xF << 16)
+#define ADC_CR2_JEXTSEL_SHIFT 16
+
+/* ALIGN: Data alignement. */
+#define ADC_CR2_ALIGN_RIGHT (0 << 11)
+#define ADC_CR2_ALIGN_LEFT (1 << 11)
+#define ADC_CR2_ALIGN (1 << 11)
+
+/* EOCS: End of conversion selection. */
+#define ADC_CR2_EOCS (1 << 10)
+
+/* DDS: DMA disable selection */
+#define ADC_CR2_DDS (1 << 9)
+
+/* DMA: Direct memory access mode. (ADC1 and ADC3 only!) */
+#define ADC_CR2_DMA (1 << 8)
+
+/* Note: Bits [7:2] are reserved and must be kept at reset value. */
+
+/* CONT: Continous conversion. */
+#define ADC_CR2_CONT (1 << 1)
+
+/* ADON: A/D converter On/Off. */
+/* Note: If any other bit in this register apart from ADON is changed at the
+ * same time, then conversion is not triggered. This is to prevent triggering
+ * an erroneous conversion.
+ * Conclusion: Must be separately written.
+ */
+#define ADC_CR2_ADON (1 << 0)
+
+/* --- ADC_SMPR1 values ---------------------------------------------------- */
+
+#define ADC_SMPR1_SMP17_LSB 21
+#define ADC_SMPR1_SMP16_LSB 18
+#define ADC_SMPR1_SMP15_LSB 15
+#define ADC_SMPR1_SMP14_LSB 12
+#define ADC_SMPR1_SMP13_LSB 9
+#define ADC_SMPR1_SMP12_LSB 6
+#define ADC_SMPR1_SMP11_LSB 3
+#define ADC_SMPR1_SMP10_LSB 0
+#define ADC_SMPR1_SMP17_MSK (0x7 << ADC_SMP17_LSB)
+#define ADC_SMPR1_SMP16_MSK (0x7 << ADC_SMP16_LSB)
+#define ADC_SMPR1_SMP15_MSK (0x7 << ADC_SMP15_LSB)
+#define ADC_SMPR1_SMP14_MSK (0x7 << ADC_SMP14_LSB)
+#define ADC_SMPR1_SMP13_MSK (0x7 << ADC_SMP13_LSB)
+#define ADC_SMPR1_SMP12_MSK (0x7 << ADC_SMP12_LSB)
+#define ADC_SMPR1_SMP11_MSK (0x7 << ADC_SMP11_LSB)
+#define ADC_SMPR1_SMP10_MSK (0x7 << ADC_SMP10_LSB)
+/****************************************************************************/
+/* ADC_SMPR1 ADC Sample Time Selection for Channels */
+/** @defgroup adc_sample_r1 ADC Sample Time Selection for ADC1
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_SMPR1_SMP_1DOT5CYC 0x0
+#define ADC_SMPR1_SMP_7DOT5CYC 0x1
+#define ADC_SMPR1_SMP_13DOT5CYC 0x2
+#define ADC_SMPR1_SMP_28DOT5CYC 0x3
+#define ADC_SMPR1_SMP_41DOT5CYC 0x4
+#define ADC_SMPR1_SMP_55DOT5CYC 0x5
+#define ADC_SMPR1_SMP_71DOT5CYC 0x6
+#define ADC_SMPR1_SMP_239DOT5CYC 0x7
+/**@}*/
+
+/* --- ADC_SMPR2 values ---------------------------------------------------- */
+
+#define ADC_SMPR2_SMP9_LSB 27
+#define ADC_SMPR2_SMP8_LSB 24
+#define ADC_SMPR2_SMP7_LSB 21
+#define ADC_SMPR2_SMP6_LSB 18
+#define ADC_SMPR2_SMP5_LSB 15
+#define ADC_SMPR2_SMP4_LSB 12
+#define ADC_SMPR2_SMP3_LSB 9
+#define ADC_SMPR2_SMP2_LSB 6
+#define ADC_SMPR2_SMP1_LSB 3
+#define ADC_SMPR2_SMP0_LSB 0
+#define ADC_SMPR2_SMP9_MSK (0x7 << ADC_SMP9_LSB)
+#define ADC_SMPR2_SMP8_MSK (0x7 << ADC_SMP8_LSB)
+#define ADC_SMPR2_SMP7_MSK (0x7 << ADC_SMP7_LSB)
+#define ADC_SMPR2_SMP6_MSK (0x7 << ADC_SMP6_LSB)
+#define ADC_SMPR2_SMP5_MSK (0x7 << ADC_SMP5_LSB)
+#define ADC_SMPR2_SMP4_MSK (0x7 << ADC_SMP4_LSB)
+#define ADC_SMPR2_SMP3_MSK (0x7 << ADC_SMP3_LSB)
+#define ADC_SMPR2_SMP2_MSK (0x7 << ADC_SMP2_LSB)
+#define ADC_SMPR2_SMP1_MSK (0x7 << ADC_SMP1_LSB)
+#define ADC_SMPR2_SMP0_MSK (0x7 << ADC_SMP0_LSB)
+/****************************************************************************/
+/* ADC_SMPR2 ADC Sample Time Selection for Channels */
+/** @defgroup adc_sample_r2 ADC Sample Time Selection for ADC2
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_SMPR2_SMP_1DOT5CYC 0x0
+#define ADC_SMPR2_SMP_7DOT5CYC 0x1
+#define ADC_SMPR2_SMP_13DOT5CYC 0x2
+#define ADC_SMPR2_SMP_28DOT5CYC 0x3
+#define ADC_SMPR2_SMP_41DOT5CYC 0x4
+#define ADC_SMPR2_SMP_55DOT5CYC 0x5
+#define ADC_SMPR2_SMP_71DOT5CYC 0x6
+#define ADC_SMPR2_SMP_239DOT5CYC 0x7
+/**@}*/
+
+/* --- ADC_SMPRx generic values -------------------------------------------- */
+/****************************************************************************/
+/* ADC_SMPRG ADC Sample Time Selection for Channels */
+/** @defgroup adc_sample_rg ADC Sample Time Selection for All Channels
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_SMPR_SMP_1DOT5CYC 0x0
+#define ADC_SMPR_SMP_7DOT5CYC 0x1
+#define ADC_SMPR_SMP_13DOT5CYC 0x2
+#define ADC_SMPR_SMP_28DOT5CYC 0x3
+#define ADC_SMPR_SMP_41DOT5CYC 0x4
+#define ADC_SMPR_SMP_55DOT5CYC 0x5
+#define ADC_SMPR_SMP_71DOT5CYC 0x6
+#define ADC_SMPR_SMP_239DOT5CYC 0x7
+/**@}*/
+
+/* --- ADC_JOFRx, ADC_HTR, ADC_LTR values ---------------------------------- */
+
+#define ADC_JOFFSET_LSB 0
+#define ADC_JOFFSET_MSK (0x7ff << 0)
+#define ADC_HT_LSB 0
+#define ADC_HT_MSK (0x7ff << 0)
+#define ADC_LT_LSB 0
+#define ADC_LT_MSK (0x7ff << 0)
+
+/* --- ADC_SQR1 values ----------------------------------------------------- */
+
+#define ADC_SQR1_L_LSB 20
+#define ADC_SQR1_SQ16_LSB 15
+#define ADC_SQR1_SQ15_LSB 10
+#define ADC_SQR1_SQ14_LSB 5
+#define ADC_SQR1_SQ13_LSB 0
+#define ADC_SQR1_L_MSK (0xf << ADC_SQR1_L_LSB)
+#define ADC_SQR1_SQ16_MSK (0x1f << ADC_SQR1_SQ16_LSB)
+#define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQR1_SQ15_LSB)
+#define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQR1_SQ14_LSB)
+#define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQR1_SQ13_LSB)
+
+/* --- ADC_SQR2 values ----------------------------------------------------- */
+
+#define ADC_SQR2_SQ12_LSB 25
+#define ADC_SQR2_SQ11_LSB 20
+#define ADC_SQR2_SQ10_LSB 15
+#define ADC_SQR2_SQ9_LSB 10
+#define ADC_SQR2_SQ8_LSB 5
+#define ADC_SQR2_SQ7_LSB 0
+#define ADC_SQR2_SQ12_MSK (0x1f << ADC_SQR2_SQ12_LSB)
+#define ADC_SQR2_SQ11_MSK (0x1f << ADC_SQR2_SQ11_LSB)
+#define ADC_SQR2_SQ10_MSK (0x1f << ADC_SQR2_SQ10_LSB)
+#define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQR2_SQ9_LSB)
+#define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQR2_SQ8_LSB)
+#define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQR2_SQ7_LSB)
+
+/* --- ADC_SQR3 values ----------------------------------------------------- */
+
+#define ADC_SQR3_SQ6_LSB 25
+#define ADC_SQR3_SQ5_LSB 20
+#define ADC_SQR3_SQ4_LSB 15
+#define ADC_SQR3_SQ3_LSB 10
+#define ADC_SQR3_SQ2_LSB 5
+#define ADC_SQR3_SQ1_LSB 0
+#define ADC_SQR3_SQ6_MSK (0x1f << ADC_SQR3_SQ6_LSB)
+#define ADC_SQR3_SQ5_MSK (0x1f << ADC_SQR3_SQ5_LSB)
+#define ADC_SQR3_SQ4_MSK (0x1f << ADC_SQR3_SQ4_LSB)
+#define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQR3_SQ3_LSB)
+#define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQR3_SQ2_LSB)
+#define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQR3_SQ1_LSB)
+
+/* --- ADC_JSQR values ----------------------------------------------------- */
+
+#define ADC_JSQR_JL_LSB 20
+#define ADC_JSQR_JSQ4_LSB 15
+#define ADC_JSQR_JSQ3_LSB 10
+#define ADC_JSQR_JSQ2_LSB 5
+#define ADC_JSQR_JSQ1_LSB 0
+
+/* JL[2:0]: Discontinous mode channel count injected channels. */
+/****************************************************************************/
+/** @defgroup adc_jsqr_jl ADC Number of channels in discontinuous mode fro injected channels.
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_JSQR_JL_1CHANNELS (0x0 << ADC_JSQR_JL_LSB)
+#define ADC_JSQR_JL_2CHANNELS (0x1 << ADC_JSQR_JL_LSB)
+#define ADC_JSQR_JL_3CHANNELS (0x2 << ADC_JSQR_JL_LSB)
+#define ADC_JSQR_JL_4CHANNELS (0x3 << ADC_JSQR_JL_LSB)
+/**@}*/
+#define ADC_JSQR_JL_SHIFT 13
+#define ADC_JSQR_JL_MSK (0x2 << ADC_JSQR_JL_LSB)
+#define ADC_JSQR_JSQ4_MSK (0x1f << ADC_JSQR_JSQ4_LSB)
+#define ADC_JSQR_JSQ3_MSK (0x1f << ADC_JSQR_JSQ3_LSB)
+#define ADC_JSQR_JSQ2_MSK (0x1f << ADC_JSQR_JSQ2_LSB)
+#define ADC_JSQR_JSQ1_MSK (0x1f << ADC_JSQR_JSQ1_LSB)
+
+/* --- ADC_JDRx, ADC_DR values --------------------------------------------- */
+
+#define ADC_JDATA_LSB 0
+#define ADC_DATA_LSB 0
+#define ADC_JDATA_MSK (0xffff << ADC_JDATA_LSB)
+#define ADC_DATA_MSK (0xffff << ADC_DA)
+
+/* --- Common Registers ---------------------------------------------------- */
+
+/* --- ADC_CSR values (read only images) ------------------------------------ */
+
+/* OVR3: Overrun ADC3. */
+#define ADC_CSR_OVR3 (1 << 21)
+
+/* STRT3: Regular channel start ADC3. */
+#define ADC_CSR_STRT3 (1 << 20)
+
+/* JSTRT3: Injected channel start ADC3. */
+#define ADC_CSR_JSTRT3 (1 << 19)
+
+/* JEOC3: Injected channel end of conversion ADC3. */
+#define ADC_CSR_JEOC3 (1 << 18)
+
+/* EOC3: Regular channel end of conversion ADC3. */
+#define ADC_CSR_EOC3 (1 << 17)
+
+/* EOC3: Regular channel end of conversion ADC3. */
+#define ADC_CSR_AWD3 (1 << 16)
+
+/* Bits 15:14 Reserved, must be kept at reset value */
+
+/* OVR2: Overrun ADC2. */
+#define ADC_CSR_OVR2 (1 << 13)
+
+/* STRT2: Regular channel start ADC2. */
+#define ADC_CSR_STRT2 (1 << 12)
+
+/* JSTRT2: Injected channel start ADC2. */
+#define ADC_CSR_JSTRT2 (1 << 11)
+
+/* JEOC2: Injected channel end of conversion ADC2. */
+#define ADC_CSR_JEOC2 (1 << 10)
+
+/* EOC2: Regular channel end of conversion ADC2. */
+#define ADC_CSR_EOC2 (1 << 9)
+
+/* EOC2: Regular channel end of conversion ADC2. */
+#define ADC_CSR_AWD2 (1 << 8)
+
+/* Bits 7:6 Reserved, must be kept at reset value */
+
+/* OVR1: Overrun ADC1. */
+#define ADC_CSR_OVR1 (1 << 5)
+
+/* STRT1: Regular channel start ADC1. */
+#define ADC_CSR_STRT1 (1 << 4)
+
+/* JSTRT1: Injected channel start ADC1. */
+#define ADC_CSR_JSTRT1 (1 << 3)
+
+/* JEOC1: Injected channel end of conversion ADC1. */
+#define ADC_CSR_JEOC1 (1 << 2)
+
+/* EOC1: Regular channel end of conversion ADC1. */
+#define ADC_CSR_EOC1 (1 << 1)
+
+/* EOC1: Regular channel end of conversion ADC1. */
+#define ADC_CSR_AWD1 (1 << 0)
+
+/* --- ADC_CCR values ------------------------------------------------------ */
+
+/* TSVREFE: Temperature sensor and Vrefint enable. */
+#define ADC_CCR_TSVREFE (1 << 23)
+
+/* VBATE: VBat enable. */
+#define ADC_CCR_VBATE (1 << 22)
+
+/* Bit 18:21 reserved, must be kept at reset value. */
+
+/* ADCPRE: ADC prescaler. */
+/****************************************************************************/
+/** @defgroup adc_ccr_adcpre ADC Prescale
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CCR_ADCPRE_BY2 (0x0 << 16)
+#define ADC_CCR_ADCPRE_BY4 (0x1 << 16)
+#define ADC_CCR_ADCPRE_BY6 (0x2 << 16)
+#define ADC_CCR_ADCPRE_BY8 (0x3 << 16)
+/**@}*/
+#define ADC_CCR_ADCPRE_MASK (0x3 << 16)
+#define ADC_CCR_ADCPRE_SHIFT 16
+
+/* DMA: Direct memory access mode for multi ADC mode. */
+/****************************************************************************/
+/** @defgroup adc_dma_mode ADC DMA mode for multi ADC mode
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CCR_DMA_DISABLE (0x0 << 14)
+#define ADC_CCR_DMA_MODE_1 (0x1 << 14)
+#define ADC_CCR_DMA_MODE_2 (0x2 << 14)
+#define ADC_CCR_DMA_MODE_3 (0x3 << 14)
+/**@}*/
+#define ADC_CCR_DMA_MASK (0x3 << 14)
+#define ADC_CCR_DMA_SHIFT 14
+
+/* DDS: DMA disable selection (for multi-ADC mode). */
+#define ADC_CCR_DDS (1 << 13)
+
+/* Bit 12 reserved, must be kept at reset value */
+
+/* DELAY: Delay between 2 sampling phases. */
+/****************************************************************************/
+/** @defgroup adc_delay ADC Delay between 2 sampling phases
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+#define ADC_CCR_DELAY_5ADCCLK (0x0 << 8)
+#define ADC_CCR_DELAY_6ADCCLK (0x1 << 8)
+#define ADC_CCR_DELAY_7ADCCLK (0x2 << 8)
+#define ADC_CCR_DELAY_8ADCCLK (0x3 << 8)
+#define ADC_CCR_DELAY_9ADCCLK (0x4 << 8)
+#define ADC_CCR_DELAY_10ADCCLK (0x5 << 8)
+#define ADC_CCR_DELAY_11ADCCLK (0x6 << 8)
+#define ADC_CCR_DELAY_12ADCCLK (0x7 << 8)
+#define ADC_CCR_DELAY_13ADCCLK (0x8 << 8)
+#define ADC_CCR_DELAY_14ADCCLK (0x9 << 8)
+#define ADC_CCR_DELAY_15ADCCLK (0xa << 8)
+#define ADC_CCR_DELAY_16ADCCLK (0xb << 8)
+#define ADC_CCR_DELAY_17ADCCLK (0xc << 8)
+#define ADC_CCR_DELAY_18ADCCLK (0xd << 8)
+#define ADC_CCR_DELAY_19ADCCLK (0xe << 8)
+#define ADC_CCR_DELAY_20ADCCLK (0xf << 8)
+/**@}*/
+#define ADC_CCR_DELAY_MASK (0xf << 8)
+#define ADC_CCR_DELAY_SHIFT 8
+
+/* Bit 7:5 reserved, must be kept at reset value */
+
+/* MULTI: Multi ADC mode selection. */
+/****************************************************************************/
+/** @defgroup adc_multi_mode ADC Multi mode selection
+@ingroup STM32F4xx_adc_defines
+
+@{*/
+
+/** All ADCs independent */
+#define ADC_CCR_MULTI_INDEPENDENT (0x00 << 0)
+
+/* dual modes (ADC1 + ADC2) */
+/** Dual modes (ADC1 + ADC2) Combined regular simultaneous + injected simultaneous mode */
+#define ADC_CCR_MULTI_DUAL_REG_SIMUL_AND_INJECTED_SIMUL (0x01 << 0)
+/** Dual modes (ADC1 + ADC2) Combined regular simultaneous + alternate trigger mode. */
+#define ADC_CCR_MULTI_DUAL_REG_SIMUL_AND_ALTERNATE_TRIG (0x02 << 0)
+/** Dual modes (ADC1 + ADC2) Injected simultaneous mode only. */
+#define ADC_CCR_MULTI_DUAL_INJECTED_SIMUL (0x05 << 0)
+/** Dual modes (ADC1 + ADC2) Regular simultaneous mode only. */
+#define ADC_CCR_MULTI_DUAL_REGULAR_SIMUL (0x06 << 0)
+/** Dual modes (ADC1 + ADC2) Interleaved mode only. */
+#define ADC_CCR_MULTI_DUAL_INTERLEAVED (0x07 << 0)
+/** Dual modes (ADC1 + ADC2) Alternate trigger mode only. */
+#define ADC_CCR_MULTI_DUAL_ALTERNATE_TRIG (0x09 << 0)
+
+/* Triple modes (ADC1 + ADC2 + ADC3) */
+/** Triple modes (ADC1 + ADC2 + ADC3) Combined regular simultaneous + injected simultaneous mode */
+#define ADC_CCR_MULTI_TRIPLE_REG_SIMUL_AND_INJECTED_SIMUL (0x11 << 0)
+/** Triple modes (ADC1 + ADC2 + ADC3) Combined regular simultaneous + alternate trigger mode. */
+#define ADC_CCR_MULTI_TRIPLE_REG_SIMUL_AND_ALTERNATE_TRIG (0x12 << 0)
+/** Triple modes (ADC1 + ADC2 + ADC3) Injected simultaneous mode only. */
+#define ADC_CCR_MULTI_TRIPLE_INJECTED_SIMUL (0x15 << 0)
+/** Triple modes (ADC1 + ADC2 + ADC3) Regular simultaneous mode only. */
+#define ADC_CCR_MULTI_TRIPLE_REGULAR_SIMUL (0x16 << 0)
+/** Triple modes (ADC1 + ADC2 + ADC3) Interleaved mode only. */
+#define ADC_CCR_MULTI_TRIPLE_INTERLEAVED (0x17 << 0)
+/** Triple modes (ADC1 + ADC2 + ADC3) Alternate trigger mode only. */
+#define ADC_CCR_MULTI_TRIPLE_ALTERNATE_TRIG (0x19 << 0)
+/**@}*/
+
+#define ADC_CCR_MULTI_MASK (0x1f << 0)
+#define ADC_CCR_MULTI_SHIFT 0
+
+/* --- ADC_CDR values ------------------------------------------------------ */
+
+#define ADC_CDR_DATA2_MASK (0xffff << 16)
+#define ADC_CDR_DATA2_SHIFT 16
+
+#define ADC_CDR_DATA1_MASK (0xffff << 0)
+#define ADC_CDR_DATA1_SHIFT 0
+
+BEGIN_DECLS
+
+void adc_power_on(u32 adc);
+void adc_off(u32 adc);
+void adc_enable_analog_watchdog_regular(u32 adc);
+void adc_disable_analog_watchdog_regular(u32 adc);
+void adc_enable_analog_watchdog_injected(u32 adc);
+void adc_disable_analog_watchdog_injected(u32 adc);
+void adc_enable_discontinuous_mode_regular(u32 adc, u8 length);
+void adc_disable_discontinuous_mode_regular(u32 adc);
+void adc_enable_discontinuous_mode_injected(u32 adc);
+void adc_disable_discontinuous_mode_injected(u32 adc);
+void adc_enable_automatic_injected_group_conversion(u32 adc);
+void adc_disable_automatic_injected_group_conversion(u32 adc);
+void adc_enable_analog_watchdog_on_all_channels(u32 adc);
+void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel);
+void adc_enable_scan_mode(u32 adc);
+void adc_disable_scan_mode(u32 adc);
+void adc_enable_eoc_interrupt_injected(u32 adc);
+void adc_disable_eoc_interrupt_injected(u32 adc);
+void adc_enable_awd_interrupt(u32 adc);
+void adc_disable_awd_interrupt(u32 adc);
+void adc_enable_eoc_interrupt(u32 adc);
+void adc_disable_eoc_interrupt(u32 adc);
+void adc_start_conversion_regular(u32 adc);
+void adc_start_conversion_injected(u32 adc);
+void adc_disable_external_trigger_regular(u32 adc);
+void adc_disable_external_trigger_injected(u32 adc);
+void adc_set_left_aligned(u32 adc);
+void adc_set_right_aligned(u32 adc);
+void adc_enable_dma(u32 adc);
+void adc_disable_dma(u32 adc);
+void adc_set_continuous_conversion_mode(u32 adc);
+void adc_set_single_conversion_mode(u32 adc);
+void adc_set_sample_time(u32 adc, u8 channel, u8 time);
+void adc_set_sample_time_on_all_channels(u32 adc, u8 time);
+void adc_set_watchdog_high_threshold(u32 adc, u16 threshold);
+void adc_set_watchdog_low_threshold(u32 adc, u16 threshold);
+void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]);
+void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]);
+bool adc_eoc(u32 adc);
+bool adc_eoc_injected(u32 adc);
+u32 adc_read_regular(u32 adc);
+u32 adc_read_injected(u32 adc, u8 reg);
+void adc_set_injected_offset(u32 adc, u8 reg, u32 offset);
+
+void adc_set_clk_prescale(u32 prescaler);
+void adc_set_multi_mode(u32 mode);
+void adc_enable_external_trigger_regular(u32 adc, u32 trigger, u32 polarity);
+void adc_enable_external_trigger_injected(u32 adc, u32 trigger, u32 polarity);
+void adc_set_resolution(u32 adc, u16 resolution);
+void adc_enable_overrun_interrupt(u32 adc);
+void adc_disable_overrun_interrupt(u32 adc);
+bool adc_get_overrun_flag(u32 adc);
+void adc_clear_overrun_flag(u32 adc);
+bool adc_awd(u32 adc);
+void adc_eoc_after_each(u32 adc);
+void adc_eoc_after_group(u32 adc);
+void adc_set_dma_continue(u32 adc);
+void adc_set_dma_terminate(u32 adc);
+void adc_enable_temperature_sensor(void);
+void adc_disable_temperature_sensor(void);
+
+END_DECLS
+
+/**@}*/
+
+#endif
diff --git a/include/libopencm3/stm32/f4/dma.h b/include/libopencm3/stm32/f4/dma.h
new file mode 100644
index 0000000..c765a79
--- /dev/null
+++ b/include/libopencm3/stm32/f4/dma.h
@@ -0,0 +1,693 @@
+/** @defgroup STM32F4xx_dma_defines DMA Defines
+
+@ingroup STM32F4xx_defines
+
+@brief Defined Constants and Types for the STM32F4xx DMA Controller
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net>
+
+@date 18 October 2012
+
+LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Ken Sarkies <ksarkies@internode.on.net>
+ *
+ * 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/>.
+ */
+
+/**@{*/
+
+#ifndef LIBOPENCM3_DMA_H
+#define LIBOPENCM3_DMA_H
+
+#include <libopencm3/stm32/memorymap.h>
+#include <libopencm3/cm3/common.h>
+
+/* --- Convenience macros -------------------------------------------------- */
+
+/* DMA register base adresses (for convenience) */
+#define DMA1 DMA1_BASE
+#define DMA2 DMA2_BASE
+
+/* --- DMA registers ------------------------------------------------------- */
+
+/* DMA low interrupt status register (DMAx_ISR) */
+#define DMA_LISR(dma_base) MMIO32(dma_base + 0x00)
+#define DMA1_LISR DMA_ISR(DMA1)
+#define DMA2_LISR DMA_ISR(DMA2)
+
+/* DMA high interrupt status register (DMAx_ISR) */
+#define DMA_HISR(dma_base) MMIO32(dma_base + 0x04)
+#define DMA1_HISR DMA_ISR(DMA1)
+#define DMA2_HISR DMA_ISR(DMA2)
+
+/* DMA low interrupt flag clear register (DMAx_IFCR) */
+#define DMA_LIFCR(dma_base) MMIO32(dma_base + 0x08)
+#define DMA1_LIFCR DMA_IFCR(DMA1)
+#define DMA2_LIFCR DMA_IFCR(DMA2)
+
+/* DMA high interrupt flag clear register (DMAx_IFCR) */
+#define DMA_HIFCR(dma_base) MMIO32(dma_base + 0x0C)
+#define DMA1_HIFCR DMA_IFCR(DMA1)
+#define DMA2_HIFCR DMA_IFCR(DMA2)
+
+/* DMA stream configuration register (DMAx_SyCR) */
+#define DMA_SCR(dma_base, stream) MMIO32(dma_base + 0x10 + \
+ (0x18 * (stream)))
+
+#define DMA1_SCR(stream) DMA_SCR(DMA1, stream)
+#define DMA1_S0CR DMA1_SCR(DMA_STREAM0)
+#define DMA1_S1CR DMA1_SCR(DMA_STREAM1)
+#define DMA1_S2CR DMA1_SCR(DMA_STREAM2)
+#define DMA1_S3CR DMA1_SCR(DMA_STREAM3)
+#define DMA1_S4CR DMA1_SCR(DMA_STREAM4)
+#define DMA1_S5CR DMA1_SCR(DMA_STREAM5)
+#define DMA1_S6CR DMA1_SCR(DMA_STREAM6)
+#define DMA1_S7CR DMA1_SCR(DMA_STREAM7)
+
+#define DMA2_SCR(stream) DMA_SCR(DMA2, stream)
+#define DMA2_S0CR DMA2_SCR(DMA_STREAM0)
+#define DMA2_S1CR DMA2_SCR(DMA_STREAM1)
+#define DMA2_S2CR DMA2_SCR(DMA_STREAM2)
+#define DMA2_S3CR DMA2_SCR(DMA_STREAM3)
+#define DMA2_S4CR DMA2_SCR(DMA_STREAM4)
+#define DMA2_S5CR DMA2_SCR(DMA_STREAM5)
+#define DMA2_S6CR DMA2_SCR(DMA_STREAM6)
+#define DMA2_S7CR DMA2_SCR(DMA_STREAM7)
+
+/* DMA number of data register (DMAx_SyNDTR) */
+#define DMA_SNDTR(dma_base, stream) MMIO32(dma_base + 0x14 + \
+ (0x18 * (stream)))
+
+#define DMA1_SNDTR(stream) DMA_SNDTR(DMA1, stream)
+#define DMA1_S0NDTR DMA1_SNDTR(DMA_STREAM0)
+#define DMA1_S1NDTR DMA1_SNDTR(DMA_STREAM1)
+#define DMA1_S2NDTR DMA1_SNDTR(DMA_STREAM2)
+#define DMA1_S3NDTR DMA1_SNDTR(DMA_STREAM3)
+#define DMA1_S4NDTR DMA1_SNDTR(DMA_STREAM4)
+#define DMA1_S5NDTR DMA1_SNDTR(DMA_STREAM5)
+#define DMA1_S6NDTR DMA1_SNDTR(DMA_STREAM6)
+#define DMA1_S7NDTR DMA1_SNDTR(DMA_STREAM7)
+
+#define DMA2_SNDTR(stream) DMA_CNDTR(DMA2, stream)
+#define DMA2_S0NDTR DMA2_SNDTR(DMA_STREAM0)
+#define DMA2_S1NDTR DMA2_SNDTR(DMA_STREAM1)
+#define DMA2_S2NDTR DMA2_SNDTR(DMA_STREAM2)
+#define DMA2_S3NDTR DMA2_SNDTR(DMA_STREAM3)
+#define DMA2_S4NDTR DMA2_SNDTR(DMA_STREAM4)
+#define DMA2_S5NDTR DMA2_SNDTR(DMA_STREAM5)
+#define DMA2_S6NDTR DMA2_SNDTR(DMA_STREAM6)
+#define DMA2_S7NDTR DMA2_SNDTR(DMA_STREAM7)
+
+/* DMA peripheral address register (DMAx_SyPAR) */
+#define DMA_SPAR(dma_base, stream) MMIO32(dma_base + 0x18 + \
+ (0x18 * (stream)))
+
+#define DMA1_SPAR(stream) DMA_SPAR(DMA1, stream)
+#define DMA1_S0PAR DMA1_SPAR(DMA_STREAM0)
+#define DMA1_S1PAR DMA1_SPAR(DMA_STREAM1)
+#define DMA1_S2PAR DMA1_SPAR(DMA_STREAM2)
+#define DMA1_S3PAR DMA1_SPAR(DMA_STREAM3)
+#define DMA1_S4PAR DMA1_SPAR(DMA_STREAM4)
+#define DMA1_S5PAR DMA1_SPAR(DMA_STREAM5)
+#define DMA1_S6PAR DMA1_SPAR(DMA_STREAM6)
+#define DMA1_S7PAR DMA1_SPAR(DMA_STREAM7)
+
+#define DMA2_SPAR(stream) DMA_SPAR(DMA2, stream)
+#define DMA2_S0PAR DMA2_SPAR(DMA_STREAM0)
+#define DMA2_S1PAR DMA2_SPAR(DMA_STREAM1)
+#define DMA2_S2PAR DMA2_SPAR(DMA_STREAM2)
+#define DMA2_S3PAR DMA2_SPAR(DMA_STREAM3)
+#define DMA2_S4PAR DMA2_SPAR(DMA_STREAM4)
+#define DMA2_S5PAR DMA2_SPAR(DMA_STREAM5)
+#define DMA2_S6PAR DMA2_SPAR(DMA_STREAM6)
+#define DMA2_S7PAR DMA2_SPAR(DMA_STREAM7)
+
+/* DMA memory 0 address register (DMAx_SyM0AR) */
+
+#define DMA_SM0AR(dma_base, stream) MMIO32(dma_base + 0x1C + \
+ (0x18 * (stream)))
+
+#define DMA1_SM0AR(stream) DMA_SM0AR(DMA1, stream)
+#define DMA1_S0M0AR DMA1_SM0AR(DMA_STREAM0)
+#define DMA1_S1M0AR DMA1_SM0AR(DMA_STREAM1)
+#define DMA1_S2M0AR DMA1_SM0AR(DMA_STREAM2)
+#define DMA1_S3M0AR DMA1_SM0AR(DMA_STREAM3)
+#define DMA1_S4M0AR DMA1_SM0AR(DMA_STREAM4)
+#define DMA1_S5M0AR DMA1_SM0AR(DMA_STREAM5)
+#define DMA1_S6M0AR DMA1_SM0AR(DMA_STREAM6)
+#define DMA1_S7M0AR DMA1_SM0AR(DMA_STREAM7)
+
+#define DMA2_SM0AR(stream) DMA_CM0AR(DMA2, stream)
+#define DMA2_S0M0AR DMA2_SM0AR(DMA_STREAM0)
+#define DMA2_S1M0AR DMA2_SM0AR(DMA_STREAM1)
+#define DMA2_S2M0AR DMA2_SM0AR(DMA_STREAM2)
+#define DMA2_S3M0AR DMA2_SM0AR(DMA_STREAM3)
+#define DMA2_S4M0AR DMA2_SM0AR(DMA_STREAM4)
+#define DMA2_S5M0AR DMA2_SM0AR(DMA_STREAM5)
+#define DMA2_S6M0AR DMA2_SM0AR(DMA_STREAM6)
+#define DMA2_S7M0AR DMA2_SM0AR(DMA_STREAM7)
+
+/* DMA memory 1 address register (DMAx_SyM1AR) */
+
+#define DMA_SM1AR(dma_base, stream) MMIO32(dma_base + 0x20 + \
+ (0x18 * (stream)))
+
+#define DMA1_SM1AR(stream) DMA_SM1AR(DMA1, stream)
+#define DMA1_S0M1AR DMA1_SM1AR(DMA_STREAM0)
+#define DMA1_S1M1AR DMA1_SM1AR(DMA_STREAM1)
+#define DMA1_S2M1AR DMA1_SM1AR(DMA_STREAM2)
+#define DMA1_S3M1AR DMA1_SM1AR(DMA_STREAM3)
+#define DMA1_S4M1AR DMA1_SM1AR(DMA_STREAM4)
+#define DMA1_S5M1AR DMA1_SM1AR(DMA_STREAM5)
+#define DMA1_S6M1AR DMA1_SM1AR(DMA_STREAM6)
+#define DMA1_S7M1AR DMA1_SM1AR(DMA_STREAM7)
+
+#define DMA2_SM1AR(stream) DMA_CM1AR(DMA2, stream)
+#define DMA2_S0M1AR DMA2_SM1AR(DMA_STREAM0)
+#define DMA2_S1M1AR DMA2_SM1AR(DMA_STREAM1)
+#define DMA2_S2M1AR DMA2_SM1AR(DMA_STREAM2)
+#define DMA2_S3M1AR DMA2_SM1AR(DMA_STREAM3)
+#define DMA2_S4M1AR DMA2_SM1AR(DMA_STREAM4)
+#define DMA2_S5M1AR DMA2_SM1AR(DMA_STREAM5)
+#define DMA2_S6M1AR DMA2_SM1AR(DMA_STREAM6)
+#define DMA2_S7M1AR DMA2_SM1AR(DMA_STREAM7)
+
+/* DMA FIFO Control Register register (DMAx_SyFCR) */
+
+#define DMA_SFCR(dma_base, stream) MMIO32(dma_base + 0x24 + \
+ (0x18 * (stream)))
+
+#define DMA1_SFCR(stream) DMA_SFCR(DMA1, stream)
+#define DMA1_S0FCR DMA1_SFCR(DMA_STREAM0)
+#define DMA1_S1FCR DMA1_SFCR(DMA_STREAM1)
+#define DMA1_S2FCR DMA1_SFCR(DMA_STREAM2)
+#define DMA1_S3FCR DMA1_SFCR(DMA_STREAM3)
+#define DMA1_S4FCR DMA1_SFCR(DMA_STREAM4)
+#define DMA1_S5FCR DMA1_SFCR(DMA_STREAM5)
+#define DMA1_S6FCR DMA1_SFCR(DMA_STREAM6)
+#define DMA1_S7FCR DMA1_SFCR(DMA_STREAM7)
+
+#define DMA2_SFCR(stream) DMA_CFCR(DMA2, stream)
+#define DMA2_S0FCR DMA2_SFCR(DMA_STREAM0)
+#define DMA2_S1FCR DMA2_SFCR(DMA_STREAM1)
+#define DMA2_S2FCR DMA2_SFCR(DMA_STREAM2)
+#define DMA2_S3FCR DMA2_SFCR(DMA_STREAM3)
+#define DMA2_S4FCR DMA2_SFCR(DMA_STREAM4)
+#define DMA2_S5FCR DMA2_SFCR(DMA_STREAM5)
+#define DMA2_S6FCR DMA2_SFCR(DMA_STREAM6)
+#define DMA2_S7FCR DMA2_SFCR(DMA_STREAM7)
+
+/* --- DMA Interrupt Flag offset values ------------------------------------- */
+/* These are based on every interrupt flag and flag clear being at the same relative location */
+/** @defgroup dma_if_offset DMA Interrupt Flag Offsets within stream flag group.
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+/** Transfer Complete Interrupt Flag */
+#define DMA_ISR_TCIF (1 << 5)
+/** Half Transfer Interrupt Flag */
+#define DMA_ISR_HTIF (1 << 4)
+/** Transfer Error Interrupt Flag */
+#define DMA_ISR_TEIF (1 << 3)
+/** Direct Mode Error Interrupt Flag */
+#define DMA_ISR_DMEIF (1 << 2)
+/** FIFO Error Interrupt Flag */
+#define DMA_ISR_FEIF (1 << 0)
+/**@}*/
+
+/* Offset within interrupt status register to start of stream interrupt flag field */
+#define DMA_ISR_OFFSET(stream) (6*(stream & 0x01)+16*((stream & 0x02) >> 1))
+#define DMA_ISR_FLAGS (DMA_ISR_TCIF | DMA_ISR_HTIF | DMA_ISR_TEIF | DMA_ISR_DMEIF | DMA_ISR_FEIF)
+#define DMA_ISR_MASK(stream) DMA_ISR_FLAGS << DMA_ISR_OFFSET(stream)
+
+/* --- DMA_LISR values ------------------------------------------------------ */
+
+/* TCIF: Transfer complete interrupt flag, streams 0-3 only */
+#define DMA_LISR_TCIF_BIT DMA_ISR_TCIF
+#define DMA_LISR_TCIF(stream) (DMA_LISR_TCIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LISR_TCIF0 DMA_LISR_TCIF(DMA_STREAM0)
+#define DMA_LISR_TCIF1 DMA_LISR_TCIF(DMA_STREAM1)
+#define DMA_LISR_TCIF2 DMA_LISR_TCIF(DMA_STREAM2)
+#define DMA_LISR_TCIF3 DMA_LISR_TCIF(DMA_STREAM3)
+
+/* HTIF: Half transfer interrupt flag, streams 0-3 only */
+#define DMA_LISR_HTIF_BIT DMA_ISR_HTIF
+#define DMA_LISR_HTIF(stream) (DMA_LISR_HTIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LISR_HTIF0 DMA_LISR_HTIF(DMA_STREAM0)
+#define DMA_LISR_HTIF1 DMA_LISR_HTIF(DMA_STREAM1)
+#define DMA_LISR_HTIF2 DMA_LISR_HTIF(DMA_STREAM2)
+#define DMA_LISR_HTIF3 DMA_LISR_HTIF(DMA_STREAM3)
+
+/* TEIF: Transfer error interrupt flag, streams 0-3 only */
+#define DMA_LISR_TEIF_BIT DMA_ISR_TEIF
+#define DMA_LISR_TEIF(stream) (DMA_LISR_TEIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LISR_TEIF0 DMA_LISR_TEIF(DMA_STREAM0)
+#define DMA_LISR_TEIF1 DMA_LISR_TEIF(DMA_STREAM1)
+#define DMA_LISR_TEIF2 DMA_LISR_TEIF(DMA_STREAM2)
+#define DMA_LISR_TEIF3 DMA_LISR_TEIF(DMA_STREAM3)
+
+/* DMEIF: Direct Mode Error interrupt flag, streams 0-3 only */
+#define DMA_LISR_DMEIF_BIT DMA_ISR_DMEIF
+#define DMA_LISR_DMEIF(stream) (DMA_LISR_DMEIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LISR_DMEIF0 DMA_LISR_DMEIF(DMA_STREAM0)
+#define DMA_LISR_DMEIF1 DMA_LISR_DMEIF(DMA_STREAM1)
+#define DMA_LISR_DMEIF2 DMA_LISR_DMEIF(DMA_STREAM2)
+#define DMA_LISR_DMEIF3 DMA_LISR_DMEIF(DMA_STREAM3)
+
+/* Interrupt #1 is reserved */
+
+/* FEIF: FIFO Error interrupt flag, streams 0-3 only */
+#define DMA_LISR_FEIF_BIT DMA_ISR_FEIF
+#define DMA_LISR_FEIF(stream) (DMA_LISR_FEIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LISR_FEIF0 DMA_LISR_FEIF(DMA_STREAM0)
+#define DMA_LISR_FEIF1 DMA_LISR_FEIF(DMA_STREAM1)
+#define DMA_LISR_FEIF2 DMA_LISR_FEIF(DMA_STREAM2)
+#define DMA_LISR_FEIF3 DMA_LISR_FEIF(DMA_STREAM3)
+
+/* --- DMA_HISR values ------------------------------------------------------ */
+
+/* TCIF: Transfer complete interrupt flag, streams 4-7 only */
+#define DMA_HISR_TCIF_BIT DMA_ISR_TCIF
+#define DMA_HISR_TCIF(stream) (DMA_HISR_TCIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HISR_TCIF4 DMA_HISR_TCIF(DMA_STREAM4)
+#define DMA_HISR_TCIF5 DMA_HISR_TCIF(DMA_STREAM5)
+#define DMA_HISR_TCIF6 DMA_HISR_TCIF(DMA_STREAM6)
+#define DMA_HISR_TCIF7 DMA_HISR_TCIF(DMA_STREAM7)
+
+/* HTIF: Half transfer interrupt flag, streams 4-7 only */
+#define DMA_HISR_HTIF_BIT DMA_ISR_HTIF
+#define DMA_HISR_HTIF(stream) (DMA_HISR_HTIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HISR_HTIF4 DMA_HISR_HTIF(DMA_STREAM4)
+#define DMA_HISR_HTIF5 DMA_HISR_HTIF(DMA_STREAM5)
+#define DMA_HISR_HTIF6 DMA_HISR_HTIF(DMA_STREAM6)
+#define DMA_HISR_HTIF7 DMA_HISR_HTIF(DMA_STREAM7)
+
+/* TEIF: Transfer error interrupt flag, streams 4-7 only */
+#define DMA_HISR_TEIF_BIT DMA_ISR_TEIF
+#define DMA_HISR_TEIF(stream) (DMA_HISR_TEIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HISR_TEIF4 DMA_HISR_TEIF(DMA_STREAM4)
+#define DMA_HISR_TEIF5 DMA_HISR_TEIF(DMA_STREAM5)
+#define DMA_HISR_TEIF6 DMA_HISR_TEIF(DMA_STREAM6)
+#define DMA_HISR_TEIF7 DMA_HISR_TEIF(DMA_STREAM7)
+
+/* DMEIF: Direct Mode Error interrupt flag, streams 4-7 only */
+#define DMA_HISR_DMEIF_BIT DMA_ISR_DMEIF
+#define DMA_HISR_DMEIF(stream) (DMA_HISR_DMEIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HISR_DMEIF4 DMA_HISR_DMEIF(DMA_STREAM4)
+#define DMA_HISR_DMEIF5 DMA_HISR_DMEIF(DMA_STREAM5)
+#define DMA_HISR_DMEIF6 DMA_HISR_DMEIF(DMA_STREAM6)
+#define DMA_HISR_DMEIF7 DMA_HISR_DMEIF(DMA_STREAM7)
+
+/* Interrupt #1 is reserved */
+
+/* FEIF: FIFO Error interrupt flag, streams 4-7 only */
+#define DMA_HISR_FEIF_BIT DMA_ISR_FEIF
+#define DMA_HISR_FEIF(stream) (DMA_HISR_FEIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HISR_FEIF4 DMA_HISR_FEIF(DMA_STREAM4)
+#define DMA_HISR_FEIF5 DMA_HISR_FEIF(DMA_STREAM5)
+#define DMA_HISR_FEIF6 DMA_HISR_FEIF(DMA_STREAM6)
+#define DMA_HISR_FEIF7 DMA_HISR_FEIF(DMA_STREAM7)
+
+/* --- DMA_LIFCR values ------------------------------------------------------ */
+
+/* TCIF: Transfer complete interrupt flag, streams 0-3 only */
+#define DMA_LIFCR_CTCIF_BIT DMA_ISR_TCIF
+#define DMA_LIFCR_CTCIF(stream) (DMA_LIFCR_CTCIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LIFCR_CTCIF0 DMA_LIFCR_CTCIF(DMA_STREAM0)
+#define DMA_LIFCR_CTCIF1 DMA_LIFCR_CTCIF(DMA_STREAM1)
+#define DMA_LIFCR_CTCIF2 DMA_LIFCR_CTCIF(DMA_STREAM2)
+#define DMA_LIFCR_CTCIF3 DMA_LIFCR_CTCIF(DMA_STREAM3)
+
+/* HTIF: Half transfer interrupt flag, streams 0-3 only */
+#define DMA_LIFCR_CHTIF_BIT DMA_ISR_HTIF
+#define DMA_LIFCR_CHTIF(stream) (DMA_LIFCR_CHTIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LIFCR_CHTIF0 DMA_LIFCR_CHTIF(DMA_STREAM0)
+#define DMA_LIFCR_CHTIF1 DMA_LIFCR_CHTIF(DMA_STREAM1)
+#define DMA_LIFCR_CHTIF2 DMA_LIFCR_CHTIF(DMA_STREAM2)
+#define DMA_LIFCR_CHTIF3 DMA_LIFCR_CHTIF(DMA_STREAM3)
+
+/* TEIF: Transfer error interrupt flag, streams 0-3 only */
+#define DMA_LIFCR_CTEIF_BIT DMA_ISR_TEIF
+#define DMA_LIFCR_CTEIF(stream) (DMA_LIFCR_CTEIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LIFCR_CTEIF0 DMA_LIFCR_CTEIF(DMA_STREAM0)
+#define DMA_LIFCR_CTEIF1 DMA_LIFCR_CTEIF(DMA_STREAM1)
+#define DMA_LIFCR_CTEIF2 DMA_LIFCR_CTEIF(DMA_STREAM2)
+#define DMA_LIFCR_CTEIF3 DMA_LIFCR_CTEIF(DMA_STREAM3)
+
+/* DMEIF: Direct Mode Error interrupt flag, streams 0-3 only */
+#define DMA_LIFCR_CDMEIF_BIT DMA_ISR_DMEIF
+#define DMA_LIFCR_CDMEIF(stream) (DMA_LIFCR_CDMEIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LIFCR_CDMEIF0 DMA_LIFCR_CDMEIF(DMA_STREAM0)
+#define DMA_LIFCR_CDMEIF1 DMA_LIFCR_CDMEIF(DMA_STREAM1)
+#define DMA_LIFCR_CDMEIF2 DMA_LIFCR_CDMEIF(DMA_STREAM2)
+#define DMA_LIFCR_CDMEIF3 DMA_LIFCR_CDMEIF(DMA_STREAM3)
+
+/* Interrupt #1 is reserved */
+
+/* FEIF: FIFO Error interrupt flag, streams 0-3 only */
+#define DMA_LIFCR_CFEIF_BIT DMA_ISR_FEIF
+#define DMA_LIFCR_CFEIF(stream) (DMA_LIFCR_CFEIF_BIT << DMA_ISR_OFFSET(stream))
+
+#define DMA_LIFCR_CFEIF0 DMA_LIFCR_CFEIF(DMA_STREAM0)
+#define DMA_LIFCR_CFEIF1 DMA_LIFCR_CFEIF(DMA_STREAM1)
+#define DMA_LIFCR_CFEIF2 DMA_LIFCR_CFEIF(DMA_STREAM2)
+#define DMA_LIFCR_CFEIF3 DMA_LIFCR_CFEIF(DMA_STREAM3)
+
+/* --- DMA_HIFCR values ------------------------------------------------------ */
+
+/* TCIF: Transfer complete interrupt flag, streams 4-7 only */
+#define DMA_HIFCR_CTCIF_BIT DMA_ISR_TCIF
+#define DMA_HIFCR_CTCIF(stream) (DMA_HIFCR_CTCIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HIFCR_CTCIF4 DMA_HIFCR_CTCIF(DMA_STREAM4)
+#define DMA_HIFCR_CTCIF5 DMA_HIFCR_CTCIF(DMA_STREAM5)
+#define DMA_HIFCR_CTCIF6 DMA_HIFCR_CTCIF(DMA_STREAM6)
+#define DMA_HIFCR_CTCIF7 DMA_HIFCR_CTCIF(DMA_STREAM7)
+
+/* HTIF: Half transfer interrupt flag, streams 4-7 only */
+#define DMA_HIFCR_CHTIF_BIT DMA_ISR_HTIF
+#define DMA_HIFCR_CHTIF(stream) (DMA_HIFCR_CHTIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HIFCR_CHTIF4 DMA_HIFCR_CHTIF(DMA_STREAM4)
+#define DMA_HIFCR_CHTIF5 DMA_HIFCR_CHTIF(DMA_STREAM5)
+#define DMA_HIFCR_CHTIF6 DMA_HIFCR_CHTIF(DMA_STREAM6)
+#define DMA_HIFCR_CHTIF7 DMA_HIFCR_CHTIF(DMA_STREAM7)
+
+/* TEIF: Transfer error interrupt flag, streams 4-7 only */
+#define DMA_HIFCR_CTEIF_BIT DMA_ISR_TEIF
+#define DMA_HIFCR_CTEIF(stream) (DMA_HIFCR_CTEIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HIFCR_CTEIF4 DMA_HIFCR_CTEIF(DMA_STREAM4)
+#define DMA_HIFCR_CTEIF5 DMA_HIFCR_CTEIF(DMA_STREAM5)
+#define DMA_HIFCR_CTEIF6 DMA_HIFCR_CTEIF(DMA_STREAM6)
+#define DMA_HIFCR_CTEIF7 DMA_HIFCR_CTEIF(DMA_STREAM7)
+
+/* DMEIF: Direct Mode Error interrupt flag, streams 4-7 only */
+#define DMA_HIFCR_CDMEIF_BIT DMA_ISR_DMEIF
+#define DMA_HIFCR_CDMEIF(stream) (DMA_HIFCR_CDMEIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HIFCR_CDMEIF4 DMA_HIFCR_CDMEIF(DMA_STREAM4)
+#define DMA_HIFCR_CDMEIF5 DMA_HIFCR_CDMEIF(DMA_STREAM5)
+#define DMA_HIFCR_CDMEIF6 DMA_HIFCR_CDMEIF(DMA_STREAM6)
+#define DMA_HIFCR_CDMEIF7 DMA_HIFCR_CDMEIF(DMA_STREAM7)
+
+/* Interrupt #1 is reserved */
+
+/* FEIF: FIFO Error interrupt flag, streams 4-7 only */
+#define DMA_HIFCR_CFEIF_BIT DMA_ISR_FEIF
+#define DMA_HIFCR_CFEIF(stream) (DMA_HIFCR_CFEIF_BIT << (DMA_ISR_OFFSET(stream - 4))
+
+#define DMA_HIFCR_CFEIF4 DMA_HIFCR_CFEIF(DMA_STREAM4)
+#define DMA_HIFCR_CFEIF5 DMA_HIFCR_CFEIF(DMA_STREAM5)
+#define DMA_HIFCR_CFEIF6 DMA_HIFCR_CFEIF(DMA_STREAM6)
+#define DMA_HIFCR_CFEIF7 DMA_HIFCR_CFEIF(DMA_STREAM7)
+
+/* --- DMA_SxCR generic values --------------------------------------------- */
+
+/* Reserved [31:28] */
+
+/* CHSEL[13:12]: Channel Select */
+/** @defgroup dma_ch_sel DMA Channel Select
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_SCR_CHSEL_0 (0x0 << 25)
+#define DMA_SCR_CHSEL_1 (0x1 << 25)
+#define DMA_SCR_CHSEL_2 (0x2 << 25)
+#define DMA_SCR_CHSEL_3 (0x3 << 25)
+#define DMA_SCR_CHSEL_4 (0x4 << 25)
+#define DMA_SCR_CHSEL_5 (0x5 << 25)
+#define DMA_SCR_CHSEL_6 (0x6 << 25)
+#define DMA_SCR_CHSEL_7 (0x7 << 25)
+/**@}*/
+#define DMA_SCR_CHSEL_MASK (0x7 << 25)
+#define DMA_SCR_CHSEL_SHIFT 25
+
+/* MBURST[13:12]: Memory Burst Configuration */
+/** @defgroup dma_mburst DMA Memory Burst Length
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_SCR_MBURST_INCR0 (0x0 << 23)
+#define DMA_SCR_MBURST_INCR4 (0x1 << 23)
+#define DMA_SCR_MBURST_INCR8 (0x2 << 23)
+#define DMA_SCR_MBURST_INCR16 (0x3 << 23)
+/**@}*/
+#define DMA_SCR_MBURST_MASK (0x3 << 23)
+#define DMA_SCR_MBURST_SHIFT 23
+
+/* PBURST[13:12]: Peripheral Burst Configuration */
+/** @defgroup dma_pburst DMA Peripheral Burst Length
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_SCR_PBURST_INCR0 (0x0 << 21)
+#define DMA_SCR_PBURST_INCR4 (0x1 << 21)
+#define DMA_SCR_PBURST_INCR8 (0x2 << 21)
+#define DMA_SCR_PBURST_INCR16 (0x3 << 21)
+/**@}*/
+#define DMA_SCR_PBURST_MASK (0x3 << 21)
+#define DMA_SCR_PBURST_SHIFT 21
+
+/* Bit 20 reserved */
+
+/* CT: Current target (in double buffered mode) */
+#define DMA_SCR_CT (1 << 19)
+
+/* DBM: Double buffered mode */
+#define DMA_SCR_DBM (1 << 18)
+
+/* PL[17:16]: Stream priority level */
+/** @defgroup dma_st_pri DMA Stream Priority Levels
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_SCR_PL_LOW (0x0 << 16)
+#define DMA_SCR_PL_MEDIUM (0x1 << 16)
+#define DMA_SCR_PL_HIGH (0x2 << 16)
+#define DMA_SCR_PL_VERY_HIGH (0x3 << 16)
+/**@}*/
+#define DMA_SCR_PL_MASK (0x3 << 16)
+#define DMA_SCR_PL_SHIFT 16
+
+/* PINCOS: Peripheral increment offset size */
+#define DMA_SCR_PINCOS (1 << 15)
+
+/* MSIZE[14:13]: Memory size */
+/** @defgroup dma_st_memwidth DMA Stream Memory Word Width
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_SCR_MSIZE_8BIT (0x0 << 13)
+#define DMA_SCR_MSIZE_16BIT (0x1 << 13)
+#define DMA_SCR_MSIZE_32BIT (0x2 << 13)
+/**@}*/
+#define DMA_SCR_MSIZE_MASK (0x3 << 13)
+#define DMA_SCR_MSIZE_SHIFT 13
+
+/* PSIZE[12:11]: Peripheral size */
+/** @defgroup dma_st_perwidth DMA Stream Peripheral Word Width
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_SCR_PSIZE_8BIT (0x0 << 11)
+#define DMA_SCR_PSIZE_16BIT (0x1 << 11)
+#define DMA_SCR_PSIZE_32BIT (0x2 << 11)
+/**@}*/
+#define DMA_SCR_PSIZE_MASK (0x3 << 11)
+#define DMA_SCR_PSIZE_SHIFT 11
+
+/* MINC: Memory increment mode */
+#define DMA_SCR_MINC (1 << 10)
+
+/* PINC: Peripheral increment mode */
+#define DMA_SCR_PINC (1 << 9)
+
+/* CIRC: Circular mode */
+#define DMA_SCR_CIRC (1 << 8)
+
+/* DIR[7:6]: Data transfer direction */
+/** @defgroup dma_st_dir DMA Stream Data transfer direction
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_SCR_DIR_PER2MEM (0x0 << 6)
+#define DMA_SCR_DIR_MEM2PER (0x1 << 6)
+#define DMA_SCR_DIR_MEM2MEM (0x2 << 6)
+/**@}*/
+#define DMA_SCR_DIR_MASK (0x3 << 6)
+#define DMA_SCR_DIR_SHIFT 6
+
+/* PFCTRL: Peripheral Flow Controller */
+#define DMA_SCR_PFCTRL (1 << 5)
+
+/* TCIE: Transfer complete interrupt enable */
+#define DMA_SCR_TCIE (1 << 4)
+
+/* HTIE: Half transfer interrupt enable */
+#define DMA_SCR_HTIE (1 << 3)
+
+/* TEIE: Transfer error interrupt enable */
+#define DMA_SCR_TEIE (1 << 2)
+
+/* DMEIE: Direct Mode error interrupt enable */
+#define DMA_SCR_DMEIE (1 << 1)
+
+/* EN: Stream enable */
+#define DMA_SCR_EN (1 << 0)
+
+/* --- DMA_SxNDTR values --------------------------------------------------- */
+
+/* NDT[15:0]: Number of data to transfer */
+
+/* --- DMA_SxPAR values ---------------------------------------------------- */
+
+/* PA[31:0]: Peripheral address */
+
+/* --- DMA_SxM0AR values ---------------------------------------------------- */
+
+/* M0A[31:0]: Memory address */
+
+/* --- DMA_SxM1AR values ---------------------------------------------------- */
+
+/* M1A[31:0]: Memory address */
+
+/* --- DMA_SxFCR generic values --------------------------------------------- */
+
+/* Reserved [31:8] */
+
+/* FEIE: FIFO error interrupt enable */
+#define DMA_FCR_FEIE (1 << 7)
+
+/* Bit 6 reserved */
+
+/* FS[5:3]: FIFO Status */
+/** @defgroup dma_fifo_status FIFO Status
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_FCR_FS_LOW (0x0 << 3)
+#define DMA_FCR_FS_UNDER_HALF (0x1 << 3)
+#define DMA_FCR_FS_MEDIUM (0x2 << 3)
+#define DMA_FCR_FS_HIGH (0x3 << 3)
+#define DMA_FCR_FS_EMPTY (0x4 << 3)
+#define DMA_FCR_FS_FULL (0x5 << 3)
+/**@}*/
+#define DMA_FCR_FS_MASK (0x7 << 3)
+#define DMA_FCR_FS_SHIFT 3
+
+/* DMDIS: Direct Mode disable */
+#define DMA_FCR_DMDIS (1 << 2)
+
+/* FTH[1:0]: FIFO Threshold selection */
+/** @defgroup dma_fifo_thresh FIFO Threshold selection
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_FCR_FTH_LOW (0x0 << 0)
+#define DMA_FCR_FTH_HALF (0x1 << 0)
+#define DMA_FCR_FTH_MEDIUM (0x2 << 0)
+#define DMA_FCR_FTH_FULL (0x3 << 0)
+/**@}*/
+#define DMA_FCR_FTH_MASK (0x3 << 0)
+#define DMA_FCR_FTH_SHIFT 3
+
+/* --- Generic values ------------------------------------------------------ */
+
+/** @defgroup dma_st_number DMA Stream Number
+@ingroup STM32F4xx_dma_defines
+
+@{*/
+#define DMA_STREAM0 0
+#define DMA_STREAM1 1
+#define DMA_STREAM2 2
+#define DMA_STREAM3 3
+#define DMA_STREAM4 4
+#define DMA_STREAM5 5
+#define DMA_STREAM6 6
+#define DMA_STREAM7 7
+/**@}*/
+
+/* --- function prototypes ------------------------------------------------- */
+
+BEGIN_DECLS
+
+void dma_stream_reset(u32 dma, u8 stream);
+void dma_clear_interrupt_flags(u32 dma, u8 stream, u32 interrupts);
+bool dma_get_interrupt_flag(u32 dma, u8 stream, u32 interrupt);
+void dma_set_transfer_mode(u32 dma, u8 stream, u32 direction);
+void dma_set_priority(u32 dma, u8 stream, u32 prio);
+void dma_set_memory_size(u32 dma, u8 stream, u32 mem_size);
+void dma_set_peripheral_size(u32 dma, u8 stream, u32 peripheral_size);
+void dma_enable_memory_increment_mode(u32 dma, u8 stream);
+void dma_disable_memory_increment_mode(u32 dma, u8 channel);
+void dma_enable_peripheral_increment_mode(u32 dma, u8 stream);
+void dma_disable_peripheral_increment_mode(u32 dma, u8 channel);
+void dma_enable_fixed_peripheral_increment_mode(u32 dma, u8 stream);
+void dma_enable_circular_mode(u32 dma, u8 stream);
+void dma_channel_select(u32 dma, u8 stream, u32 channel);
+void dma_channel_select(u32 dma, u8 stream, u32 channel);
+void dma_set_memory_burst(u32 dma, u8 stream, u32 burst);
+void dma_set_peripheral_burst(u32 dma, u8 stream, u32 burst);
+void dma_set_initial_target(u32 dma, u8 stream, u8 memory);
+u8 dma_get_target(u32 dma, u8 stream);
+void dma_enable_double_buffer_mode(u32 dma, u8 stream);
+void dma_set_peripheral_flow_control(u32 dma, u8 stream);
+void dma_set_dma_flow_control(u32 dma, u8 stream);
+void dma_enable_transfer_error_interrupt(u32 dma, u8 stream);
+void dma_disable_transfer_error_interrupt(u32 dma, u8 stream);
+void dma_enable_half_transfer_interrupt(u32 dma, u8 stream);
+void dma_disable_half_transfer_interrupt(u32 dma, u8 stream);
+void dma_enable_transfer_complete_interrupt(u32 dma, u8 stream);
+void dma_disable_transfer_complete_interrupt(u32 dma, u8 stream);
+u32 dma_fifo_status(u32 dma, u8 stream);
+void dma_enable_direct_mode_error_interrupt(u32 dma, u8 stream);
+void dma_disable_direct_mode_error_interrupt(u32 dma, u8 stream);
+void dma_enable_fifo_error_interrupt(u32 dma, u8 stream);
+void dma_disable_fifo_error_interrupt(u32 dma, u8 stream);
+void dma_enable_direct_mode(u32 dma, u8 stream);
+void dma_enable_fifo_mode(u32 dma, u8 stream);
+void dma_set_fifo_threshold(u32 dma, u8 stream, u32 threshold);
+void dma_enable_stream(u32 dma, u8 stream);
+void dma_disable_stream(u32 dma, u8 stream);
+void dma_set_peripheral_address(u32 dma, u8 stream, u32 address);
+void dma_set_memory_address(u32 dma, u8 stream, u32 address);
+void dma_set_memory_address_1(u32 dma, u8 stream, u32 address);
+void dma_set_number_of_data(u32 dma, u8 stream, u16 number);
+
+END_DECLS
+
+#endif
+/**@}*/
+
diff --git a/include/libopencm3/stm32/f4/irq.yaml b/include/libopencm3/stm32/f4/irq.yaml
new file mode 100644
index 0000000..2d4bae9
--- /dev/null
+++ b/include/libopencm3/stm32/f4/irq.yaml
@@ -0,0 +1,85 @@
+includeguard: LIBOPENCM3_STM32_F4_NVIC_H
+partname_humanreadable: STM32 F4 series
+partname_doxygen: STM32F4
+irqs:
+ - nvic_wwdg
+ - pvd
+ - tamp_stamp
+ - rtc_wkup
+ - flash
+ - rcc
+ - exti0
+ - exti1
+ - exti2
+ - exti3
+ - exti4
+ - dma1_stream0
+ - dma1_stream1
+ - dma1_stream2
+ - dma1_stream3
+ - dma1_stream4
+ - dma1_stream5
+ - dma1_stream6
+ - adc
+ - can1_tx
+ - can1_rx0
+ - can1_rx1
+ - can1_sce
+ - exti9_5
+ - tim1_brk_tim9
+ - tim1_up_tim10
+ - tim1_trg_com_tim11
+ - tim1_cc
+ - tim2
+ - tim3
+ - tim4
+ - i2c1_ev
+ - i2c1_er
+ - i2c2_ev
+ - i2c2_er
+ - spi1
+ - spi2
+ - usart1
+ - usart2
+ - usart3
+ - exti15_10
+ - rtc_alarm
+ - usb_fs_wkup
+ - tim8_brk_tim12
+ - tim8_up_tim13
+ - tim8_trg_com_tim14
+ - tim8_cc
+ - dma1_stream7
+ - fsmc
+ - sdio
+ - tim5
+ - spi3
+ - uart4
+ - uart5
+ - tim6_dac
+ - tim7
+ - dma2_stream0
+ - dma2_stream1
+ - dma2_stream2
+ - dma2_stream3
+ - dma2_stream4
+ - eth
+ - eth_wkup
+ - can2_tx
+ - can2_rx0
+ - can2_rx1
+ - can2_sce
+ - otg_fs
+ - dma2_stream5
+ - dma2_stream6
+ - dma2_stream7
+ - usart6
+ - i2c3_ev
+ - i2c3_er
+ - otg_hs_ep1_out
+ - otg_hs_ep1_in
+ - otg_hs_wkup
+ - otg_hs
+ - dcmi
+ - cryp
+ - hash_rng
diff --git a/include/libopencm3/stm32/f4/nvic_f4.h b/include/libopencm3/stm32/f4/nvic_f4.h
deleted file mode 100644
index 91b6c25..0000000
--- a/include/libopencm3/stm32/f4/nvic_f4.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
- *
- * 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/>.
- */
-
-#ifndef LIBOPENCM3_NVIC_F4_H
-#define LIBOPENCM3_NVIC_F4_H
-
-/* --- IRQ channel numbers-------------------------------------------------- */
-
-/* Note: These F4 specific user interrupt definitions supplement the
- * general NVIC definitions in ../nvic.h
- */
-
-/* User Interrupts */
-#define NVIC_NVIC_WWDG_IRQ 0
-#define NVIC_PVD_IRQ 1
-#define NVIC_TAMP_STAMP_IRQ 2
-#define NVIC_RTC_WKUP_IRQ 3
-#define NVIC_FLASH_IRQ 4
-#define NVIC_RCC_IRQ 5
-#define NVIC_EXTI0_IRQ 6
-#define NVIC_EXTI1_IRQ 7
-#define NVIC_EXTI2_IRQ 8
-#define NVIC_EXTI3_IRQ 9
-#define NVIC_EXTI4_IRQ 10
-#define NVIC_DMA1_STREAM0_IRQ 11
-#define NVIC_DMA1_STREAM1_IRQ 12
-#define NVIC_DMA1_STREAM2_IRQ 13
-#define NVIC_DMA1_STREAM3_IRQ 14
-#define NVIC_DMA1_STREAM4_IRQ 15
-#define NVIC_DMA1_STREAM5_IRQ 16
-#define NVIC_DMA1_STREAM6_IRQ 17
-#define NVIC_ADC_IRQ 18
-#define NVIC_CAN1_TX_IRQ 19
-#define NVIC_CAN1_RX0_IRQ 20
-#define NVIC_CAN1_RX1_IRQ 21
-#define NVIC_CAN1_SCE_IRQ 22
-#define NVIC_EXTI9_5_IRQ 23
-#define NVIC_TIM1_BRK_TIM9_IRQ 24
-#define NVIC_TIM1_UP_TIM10_IRQ 25
-#define NVIC_TIM1_TRG_COM_TIM11_IRQ 26
-#define NVIC_TIM1_CC_IRQ 27
-#define NVIC_TIM2_IRQ 28
-#define NVIC_TIM3_IRQ 29
-#define NVIC_TIM4_IRQ 30
-#define NVIC_I2C1_EV_IRQ 31
-#define NVIC_I2C1_ER_IRQ 32
-#define NVIC_I2C2_EV_IRQ 33
-#define NVIC_I2C2_ER_IRQ 34
-#define NVIC_SPI1_IRQ 35
-#define NVIC_SPI2_IRQ 36
-#define NVIC_USART1_IRQ 37
-#define NVIC_USART2_IRQ 38
-#define NVIC_USART3_IRQ 39
-#define NVIC_EXTI15_10_IRQ 40
-#define NVIC_RTC_ALARM_IRQ 41
-#define NVIC_USB_FS_WKUP_IRQ 42
-#define NVIC_TIM8_BRK_TIM12_IRQ 43
-#define NVIC_TIM8_UP_TIM13_IRQ 44
-#define NVIC_TIM8_TRG_COM_TIM14_IRQ 45
-#define NVIC_TIM8_CC_IRQ 46
-#define NVIC_DMA1_STREAM7_IRQ 47
-#define NVIC_FSMC_IRQ 48
-#define NVIC_SDIO_IRQ 49
-#define NVIC_TIM5_IRQ 50
-#define NVIC_SPI3_IRQ 51
-#define NVIC_UART4_IRQ 52
-#define NVIC_UART5_IRQ 53
-#define NVIC_TIM6_DAC_IRQ 54
-#define NVIC_TIM7_IRQ 55
-#define NVIC_DMA2_STREAM0_IRQ 56
-#define NVIC_DMA2_STREAM1_IRQ 57
-#define NVIC_DMA2_STREAM2_IRQ 58
-#define NVIC_DMA2_STREAM3_IRQ 59
-#define NVIC_DMA2_STREAM4_IRQ 60
-#define NVIC_ETH_IRQ 61
-#define NVIC_ETH_WKUP_IRQ 62
-#define NVIC_CAN2_TX_IRQ 63
-#define NVIC_CAN2_RX0_IRQ 64
-#define NVIC_CAN2_RX1_IRQ 65
-#define NVIC_CAN2_SCE_IRQ 66
-#define NVIC_OTG_FS_IRQ 67
-#define NVIC_DMA2_STREAM5_IRQ 68
-#define NVIC_DMA2_STREAM6_IRQ 69
-#define NVIC_DMA2_STREAM7_IRQ 70
-#define NVIC_USART6_IRQ 71
-#define NVIC_I2C3_EV_IRQ 72
-#define NVIC_I2C3_ER_IRQ 73
-#define NVIC_OTG_HS_EP1_OUT_IRQ 74
-#define NVIC_OTG_HS_EP1_IN_IRQ 75
-#define NVIC_OTG_HS_WKUP_IRQ 76
-#define NVIC_OTG_HS_IRQ 77
-#define NVIC_DCMI_IRQ 78
-#define NVIC_CRYP_IRQ 79
-#define NVIC_HASH_RNG_IRQ 80
-
-#endif
diff --git a/include/libopencm3/stm32/f4/syscfg.h b/include/libopencm3/stm32/f4/syscfg.h
deleted file mode 100644
index 7426f16..0000000
--- a/include/libopencm3/stm32/f4/syscfg.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
- *
- * 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/>.
- */
-
-#ifndef LIBOPENCM3_SYSCFG_H
-#define LIBOPENCM3_SYSCFG_H
-
-#include <libopencm3/stm32/memorymap.h>
-
-/* --- SYSCFG registers ------------------------------------------------------ */
-
-#define SYSCFG_MEMRM MMIO32(SYSCFG_BASE + 0x00)
-
-#define SYSCFG_PMC MMIO32(SYSCFG_BASE + 0x04)
-
-/* External interrupt configuration register 1 (SYSCFG_EXTICR1) */
-#define SYSCFG_EXTICR1 MMIO32(SYSCFG_BASE + 0x08)
-
-/* External interrupt configuration register 2 (SYSCFG_EXTICR2) */
-#define SYSCFG_EXTICR2 MMIO32(SYSCFG_BASE + 0x0c)
-
-/* External interrupt configuration register 3 (SYSCFG_EXTICR3) */
-#define SYSCFG_EXTICR3 MMIO32(SYSCFG_BASE + 0x10)
-
-/* External interrupt configuration register 4 (SYSCFG_EXTICR4) */
-#define SYSCFG_EXTICR4 MMIO32(SYSCFG_BASE + 0x14)
-
-#define SYSCFG_CMPCR MMIO32(SYSCFG_BASE + 0x20)
-
-#endif
-
diff --git a/include/libopencm3/stm32/l1/gpio.h b/include/libopencm3/stm32/l1/gpio.h
new file mode 100644
index 0000000..a39c9f6
--- /dev/null
+++ b/include/libopencm3/stm32/l1/gpio.h
@@ -0,0 +1,241 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
+ *
+ * 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/>.
+ */
+
+#ifndef LIBOPENCM3_GPIO_H
+#define LIBOPENCM3_GPIO_H
+
+#include <libopencm3/stm32/memorymap.h>
+#include <libopencm3/cm3/common.h>
+
+/* --- Convenience macros -------------------------------------------------- */
+
+/* GPIO port base addresses (for convenience) */
+#define GPIOA GPIO_PORT_A_BASE
+#define GPIOB GPIO_PORT_B_BASE
+#define GPIOC GPIO_PORT_C_BASE
+#define GPIOD GPIO_PORT_D_BASE
+#define GPIOE GPIO_PORT_E_BASE
+#define GPIOH GPIO_PORT_H_BASE
+
+/* GPIO number definitions (for convenience) */
+#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
+
+/* --- GPIO registers ------------------------------------------------------ */
+
+/* Port mode register (GPIOx_MODER) */
+#define GPIO_MODER(port) MMIO32(port + 0x00)
+#define GPIOA_MODER GPIO_MODER(GPIOA)
+#define GPIOB_MODER GPIO_MODER(GPIOB)
+#define GPIOC_MODER GPIO_MODER(GPIOC)
+#define GPIOD_MODER GPIO_MODER(GPIOD)
+#define GPIOE_MODER GPIO_MODER(GPIOE)
+#define GPIOH_MODER GPIO_MODER(GPIOH)
+
+/* Port output type register (GPIOx_OTYPER) */
+#define GPIO_OTYPER(port) MMIO32(port + 0x04)
+#define GPIOA_OTYPER GPIO_OTYPER(GPIOA)
+#define GPIOB_OTYPER GPIO_OTYPER(GPIOB)
+#define GPIOC_OTYPER GPIO_OTYPER(GPIOC)
+#define GPIOD_OTYPER GPIO_OTYPER(GPIOD)
+#define GPIOE_OTYPER GPIO_OTYPER(GPIOE)
+#define GPIOH_OTYPER GPIO_OTYPER(GPIOH)
+
+/* Port output speed register (GPIOx_OSPEEDR) */
+#define GPIO_OSPEEDR(port) MMIO32(port + 0x08)
+#define GPIOA_OSPEEDR GPIO_OSPEEDR(GPIOA)
+#define GPIOB_OSPEEDR GPIO_OSPEEDR(GPIOB)
+#define GPIOC_OSPEEDR GPIO_OSPEEDR(GPIOC)
+#define GPIOD_OSPEEDR GPIO_OSPEEDR(GPIOD)
+#define GPIOE_OSPEEDR GPIO_OSPEEDR(GPIOE)
+#define GPIOH_OSPEEDR GPIO_OSPEEDR(GPIOH)
+
+/* Port pull-up/pull-down register (GPIOx_PUPDR) */
+#define GPIO_PUPDR(port) MMIO32(port + 0x0c)
+#define GPIOA_PUPDR GPIO_PUPDR(GPIOA)
+#define GPIOB_PUPDR GPIO_PUPDR(GPIOB)
+#define GPIOC_PUPDR GPIO_PUPDR(GPIOC)
+#define GPIOD_PUPDR GPIO_PUPDR(GPIOD)
+#define GPIOE_PUPDR GPIO_PUPDR(GPIOE)
+#define GPIOH_PUPDR GPIO_PUPDR(GPIOH)
+
+/* Port input data register (GPIOx_IDR) */
+#define GPIO_IDR(port) MMIO32(port + 0x10)
+#define GPIOA_IDR GPIO_IDR(GPIOA)
+#define GPIOB_IDR GPIO_IDR(GPIOB)
+#define GPIOC_IDR GPIO_IDR(GPIOC)
+#define GPIOD_IDR GPIO_IDR(GPIOD)
+#define GPIOE_IDR GPIO_IDR(GPIOE)
+#define GPIOH_IDR GPIO_IDR(GPIOH)
+
+/* Port output data register (GPIOx_ODR) */
+#define GPIO_ODR(port) MMIO32(port + 0x14)
+#define GPIOA_ODR GPIO_ODR(GPIOA)
+#define GPIOB_ODR GPIO_ODR(GPIOB)
+#define GPIOC_ODR GPIO_ODR(GPIOC)
+#define GPIOD_ODR GPIO_ODR(GPIOD)
+#define GPIOE_ODR GPIO_ODR(GPIOE)
+#define GPIOH_ODR GPIO_ODR(GPIOH)
+
+/* Port bit set/reset register (GPIOx_BSRR) */
+#define GPIO_BSRR(port) MMIO32(port + 0x18)
+#define GPIOA_BSRR GPIO_BSRR(GPIOA)
+#define GPIOB_BSRR GPIO_BSRR(GPIOB)
+#define GPIOC_BSRR GPIO_BSRR(GPIOC)
+#define GPIOD_BSRR GPIO_BSRR(GPIOD)
+#define GPIOE_BSRR GPIO_BSRR(GPIOE)
+#define GPIOH_BSRR GPIO_BSRR(GPIOH)
+
+/* Port configuration lock register (GPIOx_LCKR) */
+#define GPIO_LCKR(port) MMIO32(port + 0x1C)
+#define GPIOA_LCKR GPIO_LCKR(GPIOA)
+#define GPIOB_LCKR GPIO_LCKR(GPIOB)
+#define GPIOC_LCKR GPIO_LCKR(GPIOC)
+#define GPIOD_LCKR GPIO_LCKR(GPIOD)
+#define GPIOE_LCKR GPIO_LCKR(GPIOE)
+#define GPIOH_LCKR GPIO_LCKR(GPIOH)
+
+/* Alternate function low register (GPIOx_AFRL) */
+#define GPIO_AFRL(port) MMIO32(port + 0x20)
+#define GPIOA_AFRL GPIO_AFRL(GPIOA)
+#define GPIOB_AFRL GPIO_AFRL(GPIOB)
+#define GPIOC_AFRL GPIO_AFRL(GPIOC)
+#define GPIOD_AFRL GPIO_AFRL(GPIOD)
+#define GPIOE_AFRL GPIO_AFRL(GPIOE)
+#define GPIOH_AFRL GPIO_AFRL(GPIOH)
+
+/* Alternate function high register (GPIOx_AFRH) */
+#define GPIO_AFRH(port) MMIO32(port + 0x24)
+#define GPIOA_AFRH GPIO_AFRH(GPIOA)
+#define GPIOB_AFRH GPIO_AFRH(GPIOB)
+#define GPIOC_AFRH GPIO_AFRH(GPIOC)
+#define GPIOD_AFRH GPIO_AFRH(GPIOD)
+#define GPIOE_AFRH GPIO_AFRH(GPIOE)
+#define GPIOH_AFRH GPIO_AFRH(GPIOH)
+
+/* --- GPIOx_MODER values-------------------------------------------- */
+
+#define GPIO_MODE(n, mode) (mode << (2 * (n)))
+#define GPIO_MODE_MASK(n) (0x3 << (2 * (n)))
+#define GPIO_MODE_INPUT 0x00 /* Default */
+#define GPIO_MODE_OUTPUT 0x01
+#define GPIO_MODE_AF 0x02
+#define GPIO_MODE_ANALOG 0x03
+
+/* --- GPIOx_OTYPER values -------------------------------------------- */
+/* Output type (OTx values) */
+#define GPIO_OTYPE_PP 0x0
+#define GPIO_OTYPE_OD 0x1
+
+/* Output speed values */
+#define GPIO_OSPEED(n, speed) (speed << (2 * (n)))
+#define GPIO_OSPEED_MASK(n) (0x3 << (2 * (n)))
+#define GPIO_OSPEED_400KHZ 0x0
+#define GPIO_OSPEED_2MHZ 0x1
+#define GPIO_OSPEED_10MHZ 0x2
+#define GPIO_OSPEED_40MHZ 0x3
+
+/* --- GPIOx_PUPDR values ------------------------------------------- */
+
+#define GPIO_PUPD(n, pupd) (pupd << (2 * (n)))
+#define GPIO_PUPD_MASK(n) (0x3 << (2 * (n)))
+#define GPIO_PUPD_NONE 0x0
+#define GPIO_PUPD_PULLUP 0x1
+#define GPIO_PUPD_PULLDOWN 0x2
+
+/* --- GPIO_IDR values ----------------------------------------------------- */
+
+/* GPIO_IDR[15:0]: IDRy[15:0]: Port input data (y = 0..15) */
+
+/* --- GPIO_ODR values ----------------------------------------------------- */
+
+/* GPIO_ODR[15:0]: ODRy[15:0]: Port output data (y = 0..15) */
+
+/* --- GPIO_BSRR values ---------------------------------------------------- */
+
+/* GPIO_BSRR[31:16]: BRy: Port x reset bit y (y = 0..15) */
+/* GPIO_BSRR[15:0]: BSy: Port x set bit y (y = 0..15) */
+
+/* --- GPIO_LCKR values ---------------------------------------------------- */
+
+#define GPIO_LCKK (1 << 16)
+/* GPIO_LCKR[15:0]: LCKy: Port x lock bit y (y = 0..15) */
+
+/* --- GPIOx_AFRL/H values ------------------------------------------------- */
+
+/* Note: AFRL is used for bits 0..7, AFRH is used for 8..15 */
+/* See datasheet table 5, page 35 for the definitions */
+
+#define GPIO_AFR(n, af) (af << ((n) * 4))
+#define GPIO_AFR_MASK(n) (0xf << ((n) * 4))
+#define GPIO_AF0 0x0
+#define GPIO_AF1 0x1
+#define GPIO_AF2 0x2
+#define GPIO_AF3 0x3
+#define GPIO_AF4 0x4
+#define GPIO_AF5 0x5
+#define GPIO_AF6 0x6
+#define GPIO_AF7 0x7
+#define GPIO_AF8 0x8
+#define GPIO_AF9 0x9
+#define GPIO_AF10 0xa
+#define GPIO_AF11 0xb
+#define GPIO_AF12 0xc
+#define GPIO_AF13 0xd
+#define GPIO_AF14 0xe
+#define GPIO_AF15 0xf
+
+/* --- Function prototypes ------------------------------------------------- */
+
+/*
+ * L1, like F2 and F4, has the "new" GPIO peripheral, so use that style
+ * TODO: this should all really be moved to a "common" gpio header
+ */
+
+void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios);
+void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios);
+void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios);
+
+/* F1 compatible api */
+void gpio_set(u32 gpioport, u16 gpios);
+void gpio_clear(u32 gpioport, u16 gpios);
+u16 gpio_get(u32 gpioport, u16 gpios);
+void gpio_toggle(u32 gpioport, u16 gpios);
+u16 gpio_port_read(u32 gpioport);
+void gpio_port_write(u32 gpioport, u16 data);
+void gpio_port_config_lock(u32 gpioport, u16 gpios);
+
+#endif
diff --git a/include/libopencm3/stm32/l1/irq.yaml b/include/libopencm3/stm32/l1/irq.yaml
new file mode 100644
index 0000000..c2f118f
--- /dev/null
+++ b/include/libopencm3/stm32/l1/irq.yaml
@@ -0,0 +1,49 @@
+includeguard: LIBOPENCM3_STM32_L1_NVIC_H
+partname_humanreadable: STM32 L1 series
+partname_doxygen: STM32L1
+irqs:
+ - wwdg
+ - pvd
+ - tamper
+ - rtc
+ - flash
+ - rcc
+ - exti0
+ - exti1
+ - exti2
+ - exti3
+ - exti4
+ - dma1_channel1
+ - dma1_channel2
+ - dma1_channel3
+ - dma1_channel4
+ - dma1_channel5
+ - dma1_channel6
+ - dma1_channel7
+ - adc1
+ - usb_hp
+ - usb_lp
+ - dac
+ - comp
+ - exti9_5
+ - lcd
+ - tim9
+ - tim10
+ - tim11
+ - tim2
+ - tim3
+ - tim4
+ - i2c1_ev
+ - i2c1_er
+ - i2c2_ev
+ - i2c2_er
+ - spi1
+ - spi2
+ - usart1
+ - usart2
+ - usart3
+ - exti15_10
+ - rtc_alarm
+ - usb_wakeup
+ - tim6
+ - tim7
diff --git a/include/libopencm3/stm32/l1/memorymap.h b/include/libopencm3/stm32/l1/memorymap.h
new file mode 100644
index 0000000..950dd18
--- /dev/null
+++ b/include/libopencm3/stm32/l1/memorymap.h
@@ -0,0 +1,108 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
+ *
+ * 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/>.
+ */
+
+#ifndef LIBOPENCM3_MEMORYMAP_H
+#define LIBOPENCM3_MEMORYMAP_H
+
+#include <libopencm3/cm3/memorymap.h>
+
+/* --- STM32 specific peripheral definitions ------------------------------- */
+
+/* Memory map for all busses */
+#define PERIPH_BASE ((u32)0x40000000)
+#define INFO_BASE ((u32)0x1ff00000)
+#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000)
+#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000)
+#define PERIPH_BASE_AHB (PERIPH_BASE + 0x20000)
+
+/* Register boundary addresses */
+
+/* APB1 */
+#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000)
+#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400)
+#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800)
+#define TIM5_BASE (PERIPH_BASE_APB1 + 0x0c00)
+#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000)
+#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400)
+#define LCD_BASE (PERIPH_BASE_APB1 + 0x2400)
+#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800)
+#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00)
+#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000)
+/* PERIPH_BASE_APB1 + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */
+#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800)
+// datasheet has an error? here
+#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00)
+/* PERIPH_BASE_APB1 + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */
+#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400)
+#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800)
+#define USART4_BASE (PERIPH_BASE_APB1 + 0x4c00)
+#define USART5_BASE (PERIPH_BASE_APB1 + 0x5000)
+#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400)
+#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800)
+#define USB_DEV_FS_BASE (PERIPH_BASE_APB1 + 0x5c00)
+#define USB_SRAM_BASE (PERIPH_BASE_APB1 + 0x6000)
+/* gap */
+#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000)
+#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400)
+#define COMP_BASE (PERIPH_BASE_APB1 + 0x7c00)
+#define ROUTING_BASE (PERIPH_BASE_APB1 + 0x7c04)
+
+/* APB2 */
+#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x0000)
+#define EXTI_BASE (PERIPH_BASE_APB2 + 0x0400)
+#define TIM9_BASE (PERIPH_BASE_APB2 + 0x0800)
+#define TIM10_BASE (PERIPH_BASE_APB2 + 0x0c00)
+#define TIM11_BASE (PERIPH_BASE_APB2 + 0x1000)
+/* gap */
+#define ADC_BASE (PERIPH_BASE_APB2 + 0x2400)
+/* gap */
+#define SDIO_BASE (PERIPH_BASE_APB2 + 0x2c00)
+#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000)
+/* gap */
+#define USART1_BASE (PERIPH_BASE_APB2 + 0x3800)
+
+/* AHB */
+#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB + 0x00000)
+#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB + 0x00400)
+#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB + 0x00800)
+#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB + 0x00c00)
+#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB + 0x01000)
+#define GPIO_PORT_H_BASE (PERIPH_BASE_AHB + 0x01400)
+/* gap */
+#define CRC_BASE (PERIPH_BASE_AHB + 0x03000)
+/* gap */
+#define RCC_BASE (PERIPH_BASE_AHB + 0x03800)
+#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB + 0x03c00)
+/* gap */
+#define DMA_BASE (PERIPH_BASE_AHB + 0x06000)
+
+/* PPIB */
+#define DBGMCU_BASE (PPBI_BASE + 0x00042000)
+
+/* FSMC */
+#define FSMC_BASE (PERIPH_BASE + 0x60000000)
+/* AES */
+#define AES_BASE (PERIPH_BASE + 0x10000000)
+
+/* Device Electronic Signature */
+#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x8004C)
+#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x80050)
+
+#endif
diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h
new file mode 100644
index 0000000..209d24f
--- /dev/null
+++ b/include/libopencm3/stm32/l1/rcc.h
@@ -0,0 +1,408 @@
+/** @file
+
+@ingroup STM32L1xx
+
+@brief <b>libopencm3 STM32L1xx Reset and Clock Control</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2009 Federico Ruiz-Ugalde \<memeruiz at gmail dot com\>
+@author @htmlonly &copy; @endhtmlonly 2009 Uwe Hermann <uwe@hermann-uwe.de>
+@author @htmlonly &copy; @endhtmlonly 2012 Karl Palsson <karlp@tweak.net.au>
+
+@date 18 May 2012
+
+LGPL License Terms @ref lgpl_license
+ */
+/** @defgroup STM32L1xx_rcc_defines
+
+@brief Defined Constants and Types for the STM32L1xx Reset and Clock Control
+
+@ingroup STM32L1xx_defines
+
+LGPL License Terms @ref lgpl_license
+
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2009 Federico Ruiz-Ugalde <memeruiz at gmail dot com>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
+ *
+ * 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/>.
+ *
+ * Originally based on the F1 code, as it seemed most similar to the L1
+ * TODO: very incomplete still!
+ */
+
+#ifndef LIBOPENCM3_RCC_H
+#define LIBOPENCM3_RCC_H
+
+#include <libopencm3/stm32/memorymap.h>
+#include <libopencm3/cm3/common.h>
+
+/* --- RCC registers ------------------------------------------------------- */
+
+#define RCC_CR MMIO32(RCC_BASE + 0x00)
+#define RCC_ICSCR MMIO32(RCC_BASE + 0x04)
+#define RCC_CFGR MMIO32(RCC_BASE + 0x08)
+#define RCC_CIR MMIO32(RCC_BASE + 0x0c)
+#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x10)
+#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x14)
+#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x18)
+#define RCC_AHBENR MMIO32(RCC_BASE + 0x1c)
+#define RCC_APB2ENR MMIO32(RCC_BASE + 0x20)
+#define RCC_APB1ENR MMIO32(RCC_BASE + 0x24)
+#define RCC_AHBLPENR MMIO32(RCC_BASE + 0x28)
+#define RCC_APB2LPENR MMIO32(RCC_BASE + 0x2c)
+#define RCC_APB1LPENR MMIO32(RCC_BASE + 0x30)
+#define RCC_CSR MMIO32(RCC_BASE + 0x34)
+
+/* --- RCC_CR values ------------------------------------------------------- */
+
+/* RTCPRE[1:0] at 30:29 */
+#define RCC_CR_CSSON (1 << 28)
+#define RCC_CR_PLLRDY (1 << 25)
+#define RCC_CR_PLLON (1 << 24)
+#define RCC_CR_HSEBYP (1 << 18)
+#define RCC_CR_HSERDY (1 << 17)
+#define RCC_CR_HSEON (1 << 16)
+#define RCC_CR_MSIRDY (1 << 9)
+#define RCC_CR_MSION (1 << 8)
+#define RCC_CR_HSIRDY (1 << 1)
+#define RCC_CR_HSION (1 << 0)
+
+#define RCC_CR_RTCPRE_DIV2 0
+#define RCC_CR_RTCPRE_DIV4 1
+#define RCC_CR_RTCPRE_DIV8 2
+#define RCC_CR_RTCPRE_DIV18 3
+
+/* --- RCC_ICSCR values ---------------------------------------------------- */
+
+// TODO
+
+/* --- RCC_CFGR values ----------------------------------------------------- */
+
+/* MCOPRE */
+#define RCC_CFGR_MCOPRE_DIV1 0
+#define RCC_CFGR_MCOPRE_DIV2 1
+#define RCC_CFGR_MCOPRE_DIV4 2
+#define RCC_CFGR_MCOPRE_DIV8 3
+#define RCC_CFGR_MCOPRE_DIV16 4
+
+/* MCO: Microcontroller clock output */
+#define RCC_CFGR_MCO_NOCLK 0x0
+#define RCC_CFGR_MCO_SYSCLK 0x1
+#define RCC_CFGR_MCO_HSICLK 0x2
+#define RCC_CFGR_MCO_MSICLK 0x3
+#define RCC_CFGR_MCO_HSECLK 0x4
+#define RCC_CFGR_MCO_PLLCLK 0x5
+#define RCC_CFGR_MCO_LSICLK 0x6
+#define RCC_CFGR_MCO_LSECLK 0x7
+
+/* PLL Output division selection */
+#define RCC_CFGR_PLLDIV_DIV2 0x1
+#define RCC_CFGR_PLLDIV_DIV3 0x2
+#define RCC_CFGR_PLLDIV_DIV4 0x3
+
+/* PLLMUL: PLL multiplication factor */
+#define RCC_CFGR_PLLMUL_MUL3 0x0
+#define RCC_CFGR_PLLMUL_MUL4 0x1
+#define RCC_CFGR_PLLMUL_MUL6 0x2
+#define RCC_CFGR_PLLMUL_MUL8 0x3
+#define RCC_CFGR_PLLMUL_MUL12 0x4
+#define RCC_CFGR_PLLMUL_MUL16 0x5
+#define RCC_CFGR_PLLMUL_MUL24 0x6
+#define RCC_CFGR_PLLMUL_MUL32 0x7
+#define RCC_CFGR_PLLMUL_MUL48 0x8
+
+/* PLLSRC: PLL entry clock source */
+#define RCC_CFGR_PLLSRC_HSI_CLK 0x0
+#define RCC_CFGR_PLLSRC_HSE_CLK 0x1
+
+/* PPRE2: APB high-speed prescaler (APB2) */
+#define RCC_CFGR_PPRE2_HCLK_NODIV 0x0
+#define RCC_CFGR_PPRE2_HCLK_DIV2 0x4
+#define RCC_CFGR_PPRE2_HCLK_DIV4 0x5
+#define RCC_CFGR_PPRE2_HCLK_DIV8 0x6
+#define RCC_CFGR_PPRE2_HCLK_DIV16 0x7
+
+/* PPRE1: APB low-speed prescaler (APB1) */
+#define RCC_CFGR_PPRE1_HCLK_NODIV 0x0
+#define RCC_CFGR_PPRE1_HCLK_DIV2 0x4
+#define RCC_CFGR_PPRE1_HCLK_DIV4 0x5
+#define RCC_CFGR_PPRE1_HCLK_DIV8 0x6
+#define RCC_CFGR_PPRE1_HCLK_DIV16 0x7
+
+/* HPRE: AHB prescaler */
+#define RCC_CFGR_HPRE_SYSCLK_NODIV 0x0
+#define RCC_CFGR_HPRE_SYSCLK_DIV2 0x8
+#define RCC_CFGR_HPRE_SYSCLK_DIV4 0x9
+#define RCC_CFGR_HPRE_SYSCLK_DIV8 0xa
+#define RCC_CFGR_HPRE_SYSCLK_DIV16 0xb
+#define RCC_CFGR_HPRE_SYSCLK_DIV64 0xc
+#define RCC_CFGR_HPRE_SYSCLK_DIV128 0xd
+#define RCC_CFGR_HPRE_SYSCLK_DIV256 0xe
+#define RCC_CFGR_HPRE_SYSCLK_DIV512 0xf
+
+/* SWS: System clock switch status */
+#define RCC_CFGR_SWS_SYSCLKSEL_MSICLK 0x0
+#define RCC_CFGR_SWS_SYSCLKSEL_HSICLK 0x1
+#define RCC_CFGR_SWS_SYSCLKSEL_HSECLK 0x2
+#define RCC_CFGR_SWS_SYSCLKSEL_PLLCLK 0x3
+
+/* SW: System clock switch */
+#define RCC_CFGR_SW_SYSCLKSEL_MSICLK 0x0
+#define RCC_CFGR_SW_SYSCLKSEL_HSICLK 0x1
+#define RCC_CFGR_SW_SYSCLKSEL_HSECLK 0x2
+#define RCC_CFGR_SW_SYSCLKSEL_PLLCLK 0x3
+
+/* --- RCC_CIR values ------------------------------------------------------ */
+
+/* Clock security system interrupt clear bit */
+#define RCC_CIR_CSSC (1 << 23)
+
+/* OSC ready interrupt clear bits */
+#define RCC_CIR_MSIRDYC (1 << 21)
+#define RCC_CIR_PLLRDYC (1 << 20)
+#define RCC_CIR_HSERDYC (1 << 19)
+#define RCC_CIR_HSIRDYC (1 << 18)
+#define RCC_CIR_LSERDYC (1 << 17)
+#define RCC_CIR_LSIRDYC (1 << 16)
+
+/* OSC ready interrupt enable bits */
+#define RCC_CIR_MSIRDYIE (1 << 13)
+#define RCC_CIR_PLLRDYIE (1 << 12)
+#define RCC_CIR_HSERDYIE (1 << 11)
+#define RCC_CIR_HSIRDYIE (1 << 10)
+#define RCC_CIR_LSERDYIE (1 << 9)
+#define RCC_CIR_LSIRDYIE (1 << 8)
+
+/* Clock security system interrupt flag bit */
+#define RCC_CIR_CSSF (1 << 7)
+
+/* OSC ready interrupt flag bits */
+#define RCC_CIR_MSIRDYF (1 << 5) /* (**) */
+#define RCC_CIR_PLLRDYF (1 << 4)
+#define RCC_CIR_HSERDYF (1 << 3)
+#define RCC_CIR_HSIRDYF (1 << 2)
+#define RCC_CIR_LSERDYF (1 << 1)
+#define RCC_CIR_LSIRDYF (1 << 0)
+
+/* --- RCC_AHBRSTR values ------------------------------------------------- */
+#define RCC_AHBRSTR_DMA1RST (1 << 24)
+#define RCC_AHBRSTR_FLITFRST (1 << 15)
+#define RCC_AHBRSTR_CRCRST (1 << 12)
+#define RCC_AHBRSTR_GPIOHRST (1 << 5)
+#define RCC_AHBRSTR_GPIOERST (1 << 4)
+#define RCC_AHBRSTR_GPIODRST (1 << 3)
+#define RCC_AHBRSTR_GPIOCRST (1 << 2)
+#define RCC_AHBRSTR_GPIOBRST (1 << 1)
+#define RCC_AHBRSTR_GPIOARST (1 << 0)
+
+/* --- RCC_APB2RSTR values ------------------------------------------------- */
+
+#define RCC_APB2RSTR_USART1RST (1 << 14)
+#define RCC_APB2RSTR_SPI1RST (1 << 12)
+#define RCC_APB2RSTR_ADC1RST (1 << 9)
+#define RCC_APB2RSTR_TIM11RST (1 << 4)
+#define RCC_APB2RSTR_TIM10RST (1 << 3)
+#define RCC_APB2RSTR_TIM9RST (1 << 2)
+#define RCC_APB2RSTR_SYSCFGRST (1 << 0)
+
+/* --- RCC_APB1RSTR values ------------------------------------------------- */
+
+#define RCC_APB1RSTR_COMPRST (1 << 31)
+#define RCC_APB1RSTR_DACRST (1 << 29)
+#define RCC_APB1RSTR_PWRRST (1 << 28)
+#define RCC_APB1RSTR_USBRST (1 << 23)
+#define RCC_APB1RSTR_I2C2RST (1 << 22)
+#define RCC_APB1RSTR_I2C1RST (1 << 21)
+#define RCC_APB1RSTR_USART3RST (1 << 18)
+#define RCC_APB1RSTR_USART2RST (1 << 17)
+#define RCC_APB1RSTR_SPI2RST (1 << 14)
+#define RCC_APB1RSTR_WWDGRST (1 << 11)
+#define RCC_APB1RSTR_LCDRST (1 << 9)
+#define RCC_APB1RSTR_TIM7RST (1 << 5)
+#define RCC_APB1RSTR_TIM6RST (1 << 4)
+#define RCC_APB1RSTR_TIM4RST (1 << 2)
+#define RCC_APB1RSTR_TIM3RST (1 << 1)
+#define RCC_APB1RSTR_TIM2RST (1 << 0)
+
+/* --- RCC_AHBENR values --------------------------------------------------- */
+
+/** @defgroup rcc_ahbenr_en RCC_AHBENR enable values
+@ingroup STM32L1xx_rcc_defines
+
+@{*/
+#define RCC_AHBENR_DMA1EN (1 << 24)
+#define RCC_AHBENR_FLITFEN (1 << 15)
+#define RCC_AHBENR_CRCEN (1 << 12)
+#define RCC_AHBENR_GPIOHEN (1 << 5)
+#define RCC_AHBENR_GPIOEEN (1 << 4)
+#define RCC_AHBENR_GPIODEN (1 << 3)
+#define RCC_AHBENR_GPIOCEN (1 << 2)
+#define RCC_AHBENR_GPIOBEN (1 << 1)
+#define RCC_AHBENR_GPIOAEN (1 << 0)
+/*@}*/
+
+/* --- RCC_APB2ENR values -------------------------------------------------- */
+
+/** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values
+@ingroup STM32L1xx_rcc_defines
+
+@{*/
+#define RCC_APB2ENR_USART1EN (1 << 14)
+#define RCC_APB2ENR_SPI1EN (1 << 12)
+#define RCC_APB2ENR_ADC1EN (1 << 9)
+#define RCC_APB2ENR_TIM11EN (1 << 4)
+#define RCC_APB2ENR_TIM10EN (1 << 3)
+#define RCC_APB2ENR_TIM9EN (1 << 2)
+#define RCC_APB2ENR_SYSCFGEN (1 << 0)
+/*@}*/
+
+/* --- RCC_APB1ENR values -------------------------------------------------- */
+
+/** @defgroup rcc_apb1enr_en RCC_APB1ENR enable values
+@ingroup STM32L1xx_rcc_defines
+
+@{*/
+#define RCC_APB1ENR_COMPEN (1 << 31)
+#define RCC_APB1ENR_DACEN (1 << 29)
+#define RCC_APB1ENR_PWREN (1 << 28)
+#define RCC_APB1ENR_USBEN (1 << 23)
+#define RCC_APB1ENR_I2C2EN (1 << 22)
+#define RCC_APB1ENR_I2C1EN (1 << 21)
+#define RCC_APB1ENR_USART3EN (1 << 18)
+#define RCC_APB1ENR_USART2EN (1 << 17)
+#define RCC_APB1ENR_SPI2EN (1 << 14)
+#define RCC_APB1ENR_WWDGEN (1 << 11)
+#define RCC_APB1ENR_LCDEN (1 << 9)
+#define RCC_APB1ENR_TIM7EN (1 << 5)
+#define RCC_APB1ENR_TIM6EN (1 << 4)
+#define RCC_APB1ENR_TIM4EN (1 << 2)
+#define RCC_APB1ENR_TIM3EN (1 << 1)
+#define RCC_APB1ENR_TIM2EN (1 << 0)
+/*@}*/
+
+/* --- RCC_AHBLPENR -------------------------------------------------------- */
+#define RCC_AHBLPENR_DMA1LPEN (1 << 24)
+#define RCC_AHBLPENR_SRAMLPEN (1 << 16)
+#define RCC_AHBLPENR_FLITFLPEN (1 << 15)
+#define RCC_AHBLPENR_CRCLPEN (1 << 12)
+#define RCC_AHBLPENR_GPIOHLPEN (1 << 5)
+#define RCC_AHBLPENR_GPIOELPEN (1 << 4)
+#define RCC_AHBLPENR_GPIODLPEN (1 << 3)
+#define RCC_AHBLPENR_GPIOCLPEN (1 << 2)
+#define RCC_AHBLPENR_GPIOBLPEN (1 << 1)
+#define RCC_AHBLPENR_GPIOALPEN (1 << 0)
+
+#define RCC_APB2LPENR_USART1LPEN (1 << 14)
+#define RCC_APB2LPENR_SPI1LPEN (1 << 12)
+#define RCC_APB2LPENR_ADC1LPEN (1 << 9)
+#define RCC_APB2LPENR_TIM11LPEN (1 << 4)
+#define RCC_APB2LPENR_TIM10LPEN (1 << 3)
+#define RCC_APB2LPENR_TIM9LPEN (1 << 2)
+#define RCC_APB2LPENR_SYSCFGLPEN (1 << 0)
+
+#define RCC_APB1LPENR_COMPLPEN (1 << 31)
+#define RCC_APB1LPENR_DACLPEN (1 << 29)
+#define RCC_APB1LPENR_PWRLPEN (1 << 28)
+#define RCC_APB1LPENR_USBLPEN (1 << 23)
+#define RCC_APB1LPENR_I2C2LPEN (1 << 22)
+#define RCC_APB1LPENR_I2C1LPEN (1 << 21)
+#define RCC_APB1LPENR_USART3LPEN (1 << 18)
+#define RCC_APB1LPENR_USART2LPEN (1 << 17)
+#define RCC_APB1LPENR_SPI2LPEN (1 << 14)
+#define RCC_APB1LPENR_WWDGLPEN (1 << 11)
+#define RCC_APB1LPENR_LCDLPEN (1 << 9)
+#define RCC_APB1LPENR_TIM7LPEN (1 << 5)
+#define RCC_APB1LPENR_TIM6LPEN (1 << 4)
+#define RCC_APB1LPENR_TIM4LPEN (1 << 2)
+#define RCC_APB1LPENR_TIM3LPEN (1 << 1)
+#define RCC_APB1LPENR_TIM2LPEN (1 << 0)
+
+
+/* --- RCC_CSR values ------------------------------------------------------ */
+
+#define RCC_CSR_LPWRRSTF (1 << 31)
+#define RCC_CSR_WWDGRSTF (1 << 30)
+#define RCC_CSR_IWDGRSTF (1 << 29)
+#define RCC_CSR_SFTRSTF (1 << 28)
+#define RCC_CSR_PORRSTF (1 << 27)
+#define RCC_CSR_PINRSTF (1 << 26)
+#define RCC_CSR_OBLRSTF (1 << 25)
+#define RCC_CSR_RMVF (1 << 24)
+#define RCC_CSR_RTCRST (1 << 23)
+#define RCC_CSR_RTCEN (1 << 22)
+/* RTCSEL[1:0] */
+#define RCC_CSR_LSEBYP (1 << 10)
+#define RCC_CSR_LSERDY (1 << 9)
+#define RCC_CSR_LSEON (1 << 8)
+#define RCC_CSR_LSIRDY (1 << 1)
+#define RCC_CSR_LSION (1 << 0)
+
+
+/* --- Variable definitions ------------------------------------------------ */
+extern u32 rcc_ppre1_frequency;
+extern u32 rcc_ppre2_frequency;
+
+/* --- Function prototypes ------------------------------------------------- */
+
+typedef enum {
+ PLL, HSE, HSI, MSI, LSE, LSI
+} osc_t;
+
+void rcc_osc_ready_int_clear(osc_t osc);
+void rcc_osc_ready_int_enable(osc_t osc);
+void rcc_osc_ready_int_disable(osc_t osc);
+int rcc_osc_ready_int_flag(osc_t osc);
+void rcc_css_int_clear(void);
+int rcc_css_int_flag(void);
+void rcc_wait_for_osc_ready(osc_t osc);
+void rcc_osc_on(osc_t osc);
+void rcc_osc_off(osc_t osc);
+void rcc_css_enable(void);
+void rcc_css_disable(void);
+void rcc_osc_bypass_enable(osc_t osc);
+void rcc_osc_bypass_disable(osc_t osc);
+void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en);
+void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en);
+void rcc_peripheral_reset(volatile u32 *reg, u32 reset);
+void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset);
+void rcc_set_sysclk_source(u32 clk);
+void rcc_set_pll_multiplication_factor(u32 mul);
+void rcc_set_pll_source(u32 pllsrc);
+void rcc_set_pllxtpre(u32 pllxtpre);
+void rcc_set_adcpre(u32 adcpre);
+void rcc_set_ppre2(u32 ppre2);
+void rcc_set_ppre1(u32 ppre1);
+void rcc_set_hpre(u32 hpre);
+void rcc_set_usbpre(u32 usbpre);
+u32 rcc_get_system_clock_source(int i);
+void rcc_clock_setup_in_hsi_out_64mhz(void);
+void rcc_clock_setup_in_hsi_out_48mhz(void);
+
+/**
+ * Maximum speed possible for F100 (Value Line) on HSI
+ */
+void rcc_clock_setup_in_hsi_out_24mhz(void);
+void rcc_clock_setup_in_hse_8mhz_out_24mhz(void);
+void rcc_clock_setup_in_hse_8mhz_out_72mhz(void);
+void rcc_clock_setup_in_hse_12mhz_out_72mhz(void);
+void rcc_clock_setup_in_hse_16mhz_out_72mhz(void);
+void rcc_backupdomain_reset(void);
+
+#endif
diff --git a/include/libopencm3/stm32/memorymap.h b/include/libopencm3/stm32/memorymap.h
index 6f213da..9b757ce 100644
--- a/include/libopencm3/stm32/memorymap.h
+++ b/include/libopencm3/stm32/memorymap.h
@@ -26,6 +26,8 @@
# include <libopencm3/stm32/f2/memorymap.h>
#elif defined(STM32F4)
# include <libopencm3/stm32/f4/memorymap.h>
+#elif defined(STM32L1)
+# include <libopencm3/stm32/l1/memorymap.h>
#else
# error "stm32 family not defined."
#endif
diff --git a/include/libopencm3/stm32/otg_fs.h b/include/libopencm3/stm32/otg_fs.h
index 5680e43..d8ee393 100644
--- a/include/libopencm3/stm32/otg_fs.h
+++ b/include/libopencm3/stm32/otg_fs.h
@@ -24,7 +24,7 @@
#include <libopencm3/cm3/common.h>
/* Core Global Control and Status Registers */
-#define OTG_FS_OTGCTL MMIO32(USB_OTG_FS_BASE + 0x000)
+#define OTG_FS_GOTGCTL MMIO32(USB_OTG_FS_BASE + 0x000)
#define OTG_FS_GOTGINT MMIO32(USB_OTG_FS_BASE + 0x004)
#define OTG_FS_GAHBCFG MMIO32(USB_OTG_FS_BASE + 0x008)
#define OTG_FS_GUSBCFG MMIO32(USB_OTG_FS_BASE + 0x00C)
@@ -42,40 +42,40 @@
#define OTG_FS_DIEPTXF(x) MMIO32(USB_OTG_FS_BASE + 0x104 + 4*(x-1))
/* Host-mode Control and Status Registers */
-#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400)
-#define OTG_FS_HFIR MMIO32(USB_OTG_FS_BASE + 0x404)
-#define OTG_FS_HFNUM MMIO32(USB_OTG_FS_BASE + 0x408)
-#define OTG_FS_HPTXSTS MMIO32(USB_OTG_FS_BASE + 0x410)
-#define OTG_FS_HAINT MMIO32(USB_OTG_FS_BASE + 0x414)
-#define OTG_FS_HAINTMSK MMIO32(USB_OTG_FS_BASE + 0x418)
-#define OTG_FS_HPRT MMIO32(USB_OTG_FS_BASE + 0x440)
-#define OTG_FS_HCCHARx MMIO32(USB_OTG_FS_BASE + 0x500)
-#define OTG_FS_HCINTx MMIO32(USB_OTG_FS_BASE + 0x508)
-#define OTG_FS_HCINTMSKx MMIO32(USB_OTG_FS_BASE + 0x50C)
-#define OTG_FS_HCTSIZx MMIO32(USB_OTG_FS_BASE + 0x510)
+#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400)
+#define OTG_FS_HFIR MMIO32(USB_OTG_FS_BASE + 0x404)
+#define OTG_FS_HFNUM MMIO32(USB_OTG_FS_BASE + 0x408)
+#define OTG_FS_HPTXSTS MMIO32(USB_OTG_FS_BASE + 0x410)
+#define OTG_FS_HAINT MMIO32(USB_OTG_FS_BASE + 0x414)
+#define OTG_FS_HAINTMSK MMIO32(USB_OTG_FS_BASE + 0x418)
+#define OTG_FS_HPRT MMIO32(USB_OTG_FS_BASE + 0x440)
+#define OTG_FS_HCCHARx MMIO32(USB_OTG_FS_BASE + 0x500)
+#define OTG_FS_HCINTx MMIO32(USB_OTG_FS_BASE + 0x508)
+#define OTG_FS_HCINTMSKx MMIO32(USB_OTG_FS_BASE + 0x50C)
+#define OTG_FS_HCTSIZx MMIO32(USB_OTG_FS_BASE + 0x510)
/* Device-mode Control and Status Registers */
-#define OTG_FS_DCFG MMIO32(USB_OTG_FS_BASE + 0x800)
-#define OTG_FS_DCTL MMIO32(USB_OTG_FS_BASE + 0x804)
-#define OTG_FS_DSTS MMIO32(USB_OTG_FS_BASE + 0x808)
-#define OTG_FS_DIEPMSK MMIO32(USB_OTG_FS_BASE + 0x810)
-#define OTG_FS_DOEPMSK MMIO32(USB_OTG_FS_BASE + 0x814)
-#define OTG_FS_DAINT MMIO32(USB_OTG_FS_BASE + 0x818)
-#define OTG_FS_DAINTMSK MMIO32(USB_OTG_FS_BASE + 0x81C)
-#define OTG_FS_DVBUSDIS MMIO32(USB_OTG_FS_BASE + 0x828)
-#define OTG_FS_DVBUSPULSE MMIO32(USB_OTG_FS_BASE + 0x82C)
-#define OTG_FS_DIEPEMPMSK MMIO32(USB_OTG_FS_BASE + 0x834)
-#define OTG_FS_DIEPCTL0 MMIO32(USB_OTG_FS_BASE + 0x900)
-#define OTG_FS_DIEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0x900 + 0x20*(x))
-#define OTG_FS_DOEPCTL0 MMIO32(USB_OTG_FS_BASE + 0xB00)
-#define OTG_FS_DOEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0xB00 + 0x20*(x))
-#define OTG_FS_DIEPINT(x) MMIO32(USB_OTG_FS_BASE + 0x908 + 0x20*(x))
-#define OTG_FS_DOEPINT(x) MMIO32(USB_OTG_FS_BASE + 0xB08 + 0x20*(x))
-#define OTG_FS_DIEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0x910)
-#define OTG_FS_DOEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0xB10)
-#define OTG_FS_DIEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0x910 + 0x20*(x))
-#define OTG_FS_DTXFSTS(x) MMIO32(USB_OTG_FS_BASE + 0x918 + 0x20*(x))
-#define OTG_FS_DOEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0xB10 + 0x20*(x))
+#define OTG_FS_DCFG MMIO32(USB_OTG_FS_BASE + 0x800)
+#define OTG_FS_DCTL MMIO32(USB_OTG_FS_BASE + 0x804)
+#define OTG_FS_DSTS MMIO32(USB_OTG_FS_BASE + 0x808)
+#define OTG_FS_DIEPMSK MMIO32(USB_OTG_FS_BASE + 0x810)
+#define OTG_FS_DOEPMSK MMIO32(USB_OTG_FS_BASE + 0x814)
+#define OTG_FS_DAINT MMIO32(USB_OTG_FS_BASE + 0x818)
+#define OTG_FS_DAINTMSK MMIO32(USB_OTG_FS_BASE + 0x81C)
+#define OTG_FS_DVBUSDIS MMIO32(USB_OTG_FS_BASE + 0x828)
+#define OTG_FS_DVBUSPULSE MMIO32(USB_OTG_FS_BASE + 0x82C)
+#define OTG_FS_DIEPEMPMSK MMIO32(USB_OTG_FS_BASE + 0x834)
+#define OTG_FS_DIEPCTL0 MMIO32(USB_OTG_FS_BASE + 0x900)
+#define OTG_FS_DIEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0x900 + 0x20*(x))
+#define OTG_FS_DOEPCTL0 MMIO32(USB_OTG_FS_BASE + 0xB00)
+#define OTG_FS_DOEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0xB00 + 0x20*(x))
+#define OTG_FS_DIEPINT(x) MMIO32(USB_OTG_FS_BASE + 0x908 + 0x20*(x))
+#define OTG_FS_DOEPINT(x) MMIO32(USB_OTG_FS_BASE + 0xB08 + 0x20*(x))
+#define OTG_FS_DIEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0x910)
+#define OTG_FS_DOEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0xB10)
+#define OTG_FS_DIEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0x910 + 0x20*(x))
+#define OTG_FS_DTXFSTS(x) MMIO32(USB_OTG_FS_BASE + 0x918 + 0x20*(x))
+#define OTG_FS_DOEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0xB10 + 0x20*(x))
/* Power and clock gating control and status register */
#define OTG_FS_PCGCCTL MMIO32(USB_OTG_FS_BASE + 0xE00)
@@ -84,6 +84,18 @@
#define OTG_FS_FIFO(x) ((volatile u32*)(USB_OTG_FS_BASE + (((x) + 1) << 12)))
/* Global CSRs */
+/* OTG_FS USB control registers (OTG_HS_GOTGCTL) */
+#define OTG_FS_GOTGCTL_BSVLD (1 << 19)
+#define OTG_FS_GOTGCTL_ASVLD (1 << 18)
+#define OTG_FS_GOTGCTL_DBCT (1 << 17)
+#define OTG_FS_GOTGCTL_CIDSTS (1 << 16)
+#define OTG_FS_GOTGCTL_DHNPEN (1 << 11)
+#define OTG_FS_GOTGCTL_HSHNPEN (1 << 10)
+#define OTG_FS_GOTGCTL_HNPRQ (1 << 9)
+#define OTG_FS_GOTGCTL_HNGSCS (1 << 8)
+#define OTG_FS_GOTGCTL_SRQ (1 << 1)
+#define OTG_FS_GOTGCTL_SRQSCS (1 << 0)
+
/* OTG_FS AHB configuration register (OTG_FS_GAHBCFG) */
#define OTG_FS_GAHBCFG_GINT 0x0001
#define OTG_FS_GAHBCFG_TXFELVL 0x0080
@@ -175,20 +187,20 @@
/* OTG_FS Receive Status Pop Register (OTG_FS_GRXSTSP) */
/* Bits 31:25 - Reserved */
-#define OTG_FS_GRXSTSP_FRMNUM_MASK (0xf << 21)
-#define OTG_FS_GRXSTSP_PKTSTS_MASK (0xf << 17)
-#define OTG_FS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17)
-#define OTG_FS_GRXSTSP_PKTSTS_OUT (0x2 << 17)
-#define OTG_FS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17)
+#define OTG_FS_GRXSTSP_FRMNUM_MASK (0xf << 21)
+#define OTG_FS_GRXSTSP_PKTSTS_MASK (0xf << 17)
+#define OTG_FS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17)
+#define OTG_FS_GRXSTSP_PKTSTS_OUT (0x2 << 17)
+#define OTG_FS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17)
#define OTG_FS_GRXSTSP_PKTSTS_SETUP_COMP (0x4 << 17)
-#define OTG_FS_GRXSTSP_PKTSTS_SETUP (0x6 << 17)
-#define OTG_FS_GRXSTSP_DPID_MASK (0x3 << 15)
-#define OTG_FS_GRXSTSP_DPID_DATA0 (0x0 << 15)
-#define OTG_FS_GRXSTSP_DPID_DATA1 (0x2 << 15)
-#define OTG_FS_GRXSTSP_DPID_DATA2 (0x1 << 15)
-#define OTG_FS_GRXSTSP_DPID_MDATA (0x3 << 15)
-#define OTG_FS_GRXSTSP_BCNT_MASK (0x7ff << 4)
-#define OTG_FS_GRXSTSP_EPNUM_MASK (0xf << 0)
+#define OTG_FS_GRXSTSP_PKTSTS_SETUP (0x6 << 17)
+#define OTG_FS_GRXSTSP_DPID_MASK (0x3 << 15)
+#define OTG_FS_GRXSTSP_DPID_DATA0 (0x0 << 15)
+#define OTG_FS_GRXSTSP_DPID_DATA1 (0x2 << 15)
+#define OTG_FS_GRXSTSP_DPID_DATA2 (0x1 << 15)
+#define OTG_FS_GRXSTSP_DPID_MDATA (0x3 << 15)
+#define OTG_FS_GRXSTSP_BCNT_MASK (0x7ff << 4)
+#define OTG_FS_GRXSTSP_EPNUM_MASK (0xf << 0)
/* OTG_FS general core configuration register (OTG_FS_GCCFG) */
/* Bits 31:21 - Reserved */
@@ -320,4 +332,3 @@
#define OTG_FS_DIEPSIZ0_XFRSIZ_MASK (0x7f << 0)
#endif
-
diff --git a/include/libopencm3/stm32/otg_hs.h b/include/libopencm3/stm32/otg_hs.h
new file mode 100644
index 0000000..2f59ddd
--- /dev/null
+++ b/include/libopencm3/stm32/otg_hs.h
@@ -0,0 +1,396 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * 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/>.
+ */
+
+#ifndef LIBOPENCM3_OTG_HS_H
+#define LIBOPENCM3_OTG_HS_H
+
+#include <libopencm3/stm32/memorymap.h>
+#include <libopencm3/cm3/common.h>
+
+/* Core Global Control and Status Registers */
+#define OTG_GOTGCTL 0x000
+#define OTG_GOTGIN 0x004
+#define OTG_GAHBCFG 0x008
+#define OTG_GUSBCFG 0x00C
+#define OTG_GRSTCTL 0x010
+#define OTG_GINTSTS 0x014
+#define OTG_GINTMSK 0x018
+#define OTG_GRXSTSR 0x01C
+#define OTG_GRXSTSP 0x020
+#define OTG_GRXFSIZ 0x024
+#define OTG_GNPTXFSIZ 0x028
+#define OTG_GNPTXSTS 0x02C
+#define OTG_GCCFG 0x038
+#define OTG_CID 0x03C
+#define OTG_HPTXFSIZ 0x100
+#define OTG_DIEPTXF(x) (0x104 + 4*(x-1))
+
+/* Host-mode Control and Status Registers */
+#define OTG_HCFG 0x400
+#define OTG_HFIR 0x404
+#define OTG_HFNUM 0x408
+#define OTG_HPTXSTS 0x410
+#define OTG_HAINT 0x414
+#define OTG_HAINTMSK 0x418
+#define OTG_HPRT 0x440
+#define OTG_HCCHARx 0x500
+#define OTG_HCINTx 0x508
+#define OTG_HCINTMSKx 0x50C
+#define OTG_HCTSIZx 0x510
+
+/* Device-mode Control and Status Registers */
+#define OTG_DCFG 0x800
+#define OTG_DCTL 0x804
+#define OTG_DSTS 0x808
+#define OTG_DIEPMSK 0x810
+#define OTG_DOEPMSK 0x814
+#define OTG_DAINT 0x818
+#define OTG_DAINTMSK 0x81C
+#define OTG_DVBUSDIS 0x828
+#define OTG_DVBUSPULSE 0x82C
+#define OTG_DIEPEMPMSK 0x834
+#define OTG_DIEPCTL0 0x900
+#define OTG_DIEPCTL(x) (0x900 + 0x20*(x))
+#define OTG_DOEPCTL0 0xB00
+#define OTG_DOEPCTL(x) (0xB00 + 0x20*(x))
+#define OTG_DIEPINT(x) (0x908 + 0x20*(x))
+#define OTG_DOEPINT(x) (0xB08 + 0x20*(x))
+#define OTG_DIEPTSIZ0 0x910
+#define OTG_DOEPTSIZ0 0xB10
+#define OTG_DIEPTSIZ(x) (0x910 + 0x20*(x))
+#define OTG_DTXFSTS(x) (0x918 + 0x20*(x))
+#define OTG_DOEPTSIZ(x) (0xB10 + 0x20*(x))
+
+/* Power and clock gating control and status register */
+#define OTG_PCGCCTL 0xE00
+
+/* Data FIFO */
+#define OTG_FIFO(x) (((x) + 1) << 12)
+
+/***********************************************************************/
+
+/* Core Global Control and Status Registers */
+#define OTG_HS_GOTGCTL MMIO32(USB_OTG_HS_BASE + OTG_GOTGCTL)
+#define OTG_HS_GOTGINT MMIO32(USB_OTG_HS_BASE + OTG_GOTGINT)
+#define OTG_HS_GAHBCFG MMIO32(USB_OTG_HS_BASE + OTG_GAHBCFG)
+#define OTG_HS_GUSBCFG MMIO32(USB_OTG_HS_BASE + OTG_GUSBCFG)
+#define OTG_HS_GRSTCTL MMIO32(USB_OTG_HS_BASE + OTG_GRSTCTL)
+#define OTG_HS_GINTSTS MMIO32(USB_OTG_HS_BASE + OTG_GINTSTS)
+#define OTG_HS_GINTMSK MMIO32(USB_OTG_HS_BASE + OTG_GINTMSK)
+#define OTG_HS_GRXSTSR MMIO32(USB_OTG_HS_BASE + OTG_GRXSTSR)
+#define OTG_HS_GRXSTSP MMIO32(USB_OTG_HS_BASE + OTG_GRXSTSP)
+#define OTG_HS_GRXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_GRXFSIZ)
+#define OTG_HS_GNPTXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_GNPTXFSIZ)
+#define OTG_HS_GNPTXSTS MMIO32(USB_OTG_HS_BASE + OTG_GNPTXSTS)
+#define OTG_HS_GCCFG MMIO32(USB_OTG_HS_BASE + OTG_GCCFG)
+#define OTG_HS_CID MMIO32(USB_OTG_HS_BASE + OTG_CID)
+#define OTG_HS_HPTXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_HPTXFSIZ)
+#define OTG_HS_DIEPTXF(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPTXF(x))
+
+/* Host-mode Control and Status Registers */
+#define OTG_HS_HCFG MMIO32(USB_OTG_HS_BASE + OTG_HCFG)
+#define OTG_HS_HFIR MMIO32(USB_OTG_HS_BASE + OTG_HFIR)
+#define OTG_HS_HFNUM MMIO32(USB_OTG_HS_BASE + OTG_HFNUM)
+#define OTG_HS_HPTXSTS MMIO32(USB_OTG_HS_BASE + OTG_HPTXSTS)
+#define OTG_HS_HAINT MMIO32(USB_OTG_HS_BASE + OTG_HAINT)
+#define OTG_HS_HAINTMSK MMIO32(USB_OTG_HS_BASE + OTG_HAINTMSK)
+#define OTG_HS_HPRT MMIO32(USB_OTG_HS_BASE + OTG_HPRT)
+#define OTG_HS_HCCHARx MMIO32(USB_OTG_HS_BASE + OTG_HCCHARx)
+#define OTG_HS_HCINTx MMIO32(USB_OTG_HS_BASE + OTG_HCINTx)
+#define OTG_HS_HCINTMSKx MMIO32(USB_OTG_HS_BASE + OTG_HCINTMSKx)
+#define OTG_HS_HCTSIZx MMIO32(USB_OTG_HS_BASE + OTG_HCTSIZx)
+
+/* Device-mode Control and Status Registers */
+#define OTG_HS_DCFG MMIO32(USB_OTG_HS_BASE + OTG_DCFG)
+#define OTG_HS_DCTL MMIO32(USB_OTG_HS_BASE + OTG_DCTL)
+#define OTG_HS_DSTS MMIO32(USB_OTG_HS_BASE + OTG_DSTS)
+#define OTG_HS_DIEPMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPMSK)
+#define OTG_HS_DOEPMSK MMIO32(USB_OTG_HS_BASE + OTG_DOEPMSK)
+#define OTG_HS_DAINT MMIO32(USB_OTG_HS_BASE + OTG_DAINT)
+#define OTG_HS_DAINTMSK MMIO32(USB_OTG_HS_BASE + OTG_DAINTMSK)
+#define OTG_HS_DVBUSDIS MMIO32(USB_OTG_HS_BASE + OTG_DVBUSDIS)
+#define OTG_HS_DVBUSPULSE MMIO32(USB_OTG_HS_BASE + OTG_DVBUSPULSE)
+#define OTG_HS_DIEPEMPMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPEMPMSK)
+#define OTG_HS_DIEPCTL0 MMIO32(USB_OTG_HS_BASE + OTG_DIEPCTL0)
+#define OTG_HS_DIEPCTL(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPCTL(x))
+#define OTG_HS_DOEPCTL0 MMIO32(USB_OTG_HS_BASE + OTG_DOEPCTL0)
+#define OTG_HS_DOEPCTL(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPCTL(x))
+#define OTG_HS_DIEPINT(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPINT(x))
+#define OTG_HS_DOEPINT(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPINT(x))
+#define OTG_HS_DIEPTSIZ0 MMIO32(USB_OTG_HS_BASE + OTG_DIEPTSIZ0)
+#define OTG_HS_DOEPTSIZ0 MMIO32(USB_OTG_HS_BASE + OTG_DOEPTSIZ0)
+#define OTG_HS_DIEPTSIZ(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPTSIZ(x)))
+#define OTG_HS_DTXFSTS(x) MMIO32(USB_OTG_HS_BASE + OTG_DTXFSTS(x))
+#define OTG_HS_DOEPTSIZ(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPTSIZ(x))
+
+/* Power and clock gating control and status register */
+#define OTG_HS_PCGCCTL MMIO32(USB_OTG_HS_BASE + OTG_PCGCCTL)
+
+/* Data FIFO */
+#define OTG_HS_FIFO(x) ((volatile u32*)(USB_OTG_HS_BASE + OTG_FIFO(x)))
+
+/* Global CSRs */
+/* OTG_HS USB control registers (OTG_FS_GOTGCTL) */
+#define OTG_HS_GOTGCTL_BSVLD (1 << 19)
+#define OTG_HS_GOTGCTL_ASVLD (1 << 18)
+#define OTG_HS_GOTGCTL_DBCT (1 << 17)
+#define OTG_HS_GOTGCTL_CIDSTS (1 << 16)
+#define OTG_HS_GOTGCTL_DHNPEN (1 << 11)
+#define OTG_HS_GOTGCTL_HSHNPEN (1 << 10)
+#define OTG_HS_GOTGCTL_HNPRQ (1 << 9)
+#define OTG_HS_GOTGCTL_HNGSCS (1 << 8)
+#define OTG_HS_GOTGCTL_SRQ (1 << 1)
+#define OTG_HS_GOTGCTL_SRQSCS (1 << 0)
+
+/* OTG_FS AHB configuration register (OTG_HS_GAHBCFG) */
+#define OTG_HS_GAHBCFG_GINT 0x0001
+#define OTG_HS_GAHBCFG_TXFELVL 0x0080
+#define OTG_HS_GAHBCFG_PTXFELVL 0x0100
+
+/* OTG_FS USB configuration register (OTG_HS_GUSBCFG) */
+#define OTG_HS_GUSBCFG_TOCAL 0x00000003
+#define OTG_HS_GUSBCFG_SRPCAP 0x00000100
+#define OTG_HS_GUSBCFG_HNPCAP 0x00000200
+#define OTG_HS_GUSBCFG_TRDT_MASK (0xf << 10)
+#define OTG_HS_GUSBCFG_TRDT_16BIT (0x5 << 10)
+#define OTG_HS_GUSBCFG_TRDT_8BIT (0x9 << 10)
+#define OTG_HS_GUSBCFG_NPTXRWEN 0x00004000
+#define OTG_HS_GUSBCFG_FHMOD 0x20000000
+#define OTG_HS_GUSBCFG_FDMOD 0x40000000
+#define OTG_HS_GUSBCFG_CTXPKT 0x80000000
+#define OTG_HS_GUSBCFG_PHYSEL (1 << 6)
+
+/* OTG_FS reset register (OTG_HS_GRSTCTL) */
+#define OTG_HS_GRSTCTL_AHBIDL (1 << 31)
+/* Bits 30:11 - Reserved */
+#define OTG_HS_GRSTCTL_TXFNUM_MASK (0x1f << 6)
+#define OTG_HS_GRSTCTL_TXFFLSH (1 << 5)
+#define OTG_HS_GRSTCTL_RXFFLSH (1 << 4)
+/* Bit 3 - Reserved */
+#define OTG_HS_GRSTCTL_FCRST (1 << 2)
+#define OTG_HS_GRSTCTL_HSRST (1 << 1)
+#define OTG_HS_GRSTCTL_CSRST (1 << 0)
+
+/* OTG_FS interrupt status register (OTG_HS_GINTSTS) */
+#define OTG_HS_GINTSTS_WKUPINT (1 << 31)
+#define OTG_HS_GINTSTS_SRQINT (1 << 30)
+#define OTG_HS_GINTSTS_DISCINT (1 << 29)
+#define OTG_HS_GINTSTS_CIDSCHG (1 << 28)
+/* Bit 27 - Reserved */
+#define OTG_HS_GINTSTS_PTXFE (1 << 26)
+#define OTG_HS_GINTSTS_HCINT (1 << 25)
+#define OTG_HS_GINTSTS_HPRTINT (1 << 24)
+/* Bits 23:22 - Reserved */
+#define OTG_HS_GINTSTS_IPXFR (1 << 21)
+#define OTG_HS_GINTSTS_INCOMPISOOUT (1 << 21)
+#define OTG_HS_GINTSTS_IISOIXFR (1 << 20)
+#define OTG_HS_GINTSTS_OEPINT (1 << 19)
+#define OTG_HS_GINTSTS_IEPINT (1 << 18)
+/* Bits 17:16 - Reserved */
+#define OTG_HS_GINTSTS_EOPF (1 << 15)
+#define OTG_HS_GINTSTS_ISOODRP (1 << 14)
+#define OTG_HS_GINTSTS_ENUMDNE (1 << 13)
+#define OTG_HS_GINTSTS_USBRST (1 << 12)
+#define OTG_HS_GINTSTS_USBSUSP (1 << 11)
+#define OTG_HS_GINTSTS_ESUSP (1 << 10)
+/* Bits 9:8 - Reserved */
+#define OTG_HS_GINTSTS_GONAKEFF (1 << 7)
+#define OTG_HS_GINTSTS_GINAKEFF (1 << 6)
+#define OTG_HS_GINTSTS_NPTXFE (1 << 5)
+#define OTG_HS_GINTSTS_RXFLVL (1 << 4)
+#define OTG_HS_GINTSTS_SOF (1 << 3)
+#define OTG_HS_GINTSTS_OTGINT (1 << 2)
+#define OTG_HS_GINTSTS_MMIS (1 << 1)
+#define OTG_HS_GINTSTS_CMOD (1 << 0)
+
+/* OTG_FS interrupt mask register (OTG_HS_GINTMSK) */
+#define OTG_HS_GINTMSK_MMISM 0x00000002
+#define OTG_HS_GINTMSK_OTGINT 0x00000004
+#define OTG_HS_GINTMSK_SOFM 0x00000008
+#define OTG_HS_GINTMSK_RXFLVLM 0x00000010
+#define OTG_HS_GINTMSK_NPTXFEM 0x00000020
+#define OTG_HS_GINTMSK_GINAKEFFM 0x00000040
+#define OTG_HS_GINTMSK_GONAKEFFM 0x00000080
+#define OTG_HS_GINTMSK_ESUSPM 0x00000400
+#define OTG_HS_GINTMSK_USBSUSPM 0x00000800
+#define OTG_HS_GINTMSK_USBRST 0x00001000
+#define OTG_HS_GINTMSK_ENUMDNEM 0x00002000
+#define OTG_HS_GINTMSK_ISOODRPM 0x00004000
+#define OTG_HS_GINTMSK_EOPFM 0x00008000
+#define OTG_HS_GINTMSK_EPMISM 0x00020000
+#define OTG_HS_GINTMSK_IEPINT 0x00040000
+#define OTG_HS_GINTMSK_OEPINT 0x00080000
+#define OTG_HS_GINTMSK_IISOIXFRM 0x00100000
+#define OTG_HS_GINTMSK_IISOOXFRM 0x00200000
+#define OTG_HS_GINTMSK_IPXFRM 0x00200000
+#define OTG_HS_GINTMSK_PRTIM 0x01000000
+#define OTG_HS_GINTMSK_HCIM 0x02000000
+#define OTG_HS_GINTMSK_PTXFEM 0x04000000
+#define OTG_HS_GINTMSK_CIDSCHGM 0x10000000
+#define OTG_HS_GINTMSK_DISCINT 0x20000000
+#define OTG_HS_GINTMSK_SRQIM 0x40000000
+#define OTG_HS_GINTMSK_WUIM 0x80000000
+
+/* OTG_FS Receive Status Pop Register (OTG_HS_GRXSTSP) */
+/* Bits 31:25 - Reserved */
+#define OTG_HS_GRXSTSP_FRMNUM_MASK (0xf << 21)
+#define OTG_HS_GRXSTSP_PKTSTS_MASK (0xf << 17)
+#define OTG_HS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17)
+#define OTG_HS_GRXSTSP_PKTSTS_OUT (0x2 << 17)
+#define OTG_HS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17)
+#define OTG_HS_GRXSTSP_PKTSTS_SETUP_COMP (0x4 << 17)
+#define OTG_HS_GRXSTSP_PKTSTS_SETUP (0x6 << 17)
+#define OTG_HS_GRXSTSP_DPID_MASK (0x3 << 15)
+#define OTG_HS_GRXSTSP_DPID_DATA0 (0x0 << 15)
+#define OTG_HS_GRXSTSP_DPID_DATA1 (0x2 << 15)
+#define OTG_HS_GRXSTSP_DPID_DATA2 (0x1 << 15)
+#define OTG_HS_GRXSTSP_DPID_MDATA (0x3 << 15)
+#define OTG_HS_GRXSTSP_BCNT_MASK (0x7ff << 4)
+#define OTG_HS_GRXSTSP_EPNUM_MASK (0xf << 0)
+
+/* OTG_FS general core configuration register (OTG_HS_GCCFG) */
+/* Bits 31:21 - Reserved */
+#define OTG_HS_GCCFG_SOFOUTEN (1 << 20)
+#define OTG_HS_GCCFG_VBUSBSEN (1 << 19)
+#define OTG_HS_GCCFG_VBUSASEN (1 << 18)
+/* Bit 17 - Reserved */
+#define OTG_HS_GCCFG_PWRDWN (1 << 16)
+/* Bits 15:0 - Reserved */
+
+
+/* Device-mode CSRs */
+/* OTG_FS device control register (OTG_HS_DCTL) */
+/* Bits 31:12 - Reserved */
+#define OTG_HS_DCTL_POPRGDNE (1 << 11)
+#define OTG_HS_DCTL_CGONAK (1 << 10)
+#define OTG_HS_DCTL_SGONAK (1 << 9)
+#define OTG_HS_DCTL_SGINAK (1 << 8)
+#define OTG_HS_DCTL_TCTL_MASK (7 << 4)
+#define OTG_HS_DCTL_GONSTS (1 << 3)
+#define OTG_HS_DCTL_GINSTS (1 << 2)
+#define OTG_HS_DCTL_SDIS (1 << 1)
+#define OTG_HS_DCTL_RWUSIG (1 << 0)
+
+/* OTG_FS device configuration register (OTG_HS_DCFG) */
+#define OTG_HS_DCFG_DSPD 0x0003
+#define OTG_HS_DCFG_NZLSOHSK 0x0004
+#define OTG_HS_DCFG_DAD 0x07F0
+#define OTG_HS_DCFG_PFIVL 0x1800
+
+/* OTG_FS Device IN Endpoint Common Interrupt Mask Register (OTG_HS_DIEPMSK) */
+/* Bits 31:10 - Reserved */
+#define OTG_HS_DIEPMSK_BIM (1 << 9)
+#define OTG_HS_DIEPMSK_TXFURM (1 << 8)
+/* Bit 7 - Reserved */
+#define OTG_HS_DIEPMSK_INEPNEM (1 << 6)
+#define OTG_HS_DIEPMSK_INEPNMM (1 << 5)
+#define OTG_HS_DIEPMSK_ITTXFEMSK (1 << 4)
+#define OTG_HS_DIEPMSK_TOM (1 << 3)
+/* Bit 2 - Reserved */
+#define OTG_HS_DIEPMSK_EPDM (1 << 1)
+#define OTG_HS_DIEPMSK_XFRCM (1 << 0)
+
+/* OTG_FS Device OUT Endpoint Common Interrupt Mask Register (OTG_HS_DOEPMSK) */
+/* Bits 31:10 - Reserved */
+#define OTG_HS_DOEPMSK_BOIM (1 << 9)
+#define OTG_HS_DOEPMSK_OPEM (1 << 8)
+/* Bit 7 - Reserved */
+#define OTG_HS_DOEPMSK_B2BSTUP (1 << 6)
+/* Bit 5 - Reserved */
+#define OTG_HS_DOEPMSK_OTEPDM (1 << 4)
+#define OTG_HS_DOEPMSK_STUPM (1 << 3)
+/* Bit 2 - Reserved */
+#define OTG_HS_DOEPMSK_EPDM (1 << 1)
+#define OTG_HS_DOEPMSK_XFRCM (1 << 0)
+
+/* OTG_FS Device Control IN Endpoint 0 Control Register (OTG_HS_DIEPCTL0) */
+#define OTG_HS_DIEPCTL0_EPENA (1 << 31)
+#define OTG_HS_DIEPCTL0_EPDIS (1 << 30)
+/* Bits 29:28 - Reserved */
+#define OTG_HS_DIEPCTLX_SD0PID (1 << 28)
+#define OTG_HS_DIEPCTL0_SNAK (1 << 27)
+#define OTG_HS_DIEPCTL0_CNAK (1 << 26)
+#define OTG_HS_DIEPCTL0_TXFNUM_MASK (0xf << 22)
+#define OTG_HS_DIEPCTL0_STALL (1 << 21)
+/* Bit 20 - Reserved */
+#define OTG_HS_DIEPCTL0_EPTYP_MASK (0x3 << 18)
+#define OTG_HS_DIEPCTL0_NAKSTS (1 << 17)
+/* Bit 16 - Reserved */
+#define OTG_HS_DIEPCTL0_USBAEP (1 << 15)
+/* Bits 14:2 - Reserved */
+#define OTG_HS_DIEPCTL0_MPSIZ_MASK (0x3 << 0)
+#define OTG_HS_DIEPCTL0_MPSIZ_64 (0x0 << 0)
+#define OTG_HS_DIEPCTL0_MPSIZ_32 (0x1 << 0)
+#define OTG_HS_DIEPCTL0_MPSIZ_16 (0x2 << 0)
+#define OTG_HS_DIEPCTL0_MPSIZ_8 (0x3 << 0)
+
+/* OTG_FS Device Control OUT Endpoint 0 Control Register (OTG_HS_DOEPCTL0) */
+#define OTG_HS_DOEPCTL0_EPENA (1 << 31)
+#define OTG_HS_DOEPCTL0_EPDIS (1 << 30)
+/* Bits 29:28 - Reserved */
+#define OTG_HS_DOEPCTLX_SD0PID (1 << 28)
+#define OTG_HS_DOEPCTL0_SNAK (1 << 27)
+#define OTG_HS_DOEPCTL0_CNAK (1 << 26)
+/* Bits 25:22 - Reserved */
+#define OTG_HS_DOEPCTL0_STALL (1 << 21)
+#define OTG_HS_DOEPCTL0_SNPM (1 << 20)
+#define OTG_HS_DOEPCTL0_EPTYP_MASK (0x3 << 18)
+#define OTG_HS_DOEPCTL0_NAKSTS (1 << 17)
+/* Bit 16 - Reserved */
+#define OTG_HS_DOEPCTL0_USBAEP (1 << 15)
+/* Bits 14:2 - Reserved */
+#define OTG_HS_DOEPCTL0_MPSIZ_MASK (0x3 << 0)
+#define OTG_HS_DOEPCTL0_MPSIZ_64 (0x0 << 0)
+#define OTG_HS_DOEPCTL0_MPSIZ_32 (0x1 << 0)
+#define OTG_HS_DOEPCTL0_MPSIZ_16 (0x2 << 0)
+#define OTG_HS_DOEPCTL0_MPSIZ_8 (0x3 << 0)
+
+/* OTG_FS Device IN Endpoint Interrupt Register (OTG_HS_DIEPINTx) */
+/* Bits 31:8 - Reserved */
+#define OTG_HS_DIEPINTX_TXFE (1 << 7)
+#define OTG_HS_DIEPINTX_INEPNE (1 << 6)
+/* Bit 5 - Reserved */
+#define OTG_HS_DIEPINTX_ITTXFE (1 << 4)
+#define OTG_HS_DIEPINTX_TOC (1 << 3)
+/* Bit 2 - Reserved */
+#define OTG_HS_DIEPINTX_EPDISD (1 << 1)
+#define OTG_HS_DIEPINTX_XFRC (1 << 0)
+
+/* OTG_FS Device IN Endpoint Interrupt Register (OTG_HS_DOEPINTx) */
+/* Bits 31:7 - Reserved */
+#define OTG_HS_DOEPINTX_B2BSTUP (1 << 6)
+/* Bit 5 - Reserved */
+#define OTG_HS_DOEPINTX_OTEPDIS (1 << 4)
+#define OTG_HS_DOEPINTX_STUP (1 << 3)
+/* Bit 2 - Reserved */
+#define OTG_HS_DOEPINTX_EPDISD (1 << 1)
+#define OTG_HS_DOEPINTX_XFRC (1 << 0)
+
+/* OTG_FS Device OUT Endpoint 0 Transfer Size Regsiter (OTG_HS_DOEPTSIZ0) */
+/* Bit 31 - Reserved */
+#define OTG_HS_DIEPSIZ0_STUPCNT_1 (0x1 << 29)
+#define OTG_HS_DIEPSIZ0_STUPCNT_2 (0x2 << 29)
+#define OTG_HS_DIEPSIZ0_STUPCNT_3 (0x3 << 29)
+#define OTG_HS_DIEPSIZ0_STUPCNT_MASK (0x3 << 29)
+/* Bits 28:20 - Reserved */
+#define OTG_HS_DIEPSIZ0_PKTCNT (1 << 19)
+/* Bits 18:7 - Reserved */
+#define OTG_HS_DIEPSIZ0_XFRSIZ_MASK (0x7f << 0)
+
+#endif
diff --git a/include/libopencm3/stm32/f2/syscfg.h b/include/libopencm3/stm32/syscfg.h
index 7426f16..7426f16 100644
--- a/include/libopencm3/stm32/f2/syscfg.h
+++ b/include/libopencm3/stm32/syscfg.h
diff --git a/include/libopencm3/usb/cdc.h b/include/libopencm3/usb/cdc.h
index 4b54961..5036411 100644
--- a/include/libopencm3/usb/cdc.h
+++ b/include/libopencm3/usb/cdc.h
@@ -112,7 +112,7 @@ struct usb_cdc_line_coding {
/* Table 30: Class-Specific Notification Codes for PSTN subclasses */
/* ... */
-#define USB_CDC_NOTIFY_SERIAL_STATE 0x20
+#define USB_CDC_NOTIFY_SERIAL_STATE 0x20
/* ... */
/* Notification Structure */
diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h
index 8f68555..2e5b7fb 100644
--- a/include/libopencm3/usb/usbd.h
+++ b/include/libopencm3/usb/usbd.h
@@ -32,9 +32,13 @@ enum usbd_request_return_codes {
};
typedef struct _usbd_driver usbd_driver;
+typedef struct _usbd_device usbd_device;
+
extern const usbd_driver stm32f103_usb_driver;
extern const usbd_driver stm32f107_usb_driver;
+extern const usbd_driver stm32f207_usb_driver;
#define otgfs_usb_driver stm32f107_usb_driver
+#define otghs_usb_driver stm32f207_usb_driver
/* Static buffer for control transactions:
* This is defined as weak in the library, applicaiton
@@ -42,45 +46,56 @@ extern const usbd_driver stm32f107_usb_driver;
extern u8 usbd_control_buffer[];
/* <usb.c> */
-extern int usbd_init(const usbd_driver *driver,
- const struct usb_device_descriptor *dev,
- const struct usb_config_descriptor *conf,
- const char **strings, int num_strings);
-extern void usbd_set_control_buffer_size(u16 size);
-
-extern void usbd_register_reset_callback(void (*callback)(void));
-extern void usbd_register_suspend_callback(void (*callback)(void));
-extern void usbd_register_resume_callback(void (*callback)(void));
-extern void usbd_register_sof_callback(void (*callback)(void));
-
-typedef int (*usbd_control_callback)(struct usb_setup_data *req, u8 **buf,
- u16 *len, void (**complete)(struct usb_setup_data *req));
+extern usbd_device *usbd_init(const usbd_driver *driver,
+ const struct usb_device_descriptor *dev,
+ const struct usb_config_descriptor *conf,
+ const char **strings, int num_strings);
+
+extern void usbd_set_control_buffer_size(usbd_device *usbd_dev, u16 size);
+
+extern void usbd_register_reset_callback(usbd_device *usbd_dev,
+ void (*callback)(void));
+extern void usbd_register_suspend_callback(usbd_device *usbd_dev,
+ void (*callback)(void));
+extern void usbd_register_resume_callback(usbd_device *usbd_dev,
+ void (*callback)(void));
+extern void usbd_register_sof_callback(usbd_device *usbd_dev,
+ void (*callback)(void));
+
+typedef int (*usbd_control_callback)(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf, u16 *len,
+ void (**complete)(usbd_device *usbd_dev,
+ struct usb_setup_data *req));
/* <usb_control.c> */
-extern int usbd_register_control_callback(u8 type, u8 type_mask,
- usbd_control_callback callback);
+extern int usbd_register_control_callback(usbd_device *usbd_dev, u8 type,
+ u8 type_mask,
+ usbd_control_callback callback);
/* <usb_standard.c> */
-extern void usbd_register_set_config_callback(void (*callback)(u16 wValue));
+extern void usbd_register_set_config_callback(usbd_device *usbd_dev,
+ void (*callback)(usbd_device *usbd_dev, u16 wValue));
/* Functions to be provided by the hardware abstraction layer */
-extern void usbd_poll(void);
-extern void usbd_disconnect(bool disconnected);
+extern void usbd_poll(usbd_device *usbd_dev);
+extern void usbd_disconnect(usbd_device *usbd_dev, bool disconnected);
-extern void usbd_ep_setup(u8 addr, u8 type, u16 max_size,
- void (*callback)(u8 ep));
+extern void usbd_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size,
+ void (*callback)(usbd_device *usbd_dev, u8 ep));
-extern u16 usbd_ep_write_packet(u8 addr, const void *buf, u16 len);
+extern u16 usbd_ep_write_packet(usbd_device *usbd_dev, u8 addr,
+ const void *buf, u16 len);
-extern u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len);
+extern u16 usbd_ep_read_packet(usbd_device *usbd_dev, u8 addr,
+ void *buf, u16 len);
-extern void usbd_ep_stall_set(u8 addr, u8 stall);
-extern u8 usbd_ep_stall_get(u8 addr);
+extern void usbd_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall);
+extern u8 usbd_ep_stall_get(usbd_device *usbd_dev, u8 addr);
-extern void usbd_ep_nak_set(u8 addr, u8 nak);
+extern void usbd_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak);
/* Optional */
-extern void usbd_cable_connect(u8 on);
+extern void usbd_cable_connect(usbd_device *usbd_dev, u8 on);
END_DECLS
diff --git a/include/libopencm3/usb/usbstd.h b/include/libopencm3/usb/usbstd.h
index 01fc7e3..7908280 100644
--- a/include/libopencm3/usb/usbstd.h
+++ b/include/libopencm3/usb/usbstd.h
@@ -38,6 +38,9 @@ struct usb_setup_data {
u16 wLength;
} __attribute__((packed));
+/* Class Definition */
+#define USB_CLASS_VENDOR 0xFF
+
/* bmRequestType bit definitions */
#define USB_REQ_TYPE_IN 0x80
#define USB_REQ_TYPE_STANDARD 0x00
diff --git a/include/libopencmsis/core_cm3.h b/include/libopencmsis/core_cm3.h
new file mode 100644
index 0000000..0a89381
--- /dev/null
+++ b/include/libopencmsis/core_cm3.h
@@ -0,0 +1,177 @@
+/* big fat FIXME: this should use a consistent structure, and reference
+ * functionality from libopencm3 instead of copypasting.
+ *
+ * particularly unimplemented features are FIXME'd extra
+ * */
+
+/* the original core_cm3.h is nonfree by arm; this provides libopencm3 variant of the symbols efm32lib needs of CMSIS. */
+
+#ifndef OPENCMSIS_CORECM3_H
+#define OPENCMSIS_CORECM3_H
+
+#include <libopencm3/cm3/common.h>
+#include <libopencm3/cm3/memorymap.h>
+#include <libopencm3/cm3/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/scb.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 cm3/scb.h */
+#define SCB_SCR_SLEEPDEEP_Msk SCB_SCR_SLEEPDEEP
+
+/* structure as in, for example,
+ * DeviceSupport/EnergyMicro/EFM32/efm32tg840f32.h, data from
+ * libopencm3/cm3/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)
+
+/* 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 */
+
+static inline void NVIC_ClearPendingIRQ(uint8_t irqn)
+{
+ nvic_clear_pending_irq(irqn);
+}
+static inline void NVIC_EnableIRQ(uint8_t irqn)
+{
+ nvic_enable_irq(irqn);
+}
+static inline void NVIC_DisableIRQ(uint8_t irqn)
+{
+ nvic_disable_irq(irqn);
+}
+
+/* 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.
+ * */
+
+/* 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)
+
+static inline uint32_t SysTick_Config(uint32_t n_ticks)
+{
+ /* constant from systick_set_reload -- as this returns something that's
+ * not void, this is the only possible error condition */
+ if (n_ticks & ~0x00FFFFFF) return 1;
+
+ systick_set_reload(n_ticks);
+ systick_set_clocksource(true);
+ systick_interrupt_enable();
+ systick_counter_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
+/* FIXME: this needs to be done for all of the 14 hard vectors */
+
+#include <libopencmsis/dispatch/irqhandlers.h>
+
+#endif
diff --git a/include/libopencmsis/dispatch/irqhandlers.h b/include/libopencmsis/dispatch/irqhandlers.h
new file mode 100644
index 0000000..65e071d
--- /dev/null
+++ b/include/libopencmsis/dispatch/irqhandlers.h
@@ -0,0 +1,23 @@
+#if defined(STM32F1)
+# include <libopencmsis/stm32/f1/irqhandlers.h>
+#elif defined(STM32F2)
+# include <libopencmsis/stm32/f2/irqhandlers.h>
+#elif defined(STM32F4)
+# include <libopencmsis/stm32/f4/irqhandlers.h>
+
+#elif defined(EFM32TG)
+# include <libopencmsis/efm32/efm32tg/irqhandlers.h>
+#elif defined(EFM32G)
+# include <libopencmsis/efm32/efm32g/irqhandlers.h>
+#elif defined(EFM32LG)
+# include <libopencmsis/efm32/efm32lg/irqhandlers.h>
+#elif defined(EFM32GG)
+# include <libopencmsis/efm32/efm32gg/irqhandlers.h>
+
+#elif defined(LPC43XX)
+# include <libopencmsis/lpc43xx/irqhandlers.h>
+
+#else
+# warning"no chipset defined; user interrupts are not redirected"
+
+#endif
diff --git a/lib/Makefile.include b/lib/Makefile.include
index 9fbea24..6c25069 100644
--- a/lib/Makefile.include
+++ b/lib/Makefile.include
@@ -23,6 +23,9 @@ ifneq ($(V),1)
Q := @
endif
+# common objects
+OBJS += vector.o systick.o scb.o nvic.o assert.o
+
all: $(SRCLIBDIR)/$(LIBNAME).a
$(SRCLIBDIR)/$(LIBNAME).a: $(SRCLIBDIR)/$(LIBNAME).ld $(OBJS)
diff --git a/lib/stm32/nvic.c b/lib/cm3/nvic.c
index 84fa674..db187b3 100644
--- a/lib/stm32/nvic.c
+++ b/lib/cm3/nvic.c
@@ -1,31 +1,9 @@
-/** @defgroup STM32F_nvic_file NVIC
-
-@ingroup STM32F_files
-
-@brief <b>libopencm3 STM32F Nested Vectored Interrupt Controller</b>
-
-@version 1.0.0
-
-@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
-@author @htmlonly &copy; @endhtmlonly 2012 Fergus Noble <fergusnoble@gmail.com>
-
-@date 18 August 2012
-
-The STM32F series provides up to 68 maskable user interrupts for the STM32F10x
-series, and 87 for the STM32F2xx and STM32F4xx series.
-
-The NVIC registers are defined by the ARM standards but the STM32F series have some
-additional limitations
-@see Cortex-M3 Devices Generic User Guide
-@see STM32F10xxx Cortex-M3 programming manual
-
-LGPL License Terms @ref lgpl_license
-*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
*
* 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
@@ -40,10 +18,32 @@ LGPL License Terms @ref lgpl_license
* 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/>.
*/
+/** @defgroup CM3_nvic_file NVIC
+@ingroup CM3_files
+
+@brief <b>libopencm3 Cortex Nested Vectored Interrupt Controller</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
+@author @htmlonly &copy; @endhtmlonly 2012 Fergus Noble <fergusnoble@gmail.com>
+
+@date 18 August 2012
+
+Cortex processors provide 14 cortex-defined interrupts (NMI, usage faults,
+systicks etc.) and varying numbers of implementation defined interrupts
+(typically peripherial interrupts and DMA).
+
+@see Cortex-M3 Devices Generic User Guide
+@see STM32F10xxx Cortex-M3 programming manual
+
+LGPL License Terms @ref lgpl_license
+*/
/**@{*/
-#include <libopencm3/stm32/nvic.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/scs.h>
/*-----------------------------------------------------------------------------*/
/** @brief NVIC Enable Interrupt
@@ -153,7 +153,18 @@ Control Register (SCB_AIRCR), as done in @ref scb_set_priority_grouping.
void nvic_set_priority(u8 irqn, u8 priority)
{
- NVIC_IPR(irqn) = priority;
+ /* code from lpc43xx/nvic.c -- this is quite a hack and alludes to the
+ * negative interrupt numbers assigned to the system interrupts. better
+ * handling would mean signed integers. */
+ if(irqn>=NVIC_IRQ_COUNT)
+ {
+ /* Cortex-M system interrupts */
+ SCS_SHPR( (irqn&0xF)-4 ) = priority;
+ }else
+ {
+ /* Device specific interrupts */
+ NVIC_IPR(irqn) = priority;
+ }
}
/*-----------------------------------------------------------------------------*/
@@ -171,4 +182,3 @@ void nvic_generate_software_interrupt(u16 irqn)
NVIC_STIR |= irqn;
}
/**@}*/
-
diff --git a/lib/stm32/f4/scb.c b/lib/cm3/scb.c
index cbf4d53..904bd7c 100644
--- a/lib/stm32/f4/scb.c
+++ b/lib/cm3/scb.c
@@ -17,7 +17,7 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libopencm3/stm32/f4/scb.h>
+#include <libopencm3/cm3/scb.h>
void scb_reset_core(void)
{
diff --git a/lib/stm32/systick.c b/lib/cm3/systick.c
index 36077cc..325ffff 100644
--- a/lib/stm32/systick.c
+++ b/lib/cm3/systick.c
@@ -1,27 +1,8 @@
-/** @defgroup STM32F_systick_file SysTick
-
-@ingroup STM32F_files
-
-@brief <b>libopencm3 STM32Fxx System Tick Timer</b>
-
-@version 1.0.0
-
-@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
-
-@date 19 August 2012
-
-This library supports the System Tick timer in the
-STM32F series of ARM Cortex Microcontrollers by ST Microelectronics.
-
-The System Tick timer is part of the ARM Cortex core. It is a 24 bit
-down counter that can be configured with an automatical reload value.
-
-LGPL License Terms @ref lgpl_license
- */
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
+ * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
*
* 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
@@ -36,9 +17,28 @@ LGPL License Terms @ref lgpl_license
* 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/>.
*/
+/** @defgroup CM3_systick_file SysTick
+
+@ingroup CM3_files
+
+@brief <b>libopencm3 Cortex System Tick Timer</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
+
+@date 19 August 2012
+
+This library supports the System Tick timer in ARM Cortex Microcontrollers.
+
+The System Tick timer is part of the ARM Cortex core. It is a 24 bit
+down counter that can be configured with an automatical reload value.
+
+LGPL License Terms @ref lgpl_license
+ */
/**@{*/
-#include <libopencm3/stm32/systick.h>
+#include <libopencm3/cm3/systick.h>
/*-----------------------------------------------------------------------------*/
/** @brief SysTick Set the Automatic Reload Value.
@@ -135,5 +135,15 @@ u8 systick_get_countflag(void)
else
return 0;
}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief SysTick Get Calibration Value
+
+@returns Current calibration value
+*/
+u32 systick_get_calib(void)
+{
+ return (STK_CALIB&0x00FFFFFF);
+}
/**@}*/
diff --git a/lib/lpc17xx/vector.c b/lib/cm3/vector.c
index 518f562..b049526 100644
--- a/lib/lpc17xx/vector.c
+++ b/lib/cm3/vector.c
@@ -1,7 +1,8 @@
/*
* This file is part of the libopencm3 project.
*
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
+ * 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
@@ -14,19 +15,26 @@
* 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/>.
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <libopencm3/cm3/vector.h>
+
+/* load optional platform dependent initialization routines */
+#include "../dispatch/vector_chipset.c"
+/* load the weak symbols for IRQ_HANDLERS */
+#include "../dispatch/vector_nvic.c"
+
#define WEAK __attribute__ ((weak))
/* Symbols exported by the linker script(s): */
extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack;
void main(void);
-void reset_handler(void);
void blocking_handler(void);
void null_handler(void);
+void WEAK reset_handler(void);
void WEAK nmi_handler(void);
void WEAK hard_fault_handler(void);
void WEAK mem_manage_handler(void);
@@ -37,27 +45,25 @@ void WEAK debug_monitor_handler(void);
void WEAK pend_sv_handler(void);
void WEAK sys_tick_handler(void);
-/* TODO: Interrupt handler prototypes */
-
__attribute__ ((section(".vectors")))
-void (*const vector_table[]) (void) = {
- (void*)&_stack, /* Addr: 0x0000_0000 */
- reset_handler, /* Addr: 0x0000_0004 */
- nmi_handler, /* Addr: 0x0000_0008 */
- hard_fault_handler, /* Addr: 0x0000_000C */
- mem_manage_handler, /* Addr: 0x0000_0010 */
- bus_fault_handler, /* Addr: 0x0000_0014 */
- usage_fault_handler, /* Addr: 0x0000_0018 */
- 0, 0, 0, 0, /* Reserved Addr: 0x0000_001C - 0x0000_002B */
- sv_call_handler, /* Addr: 0x0000_002C */
- debug_monitor_handler, /* Addr: 0x0000_0030 */
- 0, /* Reserved Addr: 0x0000_00034 */
- pend_sv_handler, /* Addr: 0x0000_0038 */
- sys_tick_handler, /* Addr: 0x0000_003C */
+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,
+ .debug_monitor = debug_monitor_handler,
+ .sv_call = sv_call_handler,
+ .pend_sv = pend_sv_handler,
+ .systick = sys_tick_handler,
+ .irq = {
+ IRQ_HANDLERS
+ }
};
-
-void reset_handler(void)
+void WEAK reset_handler(void)
{
volatile unsigned *src, *dest;
@@ -69,6 +75,9 @@ void reset_handler(void)
while (dest < &_ebss)
*dest++ = 0;
+ /* might be provided by platform specific vector.c */
+ pre_main();
+
/* Call the application's entry point. */
main();
}
@@ -92,4 +101,3 @@ void null_handler(void)
#pragma weak debug_monitor_handler = null_handler
#pragma weak pend_sv_handler = null_handler
#pragma weak sys_tick_handler = null_handler
-/* TODO: Interrupt handler weak aliases */
diff --git a/lib/dispatch/vector_chipset.c b/lib/dispatch/vector_chipset.c
new file mode 100644
index 0000000..796276c
--- /dev/null
+++ b/lib/dispatch/vector_chipset.c
@@ -0,0 +1,11 @@
+#if defined(STM32F4)
+# include "../stm32/f4/vector_chipset.c"
+
+#elif defined(LPC43XX)
+# include "../lpc43xx/vector_chipset.c"
+
+#else
+
+static void pre_main(void) {}
+
+#endif
diff --git a/lib/dispatch/vector_nvic.c b/lib/dispatch/vector_nvic.c
new file mode 100644
index 0000000..33104eb
--- /dev/null
+++ b/lib/dispatch/vector_nvic.c
@@ -0,0 +1,34 @@
+#if defined(STM32F1)
+# include "../stm32/f1/vector_nvic.c"
+#elif defined(STM32F2)
+# include "../stm32/f2/vector_nvic.c"
+#elif defined(STM32F4)
+# include "../stm32/f4/vector_nvic.c"
+#elif defined(STM32L1)
+# include "../stm32/l1/vector_nvic.c"
+
+#elif defined(EFM32TG)
+# include "../efm32/efm32tg/vector_nvic.c"
+#elif defined(EFM32G)
+# include "../efm32/efm32g/vector_nvic.c"
+#elif defined(EFM32LG)
+# include "../efm32/efm32lg/vector_nvic.c"
+#elif defined(EFM32GG)
+# include "../efm32/efm32gg/vector_nvic.c"
+
+#elif defined(LPC13XX)
+# include "../lpc13xx/vector_nvic.c"
+#elif defined(LPC17XX)
+# include "../lpc17xx/vector_nvic.c"
+#elif defined(LPC43XX)
+# include "../lpc43xx/vector_nvic.c"
+
+#elif defined(LM3S)
+# include "../lm3s/vector_nvic.c"
+
+#else
+# warning"no interrupts defined for chipset; not allocating space in the vector table"
+
+#define IRQ_HANDLERS
+
+#endif
diff --git a/lib/efm32/efm32g/Makefile b/lib/efm32/efm32g/Makefile
new file mode 100644
index 0000000..1dd4485
--- /dev/null
+++ b/lib/efm32/efm32g/Makefile
@@ -0,0 +1,38 @@
+##
+## 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_efm32g
+FAMILY = EFM32G
+
+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 =
+
+VPATH += ../:../../cm3
+
+include ../../Makefile.include
+
diff --git a/lib/efm32/efm32g/libopencm3_efm32g.ld b/lib/efm32/efm32g/libopencm3_efm32g.ld
new file mode 100644
index 0000000..8ef5e42
--- /dev/null
+++ b/lib/efm32/efm32g/libopencm3_efm32g.ld
@@ -0,0 +1,79 @@
+/*
+ * 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
+ _data_loadaddr = LOADADDR(.data);
+
+ /*
+ * 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/efm32g/libopencm3_efm32g880f128.ld b/lib/efm32/efm32g/libopencm3_efm32g880f128.ld
new file mode 100644
index 0000000..09c6fb0
--- /dev/null
+++ b/lib/efm32/efm32g/libopencm3_efm32g880f128.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 = 128k
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16k
+}
+
+INCLUDE libopencm3_efm32g.ld;
diff --git a/lib/efm32/efm32gg/Makefile b/lib/efm32/efm32gg/Makefile
new file mode 100644
index 0000000..2407859
--- /dev/null
+++ b/lib/efm32/efm32gg/Makefile
@@ -0,0 +1,38 @@
+##
+## 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_efm32gg
+FAMILY = EFM32GG
+
+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 =
+
+VPATH += ../:../../cm3
+
+include ../../Makefile.include
+
diff --git a/lib/efm32/efm32gg/libopencm3_efm32gg.ld b/lib/efm32/efm32gg/libopencm3_efm32gg.ld
new file mode 100644
index 0000000..8ef5e42
--- /dev/null
+++ b/lib/efm32/efm32gg/libopencm3_efm32gg.ld
@@ -0,0 +1,79 @@
+/*
+ * 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
+ _data_loadaddr = LOADADDR(.data);
+
+ /*
+ * 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/efm32lg/Makefile b/lib/efm32/efm32lg/Makefile
new file mode 100644
index 0000000..9b6343c
--- /dev/null
+++ b/lib/efm32/efm32lg/Makefile
@@ -0,0 +1,38 @@
+##
+## 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_efm32lg
+FAMILY = EFM32LG
+
+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 =
+
+VPATH += ../:../../cm3
+
+include ../../Makefile.include
+
diff --git a/lib/efm32/efm32lg/libopencm3_efm32lg.ld b/lib/efm32/efm32lg/libopencm3_efm32lg.ld
new file mode 100644
index 0000000..8ef5e42
--- /dev/null
+++ b/lib/efm32/efm32lg/libopencm3_efm32lg.ld
@@ -0,0 +1,79 @@
+/*
+ * 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
+ _data_loadaddr = LOADADDR(.data);
+
+ /*
+ * 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/efm32tg/Makefile b/lib/efm32/efm32tg/Makefile
new file mode 100644
index 0000000..605438a
--- /dev/null
+++ b/lib/efm32/efm32tg/Makefile
@@ -0,0 +1,38 @@
+##
+## 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_efm32tg
+FAMILY = EFM32TG
+
+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 =
+
+VPATH += ../:../../cm3
+
+include ../../Makefile.include
+
diff --git a/lib/efm32/efm32tg/libopencm3_efm32tg.ld b/lib/efm32/efm32tg/libopencm3_efm32tg.ld
new file mode 100644
index 0000000..8ef5e42
--- /dev/null
+++ b/lib/efm32/efm32tg/libopencm3_efm32tg.ld
@@ -0,0 +1,79 @@
+/*
+ * 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
+ _data_loadaddr = LOADADDR(.data);
+
+ /*
+ * 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/efm32tg/libopencm3_efm32tg840f32.ld b/lib/efm32/efm32tg/libopencm3_efm32tg840f32.ld
new file mode 100644
index 0000000..2cb8daf
--- /dev/null
+++ b/lib/efm32/efm32tg/libopencm3_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 libopencm3_efm32tg.ld;
diff --git a/lib/lm3s/Makefile b/lib/lm3s/Makefile
index e471a00..6fc814d 100644
--- a/lib/lm3s/Makefile
+++ b/lib/lm3s/Makefile
@@ -25,7 +25,7 @@ CC = $(PREFIX)-gcc
AR = $(PREFIX)-ar
CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \
-mcpu=cortex-m3 -mthumb -Wstrict-prototypes \
- -ffunction-sections -fdata-sections -MD
+ -ffunction-sections -fdata-sections -MD -DLM3S
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = gpio.o vector.o assert.o
diff --git a/lib/lm3s/vector.c b/lib/lm3s/vector.c
deleted file mode 100644
index b7c92ae..0000000
--- a/lib/lm3s/vector.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
- *
- * 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/>.
- */
-
-#define WEAK __attribute__ ((weak))
-
-/* Symbols exported by the linker script(s): */
-extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack;
-
-void main(void);
-void reset_handler(void);
-void blocking_handler(void);
-void null_handler(void);
-
-void WEAK nmi_handler(void);
-void WEAK hard_fault_handler(void);
-void WEAK mem_manage_handler(void);
-void WEAK bus_fault_handler(void);
-void WEAK usage_fault_handler(void);
-void WEAK sv_call_handler(void);
-void WEAK debug_monitor_handler(void);
-void WEAK pend_sv_handler(void);
-void WEAK sys_tick_handler(void);
-
-void WEAK gpioa_handler(void);
-void WEAK gpiob_handler(void);
-void WEAK gpioc_handler(void);
-void WEAK gpiod_handler(void);
-void WEAK gpioe_handler(void);
-void WEAK uart0_handler(void);
-void WEAK uart1_handler(void);
-void WEAK ssi0_handler(void);
-void WEAK i2c0_handler(void);
-void WEAK pwm0_fault_handler(void);
-void WEAK pwm0_0_handler(void);
-void WEAK pwm0_1_handler(void);
-void WEAK pwm0_2_handler(void);
-void WEAK qei0_handler(void);
-void WEAK adc0ss0_handler(void);
-void WEAK adc0ss1_handler(void);
-void WEAK adc0ss2_handler(void);
-void WEAK adc0ss3_handler(void);
-void WEAK watchdog_handler(void);
-void WEAK timer0a_handler(void);
-void WEAK timer0b_handler(void);
-void WEAK timer1a_handler(void);
-void WEAK timer1b_handler(void);
-void WEAK timer2a_handler(void);
-void WEAK timer2b_handler(void);
-void WEAK comp0_handler(void);
-void WEAK comp1_handler(void);
-void WEAK comp2_handler(void);
-void WEAK sysctl_handler(void);
-void WEAK flash_handler(void);
-void WEAK gpiof_handler(void);
-void WEAK gpiog_handler(void);
-void WEAK gpioh_handler(void);
-void WEAK uart2_handler(void);
-void WEAK ssi1_handler(void);
-void WEAK timer3a_handler(void);
-void WEAK timer3b_handler(void);
-void WEAK i2c1_handler(void);
-void WEAK qei1_handler(void);
-void WEAK can0_handler(void);
-void WEAK can1_handler(void);
-void WEAK can2_handler(void);
-void WEAK eth_handler(void);
-void WEAK hibernate_handler(void);
-void WEAK usb0_handler(void);
-void WEAK pwm0_3_handler(void);
-void WEAK udma_handler(void);
-void WEAK udmaerr_handler(void);
-void WEAK adc1ss0_handler(void);
-void WEAK adc1ss1_handler(void);
-void WEAK adc1ss2_handler(void);
-void WEAK adc1ss3_handler(void);
-void WEAK i2s0_handler(void);
-void WEAK epi0_handler(void);
-void WEAK gpioj_handler(void);
-void WEAK gpiok_handler(void);
-void WEAK gpiol_handler(void);
-void WEAK ssi2_handler(void);
-void WEAK ssi3_handler(void);
-void WEAK uart3_handler(void);
-void WEAK uart4_handler(void);
-void WEAK uart5_handler(void);
-void WEAK uart6_handler(void);
-void WEAK uart7_handler(void);
-void WEAK i2c2_handler(void);
-void WEAK i2c3_handler(void);
-void WEAK timer4a_handler(void);
-void WEAK timer4b_handler(void);
-void WEAK timer5a_handler(void);
-void WEAK timer5b_handler(void);
-void WEAK wtimer0a_handler(void);
-void WEAK wtimer0b_handler(void);
-void WEAK wtimer1a_handler(void);
-void WEAK wtimer1b_handler(void);
-void WEAK wtimer2a_handler(void);
-void WEAK wtimer2b_handler(void);
-void WEAK wtimer3a_handler(void);
-void WEAK wtimer3b_handler(void);
-void WEAK wtimer4a_handler(void);
-void WEAK wtimer4b_handler(void);
-void WEAK wtimer5a_handler(void);
-void WEAK wtimer5b_handler(void);
-void WEAK sysexc_handler(void);
-void WEAK peci0_handler(void);
-void WEAK lpc0_handler(void);
-void WEAK i2c4_handler(void);
-void WEAK i2c5_handler(void);
-void WEAK gpiom_handler(void);
-void WEAK gpion_handler(void);
-void WEAK fan0_handler(void);
-void WEAK gpiop0_handler(void);
-void WEAK gpiop1_handler(void);
-void WEAK gpiop2_handler(void);
-void WEAK gpiop3_handler(void);
-void WEAK gpiop4_handler(void);
-void WEAK gpiop5_handler(void);
-void WEAK gpiop6_handler(void);
-void WEAK gpiop7_handler(void);
-void WEAK gpioq0_handler(void);
-void WEAK gpioq1_handler(void);
-void WEAK gpioq2_handler(void);
-void WEAK gpioq3_handler(void);
-void WEAK gpioq4_handler(void);
-void WEAK gpioq5_handler(void);
-void WEAK gpioq6_handler(void);
-void WEAK gpioq7_handler(void);
-void WEAK pwm1_0_handler(void);
-void WEAK pwm1_1_handler(void);
-void WEAK pwm1_2_handler(void);
-void WEAK pwm1_3_handler(void);
-void WEAK pwm1_fault_handler(void);
-
-__attribute__ ((section(".vectors")))
-void (*const vector_table[]) (void) = {
- (void *)&_stack,
- reset_handler,
- nmi_handler,
- hard_fault_handler,
- mem_manage_handler,
- bus_fault_handler,
- usage_fault_handler,
- 0, 0, 0, 0, /* Reserved */
- sv_call_handler,
- debug_monitor_handler,
- 0, /* Reserved */
- pend_sv_handler,
- sys_tick_handler,
-
- gpioa_handler, /* 16 */
- gpiob_handler, /* 17 */
- gpioc_handler, /* 18 */
- gpiod_handler, /* 19 */
- gpioe_handler, /* 20 */
- uart0_handler, /* 21 */
- uart1_handler, /* 22 */
- ssi0_handler, /* 23 */
- i2c0_handler, /* 24 */
- pwm0_fault_handler, /* 25 */
- pwm0_0_handler, /* 26 */
- pwm0_1_handler, /* 27 */
- pwm0_2_handler, /* 28 */
- qei0_handler, /* 29 */
- adc0ss0_handler, /* 30 */
- adc0ss1_handler, /* 31 */
- adc0ss2_handler, /* 32 */
- adc0ss3_handler, /* 33 */
- watchdog_handler, /* 34 */
- timer0a_handler, /* 35 */
- timer0b_handler, /* 36 */
- timer1a_handler, /* 37 */
- timer1b_handler, /* 38 */
- timer2a_handler, /* 39 */
- timer2b_handler, /* 40 */
- comp0_handler, /* 41 */
- comp1_handler, /* 42 */
- comp2_handler, /* 43 */
- sysctl_handler, /* 44 */
- flash_handler, /* 45 */
- gpiof_handler, /* 46 */
- gpiog_handler, /* 47 */
- gpioh_handler, /* 48 */
- uart2_handler, /* 49 */
- ssi1_handler, /* 50 */
- timer3a_handler, /* 51 */
- timer3b_handler, /* 52 */
- i2c1_handler, /* 53 */
- qei1_handler, /* 54 */
- can0_handler, /* 55 */
- can1_handler, /* 56 */
- can2_handler, /* 57 */
- eth_handler, /* 58 */
- hibernate_handler, /* 59 */
- usb0_handler, /* 60 */
- pwm0_3_handler, /* 61 */
- udma_handler, /* 62 */
- udmaerr_handler, /* 63 */
- adc1ss0_handler, /* 64 */
- adc1ss1_handler, /* 65 */
- adc1ss2_handler, /* 66 */
- adc1ss3_handler, /* 67 */
- i2s0_handler, /* 68 */
- epi0_handler, /* 69 */
- gpioj_handler, /* 70 */
- gpiok_handler, /* 71 */
- gpiol_handler, /* 72 */
- ssi2_handler, /* 73 */
- ssi3_handler, /* 74 */
- uart3_handler, /* 75 */
- uart4_handler, /* 76 */
- uart5_handler, /* 77 */
- uart6_handler, /* 78 */
- uart7_handler, /* 79 */
- 0, /* 80 */
- 0, /* 81 */
- 0, /* 82 */
- 0, /* 83 */
- i2c2_handler, /* 84 */
- i2c3_handler, /* 85 */
- timer4a_handler, /* 86 */
- timer4b_handler, /* 87 */
- 0, /* 88 */
- 0, /* 89 */
- 0, /* 90 */
- 0, /* 91 */
- 0, /* 92 */
- 0, /* 93 */
- 0, /* 94 */
- 0, /* 95 */
- 0, /* 96 */
- 0, /* 97 */
- 0, /* 98 */
- 0, /* 99 */
- 0, /* 100 */
- 0, /* 101 */
- 0, /* 102 */
- 0, /* 103 */
- 0, /* 104 */
- 0, /* 105 */
- 0, /* 106 */
- 0, /* 107 */
- timer5a_handler, /* 108 */
- timer5b_handler, /* 109 */
- wtimer0a_handler, /* 110 */
- wtimer0b_handler, /* 111 */
- wtimer1a_handler, /* 112 */
- wtimer1b_handler, /* 113 */
- wtimer2a_handler, /* 114 */
- wtimer2b_handler, /* 115 */
- wtimer3a_handler, /* 116 */
- wtimer3b_handler, /* 117 */
- wtimer4a_handler, /* 118 */
- wtimer4b_handler, /* 119 */
- wtimer5a_handler, /* 120 */
- wtimer5b_handler, /* 121 */
- sysexc_handler, /* 122 */
- peci0_handler, /* 123 */
- lpc0_handler, /* 124 */
- i2c4_handler, /* 125 */
- i2c5_handler, /* 126 */
- gpiom_handler, /* 127 */
- gpion_handler, /* 128 */
- 0, /* 129 */
- fan0_handler, /* 130 */
- 0, /* 131 */
- gpiop0_handler, /* 132 */
- gpiop1_handler, /* 133 */
- gpiop2_handler, /* 134 */
- gpiop3_handler, /* 135 */
- gpiop4_handler, /* 136 */
- gpiop5_handler, /* 137 */
- gpiop6_handler, /* 138 */
- gpiop7_handler, /* 139 */
- gpioq0_handler, /* 140 */
- gpioq1_handler, /* 141 */
- gpioq2_handler, /* 142 */
- gpioq3_handler, /* 143 */
- gpioq4_handler, /* 144 */
- gpioq5_handler, /* 145 */
- gpioq6_handler, /* 146 */
- gpioq7_handler, /* 147 */
- 0, /* 148 */
- 0, /* 149 */
- pwm1_0_handler, /* 150 */
- pwm1_1_handler, /* 151 */
- pwm1_2_handler, /* 152 */
- pwm1_3_handler, /* 153 */
- pwm1_fault_handler, /* 154 */
-};
-
-void reset_handler(void)
-{
- volatile unsigned *src, *dest;
-
- __asm__("MSR msp, %0" : : "r"(&_stack));
-
- for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++)
- *dest = *src;
-
- while (dest < &_ebss)
- *dest++ = 0;
-
- /* Call the application's entry point. */
- main();
-}
-
-void blocking_handler(void)
-{
- while (1) ;
-}
-
-void null_handler(void)
-{
- /* Do nothing. */
-}
-
-#pragma weak nmi_handler = null_handler
-#pragma weak hard_fault_handler = blocking_handler
-#pragma weak mem_manage_handler = blocking_handler
-#pragma weak bus_fault_handler = blocking_handler
-#pragma weak usage_fault_handler = blocking_handler
-#pragma weak sv_call_handler = null_handler
-#pragma weak debug_monitor_handler = null_handler
-#pragma weak pend_sv_handler = null_handler
-#pragma weak sys_tick_handler = null_handler
-#pragma weak gpioa_handler = null_handler
-#pragma weak gpiob_handler = null_handler
-#pragma weak gpioc_handler = null_handler
-#pragma weak gpiod_handler = null_handler
-#pragma weak gpioe_handler = null_handler
-#pragma weak uart0_handler = null_handler
-#pragma weak uart1_handler = null_handler
-#pragma weak ssi0_handler = null_handler
-#pragma weak i2c0_handler = null_handler
-#pragma weak pwm0_fault_handler = null_handler
-#pragma weak pwm0_0_handler = null_handler
-#pragma weak pwm0_1_handler = null_handler
-#pragma weak pwm0_2_handler = null_handler
-#pragma weak qei0_handler = null_handler
-#pragma weak adc0ss0_handler = null_handler
-#pragma weak adc0ss1_handler = null_handler
-#pragma weak adc0ss2_handler = null_handler
-#pragma weak adc0ss3_handler = null_handler
-#pragma weak watchdog_handler = null_handler
-#pragma weak timer0a_handler = null_handler
-#pragma weak timer0b_handler = null_handler
-#pragma weak timer1a_handler = null_handler
-#pragma weak timer1b_handler = null_handler
-#pragma weak timer2a_handler = null_handler
-#pragma weak timer2b_handler = null_handler
-#pragma weak comp0_handler = null_handler
-#pragma weak comp1_handler = null_handler
-#pragma weak comp2_handler = null_handler
-#pragma weak sysctl_handler = null_handler
-#pragma weak flash_handler = null_handler
-#pragma weak gpiof_handler = null_handler
-#pragma weak gpiog_handler = null_handler
-#pragma weak gpioh_handler = null_handler
-#pragma weak uart2_handler = null_handler
-#pragma weak ssi1_handler = null_handler
-#pragma weak timer3a_handler = null_handler
-#pragma weak timer3b_handler = null_handler
-#pragma weak i2c1_handler = null_handler
-#pragma weak qei1_handler = null_handler
-#pragma weak can0_handler = null_handler
-#pragma weak can1_handler = null_handler
-#pragma weak can2_handler = null_handler
-#pragma weak eth_handler = null_handler
-#pragma weak hibernate_handler = null_handler
-#pragma weak usb0_handler = null_handler
-#pragma weak pwm0_3_handler = null_handler
-#pragma weak udma_handler = null_handler
-#pragma weak udmaerr_handler = null_handler
-#pragma weak adc1ss0_handler = null_handler
-#pragma weak adc1ss1_handler = null_handler
-#pragma weak adc1ss2_handler = null_handler
-#pragma weak adc1ss3_handler = null_handler
-#pragma weak i2s0_handler = null_handler
-#pragma weak epi0_handler = null_handler
-#pragma weak gpioj_handler = null_handler
-#pragma weak gpiok_handler = null_handler
-#pragma weak gpiol_handler = null_handler
-#pragma weak ssi2_handler = null_handler
-#pragma weak ssi3_handler = null_handler
-#pragma weak uart3_handler = null_handler
-#pragma weak uart4_handler = null_handler
-#pragma weak uart5_handler = null_handler
-#pragma weak uart6_handler = null_handler
-#pragma weak uart7_handler = null_handler
-#pragma weak i2c2_handler = null_handler
-#pragma weak i2c3_handler = null_handler
-#pragma weak timer4a_handler = null_handler
-#pragma weak timer4b_handler = null_handler
-#pragma weak timer5a_handler = null_handler
-#pragma weak timer5b_handler = null_handler
-#pragma weak wtimer0a_handler = null_handler
-#pragma weak wtimer0b_handler = null_handler
-#pragma weak wtimer1a_handler = null_handler
-#pragma weak wtimer1b_handler = null_handler
-#pragma weak wtimer2a_handler = null_handler
-#pragma weak wtimer2b_handler = null_handler
-#pragma weak wtimer3a_handler = null_handler
-#pragma weak wtimer3b_handler = null_handler
-#pragma weak wtimer4a_handler = null_handler
-#pragma weak wtimer4b_handler = null_handler
-#pragma weak wtimer5a_handler = null_handler
-#pragma weak wtimer5b_handler = null_handler
-#pragma weak sysexc_handler = null_handler
-#pragma weak peci0_handler = null_handler
-#pragma weak lpc0_handler = null_handler
-#pragma weak i2c4_handler = null_handler
-#pragma weak i2c5_handler = null_handler
-#pragma weak gpiom_handler = null_handler
-#pragma weak gpion_handler = null_handler
-#pragma weak fan0_handler = null_handler
-#pragma weak gpiop0_handler = null_handler
-#pragma weak gpiop1_handler = null_handler
-#pragma weak gpiop2_handler = null_handler
-#pragma weak gpiop3_handler = null_handler
-#pragma weak gpiop4_handler = null_handler
-#pragma weak gpiop5_handler = null_handler
-#pragma weak gpiop6_handler = null_handler
-#pragma weak gpiop7_handler = null_handler
-#pragma weak gpioq0_handler = null_handler
-#pragma weak gpioq1_handler = null_handler
-#pragma weak gpioq2_handler = null_handler
-#pragma weak gpioq3_handler = null_handler
-#pragma weak gpioq4_handler = null_handler
-#pragma weak gpioq5_handler = null_handler
-#pragma weak gpioq6_handler = null_handler
-#pragma weak gpioq7_handler = null_handler
-#pragma weak pwm1_0_handler = null_handler
-#pragma weak pwm1_1_handler = null_handler
-#pragma weak pwm1_2_handler = null_handler
-#pragma weak pwm1_3_handler = null_handler
-#pragma weak pwm1_fault_handler = null_handler
diff --git a/lib/lpc13xx/Makefile b/lib/lpc13xx/Makefile
index e1e69f7..15bc686 100644
--- a/lib/lpc13xx/Makefile
+++ b/lib/lpc13xx/Makefile
@@ -25,10 +25,10 @@ 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
+ -ffunction-sections -fdata-sections -MD -DLPC13XX
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = gpio.o assert.o
+OBJS = gpio.o
VPATH += ../cm3
diff --git a/lib/lpc17xx/Makefile b/lib/lpc17xx/Makefile
index d1da64a..19fc152 100644
--- a/lib/lpc17xx/Makefile
+++ b/lib/lpc17xx/Makefile
@@ -25,10 +25,10 @@ CC = $(PREFIX)-gcc
AR = $(PREFIX)-ar
CFLAGS = -O0 -g -Wall -Wextra -I../../include -fno-common \
-mcpu=cortex-m3 -mthumb -Wstrict-prototypes \
- -ffunction-sections -fdata-sections -MD
+ -ffunction-sections -fdata-sections -MD -DLPC17XX
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = gpio.o vector.o assert.o
+OBJS = gpio.o
VPATH += ../cm3
diff --git a/lib/lpc43xx/Makefile b/lib/lpc43xx/Makefile
index 6e08ea0..efbba0d 100644
--- a/lib/lpc43xx/Makefile
+++ b/lib/lpc43xx/Makefile
@@ -28,11 +28,10 @@ AR = $(PREFIX)-ar
CFLAGS = -O2 -g3 -Wall -Wextra -I../../include -fno-common \
-mcpu=cortex-m4 -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD \
- -mfloat-abi=hard -mfpu=fpv4-sp-d16
+ -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = gpio.o vector.o scu.o i2c.o ssp.o nvic.o systick.o \
- assert.o
+OBJS = gpio.o scu.o i2c.o ssp.o
VPATH += ../cm3
diff --git a/lib/lpc43xx/nvic.c b/lib/lpc43xx/nvic.c
deleted file mode 100644
index 4793312..0000000
--- a/lib/lpc43xx/nvic.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
- * Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
- * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
- *
- * 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/cm3/scs.h>
-#include <libopencm3/lpc43xx/nvic.h>
-
-void nvic_enable_irq(u8 irqn)
-{
- NVIC_ISER(irqn / 32) = (1 << (irqn % 32));
-}
-
-void nvic_disable_irq(u8 irqn)
-{
- NVIC_ICER(irqn / 32) = (1 << (irqn % 32));
-}
-
-u8 nvic_get_pending_irq(u8 irqn)
-{
- return NVIC_ISPR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
-}
-
-void nvic_set_pending_irq(u8 irqn)
-{
- NVIC_ISPR(irqn / 32) = (1 << (irqn % 32));
-}
-
-void nvic_clear_pending_irq(u8 irqn)
-{
- NVIC_ICPR(irqn / 32) = (1 << (irqn % 32));
-}
-
-u8 nvic_get_active_irq(u8 irqn)
-{
- return NVIC_IABR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
-}
-
-u8 nvic_get_irq_enabled(u8 irqn)
-{
- return NVIC_ISER(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
-}
-
-void nvic_set_priority(u8 irqn, u8 priority)
-{
- if(irqn>NVIC_M4_QEI_IRQ)
- {
- /* Cortex-M system interrupts */
- SCS_SHPR( (irqn&0xF)-4 ) = priority;
- }else
- {
- /* Device specific interrupts */
- NVIC_IPR(irqn) = priority;
- }
-}
-
-void nvic_generate_software_interrupt(u8 irqn)
-{
- if (irqn <= 239)
- NVIC_STIR |= irqn;
-}
diff --git a/lib/lpc43xx/systick.c b/lib/lpc43xx/systick.c
deleted file mode 100644
index 82345a9..0000000
--- a/lib/lpc43xx/systick.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
- * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
- *
- * 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/lpc43xx/systick.h>
-
-void systick_set_reload(u32 value)
-{
- STK_LOAD = (value & 0x00FFFFFF);
-}
-
-u32 systick_get_value(void)
-{
- return STK_VAL;
-}
-
-void systick_set_clocksource(u8 clocksource)
-{
- STK_CTRL |= clocksource;
-}
-
-void systick_interrupt_enable(void)
-{
- STK_CTRL |= STK_CTRL_TICKINT;
-}
-
-void systick_interrupt_disable(void)
-{
- STK_CTRL &= ~STK_CTRL_TICKINT;
-}
-
-void systick_counter_enable(void)
-{
- STK_CTRL |= STK_CTRL_ENABLE;
-}
-
-void systick_counter_disable(void)
-{
- STK_CTRL &= ~STK_CTRL_ENABLE;
-}
-
-u8 systick_get_countflag(void)
-{
- if (STK_CTRL & STK_CTRL_COUNTFLAG)
- return 1;
- else
- return 0;
-}
-
-u32 systick_get_calib(void)
-{
- return (STK_CALIB&0x00FFFFFF);
-}
diff --git a/lib/lpc43xx/vector.c b/lib/lpc43xx/vector.c
deleted file mode 100644
index 23008bc..0000000
--- a/lib/lpc43xx/vector.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
- * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
- *
- * 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/>.
- */
-
-#define WEAK __attribute__ ((weak))
-
-/* Symbols exported by the linker script(s): */
-extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack;
-extern unsigned _etext_ram, _text_ram, _etext_rom;
-
-void main(void);
-void reset_handler(void);
-void blocking_handler(void);
-void null_handler(void);
-
-void WEAK nmi_handler(void);
-void WEAK hard_fault_handler(void);
-void WEAK mem_manage_handler(void);
-void WEAK bus_fault_handler(void);
-void WEAK usage_fault_handler(void);
-void WEAK sv_call_handler(void);
-void WEAK debug_monitor_handler(void);
-void WEAK pend_sv_handler(void);
-void WEAK sys_tick_handler(void);
-void WEAK dac_irqhandler(void);
-void WEAK m0core_irqhandler(void);
-void WEAK dma_irqhandler(void);
-void WEAK ethernet_irqhandler(void);
-void WEAK sdio_irqhandler(void);
-void WEAK lcd_irqhandler(void);
-void WEAK usb0_irqhandler(void);
-void WEAK usb1_irqhandler(void);
-void WEAK sct_irqhandler(void);
-void WEAK ritimer_irqhandler(void);
-void WEAK timer0_irqhandler(void);
-void WEAK timer1_irqhandler(void);
-void WEAK timer2_irqhandler(void);
-void WEAK timer3_irqhandler(void);
-void WEAK mcpwm_irqhandler(void);
-void WEAK adc0_irqhandler(void);
-void WEAK i2c0_irqhandler(void);
-void WEAK i2c1_irqhandler(void);
-void WEAK spi_irqhandler(void);
-void WEAK adc1_irqhandler(void);
-void WEAK ssp0_irqhandler(void);
-void WEAK ssp1_irqhandler(void);
-void WEAK usart0_irqhandler(void);
-void WEAK uart1_irqhandler(void);
-void WEAK usart2_irqhandler(void);
-void WEAK usart3_irqhandler(void);
-void WEAK i2s0_irqhandler(void);
-void WEAK i2s1_irqhandler(void);
-void WEAK spifi_irqhandler(void);
-void WEAK sgpio_irqhandler(void);
-void WEAK pin_int0_irqhandler(void);
-void WEAK pin_int1_irqhandler(void);
-void WEAK pin_int2_irqhandler(void);
-void WEAK pin_int3_irqhandler(void);
-void WEAK pin_int4_irqhandler(void);
-void WEAK pin_int5_irqhandler(void);
-void WEAK pin_int6_irqhandler(void);
-void WEAK pin_int7_irqhandler(void);
-void WEAK gint0_irqhandler(void);
-void WEAK gint1_irqhandler(void);
-void WEAK eventrouter_irqhandler(void);
-void WEAK c_can1_irqhandler(void);
-void WEAK atimer_irqhandler(void);
-void WEAK rtc_irqhandler(void);
-void WEAK wwdt_irqhandler(void);
-void WEAK c_can0_irqhandler(void);
-void WEAK qei_irqhandler(void);
-
-__attribute__ ((section(".vectors")))
-void (*const vector_table[]) (void) = {
- /* Cortex-M4 interrupts */
- (void*)&_stack,
- reset_handler,
- nmi_handler,
- hard_fault_handler,
- mem_manage_handler,
- bus_fault_handler,
- usage_fault_handler,
- 0, 0, 0, 0, /* reserved */
- sv_call_handler,
- debug_monitor_handler,
- 0, /* reserved */
- pend_sv_handler,
- sys_tick_handler,
-
- /* LPC43xx interrupts */
- dac_irqhandler,
- m0core_irqhandler,
- dma_irqhandler,
- 0, /* reserved */
- 0, /* reserved */
- ethernet_irqhandler,
- sdio_irqhandler,
- lcd_irqhandler,
- usb0_irqhandler,
- usb1_irqhandler,
- sct_irqhandler,
- ritimer_irqhandler,
- timer0_irqhandler,
- timer1_irqhandler,
- timer2_irqhandler,
- timer3_irqhandler,
- mcpwm_irqhandler,
- adc0_irqhandler,
- i2c0_irqhandler,
- i2c1_irqhandler,
- spi_irqhandler,
- adc1_irqhandler,
- ssp0_irqhandler,
- ssp1_irqhandler,
- usart0_irqhandler,
- uart1_irqhandler,
- usart2_irqhandler,
- usart3_irqhandler,
- i2s0_irqhandler,
- i2s1_irqhandler,
- spifi_irqhandler,
- sgpio_irqhandler,
- pin_int0_irqhandler,
- pin_int1_irqhandler,
- pin_int2_irqhandler,
- pin_int3_irqhandler,
- pin_int4_irqhandler,
- pin_int5_irqhandler,
- pin_int6_irqhandler,
- pin_int7_irqhandler,
- gint0_irqhandler,
- gint1_irqhandler,
- eventrouter_irqhandler,
- c_can1_irqhandler,
- 0, /* reserved */
- 0, /* reserved */
- atimer_irqhandler,
- rtc_irqhandler,
- 0, /* reserved */
- wwdt_irqhandler,
- 0, /* reserved */
- c_can0_irqhandler,
- qei_irqhandler,
-};
-
-#define MMIO32(addr) (*(volatile unsigned long*)(addr))
-#define CREG_M4MEMMAP MMIO32( (0x40043000 + 0x100) )
-
-void reset_handler(void)
-{
- volatile unsigned *src, *dest;
-
- __asm__("MSR msp, %0" : : "r"(&_stack));
-
- /* Copy the code from ROM to Real RAM (if enabled) */
- if( (&_etext_ram-&_text_ram) > 0 )
- {
- src = &_etext_rom-(&_etext_ram-&_text_ram);
- /* Change Shadow memory to ROM (for Debug Purpose in case Boot has not set correctly the M4MEMMAP because of debug) */
- CREG_M4MEMMAP = (unsigned long)src;
-
- for(dest = &_text_ram; dest < &_etext_ram; )
- {
- *dest++ = *src++;
- }
-
- /* Change Shadow memory to Real RAM */
- CREG_M4MEMMAP = (unsigned long)&_text_ram;
-
- /* Continue Execution in RAM */
- }
-
- for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++)
- *dest = *src;
-
- while (dest < &_ebss)
- *dest++ = 0;
-
- /* Call the application's entry point. */
- main();
-}
-
-void blocking_handler(void)
-{
- while (1) ;
-}
-
-void null_handler(void)
-{
- /* Do nothing. */
-}
-
-#pragma weak nmi_handler = null_handler
-#pragma weak hard_fault_handler = blocking_handler
-#pragma weak mem_manage_handler = blocking_handler
-#pragma weak bus_fault_handler = blocking_handler
-#pragma weak usage_fault_handler = blocking_handler
-#pragma weak sv_call_handler = null_handler
-#pragma weak debug_monitor_handler = null_handler
-#pragma weak pend_sv_handler = null_handler
-#pragma weak sys_tick_handler = null_handler
-#pragma weak dac_irqhandler = null_handler
-#pragma weak m0core_irqhandler = null_handler
-#pragma weak dma_irqhandler = null_handler
-#pragma weak ethernet_irqhandler = null_handler
-#pragma weak sdio_irqhandler = null_handler
-#pragma weak lcd_irqhandler = null_handler
-#pragma weak usb0_irqhandler = null_handler
-#pragma weak usb1_irqhandler = null_handler
-#pragma weak sct_irqhandler = null_handler
-#pragma weak ritimer_irqhandler = null_handler
-#pragma weak timer0_irqhandler = null_handler
-#pragma weak timer1_irqhandler = null_handler
-#pragma weak timer2_irqhandler = null_handler
-#pragma weak timer3_irqhandler = null_handler
-#pragma weak mcpwm_irqhandler = null_handler
-#pragma weak adc0_irqhandler = null_handler
-#pragma weak i2c0_irqhandler = null_handler
-#pragma weak i2c1_irqhandler = null_handler
-#pragma weak spi_irqhandler = null_handler
-#pragma weak adc1_irqhandler = null_handler
-#pragma weak ssp0_irqhandler = null_handler
-#pragma weak ssp1_irqhandler = null_handler
-#pragma weak usart0_irqhandler = null_handler
-#pragma weak uart1_irqhandler = null_handler
-#pragma weak usart2_irqhandler = null_handler
-#pragma weak usart3_irqhandler = null_handler
-#pragma weak i2s0_irqhandler = null_handler
-#pragma weak i2s1_irqhandler = null_handler
-#pragma weak spifi_irqhandler = null_handler
-#pragma weak sgpio_irqhandler = null_handler
-#pragma weak pin_int0_irqhandler = null_handler
-#pragma weak pin_int1_irqhandler = null_handler
-#pragma weak pin_int2_irqhandler = null_handler
-#pragma weak pin_int3_irqhandler = null_handler
-#pragma weak pin_int4_irqhandler = null_handler
-#pragma weak pin_int5_irqhandler = null_handler
-#pragma weak pin_int6_irqhandler = null_handler
-#pragma weak pin_int7_irqhandler = null_handler
-#pragma weak gint0_irqhandler = null_handler
-#pragma weak gint1_irqhandler = null_handler
-#pragma weak eventrouter_irqhandler = null_handler
-#pragma weak c_can1_irqhandler = null_handler
-#pragma weak atimer_irqhandler = null_handler
-#pragma weak rtc_irqhandler = null_handler
-#pragma weak wwdt_irqhandler = null_handler
-#pragma weak c_can0_irqhandler = null_handler
-#pragma weak qei_irqhandler = null_handler
diff --git a/lib/lpc43xx/vector_chipset.c b/lib/lpc43xx/vector_chipset.c
new file mode 100644
index 0000000..0463a65
--- /dev/null
+++ b/lib/lpc43xx/vector_chipset.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
+ * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com>
+ *
+ * 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/cm3/common.h>
+
+extern unsigned _etext_ram, _text_ram, _etext_rom;
+
+#define CREG_M4MEMMAP MMIO32( (0x40043000 + 0x100) )
+
+static void pre_main(void)
+{
+ volatile unsigned *src, *dest;
+
+ /* Copy the code from ROM to Real RAM (if enabled) */
+ if( (&_etext_ram-&_text_ram) > 0 )
+ {
+ src = &_etext_rom-(&_etext_ram-&_text_ram);
+ /* Change Shadow memory to ROM (for Debug Purpose in case Boot has not set correctly the M4MEMMAP because of debug) */
+ CREG_M4MEMMAP = (unsigned long)src;
+
+ for(dest = &_text_ram; dest < &_etext_ram; )
+ {
+ *dest++ = *src++;
+ }
+
+ /* Change Shadow memory to Real RAM */
+ CREG_M4MEMMAP = (unsigned long)&_text_ram;
+
+ /* Continue Execution in RAM */
+ }
+}
diff --git a/lib/stm32/f1/can.c b/lib/stm32/can.c
index f04fd26..3ee86c3 100644
--- a/lib/stm32/f1/can.c
+++ b/lib/stm32/can.c
@@ -18,7 +18,16 @@
*/
#include <libopencm3/stm32/can.h>
-#include <libopencm3/stm32/f1/rcc.h>
+
+#if defined(STM32F1)
+# include <libopencm3/stm32/f1/rcc.h>
+#elif defined(STM32F2)
+# include <libopencm3/stm32/f2/rcc.h>
+#elif defined(STM32F4)
+# include <libopencm3/stm32/f4/rcc.h>
+#else
+# error "stm32 family not defined."
+#endif
void can_reset(u32 canport)
{
@@ -314,7 +323,7 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
/* Release the FIFO. */
if (release)
- can_fifo_release(CAN1, 0);
+ can_fifo_release(canport, fifo);
}
bool can_available_mailbox(u32 canport)
diff --git a/lib/stm32/f1/desig.c b/lib/stm32/desig.c
index 7f213fa..ea861aa 100644
--- a/lib/stm32/f1/desig.c
+++ b/lib/stm32/desig.c
@@ -17,7 +17,7 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libopencm3/stm32/f1/desig.h>
+#include <libopencm3/stm32/desig.h>
u16 desig_get_flash_size(void)
{
diff --git a/lib/stm32/f2/exti.c b/lib/stm32/exti2.c
index 5280914..bea2f4d 100644
--- a/lib/stm32/f2/exti.c
+++ b/lib/stm32/exti2.c
@@ -2,6 +2,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
*
* 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
@@ -15,11 +16,22 @@
*
* 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/>.
+ *
+ * This provides the code for the "next gen" EXTI block provided in F2/F4/L1
+ * devices. (differences only in the source selection)
*/
#include <libopencm3/stm32/exti.h>
-#include <libopencm3/stm32/f2/syscfg.h>
+#include <libopencm3/stm32/syscfg.h>
+#if defined(STM32F2)
#include <libopencm3/stm32/f2/gpio.h>
+#elif defined(STM32F4)
+#include <libopencm3/stm32/f4/gpio.h>
+#elif defined(STM32L1)
+#include <libopencm3/stm32/l1/gpio.h>
+#else
+#error "invalid/unknown stm32 family for this code"
+#endif
void exti_set_trigger(u32 extis, exti_trigger_type trig)
{
@@ -121,12 +133,24 @@ void exti_select_source(u32 exti, u32 gpioport)
case GPIOE:
bits = 0xb;
break;
+#if defined(STM32L1)
+#else
case GPIOF:
bits = 0xa;
break;
case GPIOG:
bits = 0x9;
break;
+#endif
+ case GPIOH:
+ bits = 0x8;
+ break;
+#if defined(STM32L1)
+#else
+ case GPIOI:
+ bits = 0x7;
+ break;
+#endif
}
/* Ensure that only valid EXTI lines are used. */
diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile
index a2f7bf2..ed8ae29 100644
--- a/lib/stm32/f1/Makefile
+++ b/lib/stm32/f1/Makefile
@@ -28,10 +28,11 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-ffunction-sections -fdata-sections -MD -DSTM32F1
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = vector.o rcc.o gpio.o usart.o adc.o spi.o flash.o nvic.o \
- rtc.o i2c.o dma.o systick.o exti.o scb.o ethernet.o \
+OBJS = rcc.o gpio.o usart.o adc.o spi.o flash.o \
+ rtc.o i2c.o dma.o exti.o ethernet.o \
usb_f103.o usb.o usb_control.o usb_standard.o can.o \
- timer.o usb_f107.o desig.o crc.o assert.o dac.o iwdg.o pwr.o
+ timer.o usb_f107.o desig.o crc.o dac.o iwdg.o pwr.o \
+ usb_fx07_common.o
VPATH += ../../usb:../:../../cm3
diff --git a/lib/stm32/f1/dma.c b/lib/stm32/f1/dma.c
index 2bc8926..3dbb14f 100644
--- a/lib/stm32/f1/dma.c
+++ b/lib/stm32/f1/dma.c
@@ -10,12 +10,18 @@
@date 18 August 2012
-This library supports the DMA
-Control System in the STM32F1xx series of ARM Cortex Microcontrollers
-by ST Microelectronics. It can provide for two DMA controllers,
-one with 7 channels and one with 5. Channels are hardware dedicated
-and each is shared with a number of different sources (only one can be
-used at a time, under the responsibility of the programmer).
+This library supports the DMA Control System in the STM32 series of ARM Cortex
+Microcontrollers by ST Microelectronics.
+
+Up to two DMA controllers are supported. 12 DMA channels are allocated 7 to
+the first DMA controller and 5 to the second. Each channel is connected to
+between 3 and 6 hardware peripheral DMA signals in a logical OR arrangement.
+
+DMA transfers can be configured to occur between peripheral and memory in
+any combination including memory to memory. Circular mode transfers are
+also supported in transfers involving a peripheral. An arbiter is provided
+to resolve priority DMA requests. Transfers can be made with 8, 16 or 32 bit
+words.
LGPL License Terms @ref lgpl_license
*/
@@ -68,6 +74,42 @@ void dma_channel_reset(u32 dma, u8 channel)
}
/*-----------------------------------------------------------------------------*/
+/** @brief DMA Channel Clear Interrupt Flag
+
+The interrupt flag for the channel is cleared. More than one interrupt for the
+same channel may be cleared by using the logical OR of the interrupt flags.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] channel unsigned int8. Channel number: @ref dma_st_number
+@param[in] interrupts unsigned int32. Logical OR of interrupt numbers: @ref dma_if_offset
+*/
+
+void dma_clear_interrupt_flags(u32 dma, u8 channel, u32 interrupts)
+{
+/* Get offset to interrupt flag location in channel field */
+ u32 flags = (interrupts << DMA_FLAG_OFFSET(channel));
+ DMA_IFCR(dma) = flags;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Channel Read Interrupt Flag
+
+The interrupt flag for the channel is returned.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] channel unsigned int8. Channel number: @ref dma_st_number
+@param[in] interrupt unsigned int32. Interrupt number: @ref dma_st_number
+@returns bool interrupt flag is set.
+*/
+
+bool dma_get_interrupt_flag(u32 dma, u8 channel, u32 interrupt)
+{
+/* get offset to interrupt flag location in channel field. */
+ u32 flag = (interrupt << DMA_FLAG_OFFSET(channel));
+ return ((DMA_ISR(dma) & flag) > 0);
+}
+
+/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Memory to Memory Transfers
Memory to memory transfers do not require a trigger to activate each transfer.
@@ -160,12 +202,40 @@ void dma_enable_memory_increment_mode(u32 dma, u8 channel)
@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
*/
+void dma_disable_memory_increment_mode(u32 dma, u8 channel)
+{
+ DMA_CCR(dma, channel) &= ~DMA_CCR_MINC;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Channel Enable Peripheral Increment after Transfer
+
+Following each transfer the current peripheral address is incremented by
+1, 2 or 4 depending on the data size set in @ref dma_set_peripheral_size. The
+value held by the base peripheral address register is unchanged.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
+*/
+
void dma_enable_peripheral_increment_mode(u32 dma, u8 channel)
{
DMA_CCR(dma, channel) |= DMA_CCR_PINC;
}
/*-----------------------------------------------------------------------------*/
+/** @brief DMA Channel Disable Peripheral Increment after Transfer
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
+*/
+
+void dma_disable_peripheral_increment_mode(u32 dma, u8 channel)
+{
+ DMA_CCR(dma, channel) &= ~DMA_CCR_PINC;
+}
+
+/*-----------------------------------------------------------------------------*/
/** @brief DMA Channel Enable Memory Circular Mode
After the number of bytes/words to be transferred has been completed, the
diff --git a/lib/stm32/f1/vector.c b/lib/stm32/f1/vector.c
deleted file mode 100644
index 87fd655..0000000
--- a/lib/stm32/f1/vector.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
- *
- * 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/>.
- */
-
-#define WEAK __attribute__ ((weak))
-#define NAKED __attribute__((naked))
-#include <stdint.h>
-/* Symbols exported by the linker script(s): */
-extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack;
-
-void main(void);
-void reset_handler(void);
-void blocking_handler(void);
-void null_handler(void);
-
-void WEAK nmi_handler(void);
-void WEAK hard_fault_handler(void);
-void WEAK mem_manage_handler(void);
-void WEAK bus_fault_handler(void);
-void WEAK usage_fault_handler(void);
-void WEAK sv_call_handler(void);
-void WEAK debug_monitor_handler(void);
-void WEAK pend_sv_handler(void);
-void WEAK sys_tick_handler(void);
-void WEAK wwdg_isr(void);
-void WEAK pvd_isr(void);
-void WEAK tamper_isr(void);
-void WEAK rtc_isr(void);
-void WEAK flash_isr(void);
-void WEAK rcc_isr(void);
-void WEAK exti0_isr(void);
-void WEAK exti1_isr(void);
-void WEAK exti2_isr(void);
-void WEAK exti3_isr(void);
-void WEAK exti4_isr(void);
-void WEAK dma1_channel1_isr(void);
-void WEAK dma1_channel2_isr(void);
-void WEAK dma1_channel3_isr(void);
-void WEAK dma1_channel4_isr(void);
-void WEAK dma1_channel5_isr(void);
-void WEAK dma1_channel6_isr(void);
-void WEAK dma1_channel7_isr(void);
-void WEAK adc1_2_isr(void);
-void WEAK usb_hp_can_tx_isr(void);
-void WEAK usb_lp_can_rx0_isr(void);
-void WEAK can_rx1_isr(void);
-void WEAK can_sce_isr(void);
-void WEAK exti9_5_isr(void);
-void WEAK tim1_brk_isr(void);
-void WEAK tim1_up_isr(void);
-void WEAK tim1_trg_com_isr(void);
-void WEAK tim1_cc_isr(void);
-void WEAK tim2_isr(void);
-void WEAK tim3_isr(void);
-void WEAK tim4_isr(void);
-void WEAK i2c1_ev_isr(void);
-void WEAK i2c1_er_isr(void);
-void WEAK i2c2_ev_isr(void);
-void WEAK i2c2_er_isr(void);
-void WEAK spi1_isr(void);
-void WEAK spi2_isr(void);
-void WEAK usart1_isr(void);
-void WEAK usart2_isr(void);
-void WEAK usart3_isr(void);
-void WEAK exti15_10_isr(void);
-void WEAK rtc_alarm_isr(void);
-void WEAK usb_wakeup_isr(void);
-void WEAK tim8_brk_isr(void);
-void WEAK tim8_up_isr(void);
-void WEAK tim8_trg_com_isr(void);
-void WEAK tim8_cc_isr(void);
-void WEAK adc3_isr(void);
-void WEAK fsmc_isr(void);
-void WEAK sdio_isr(void);
-void WEAK tim5_isr(void);
-void WEAK spi3_isr(void);
-void WEAK uart4_isr(void);
-void WEAK uart5_isr(void);
-void WEAK tim6_isr(void);
-void WEAK tim7_isr(void);
-void WEAK dma2_channel1_isr(void);
-void WEAK dma2_channel2_isr(void);
-void WEAK dma2_channel3_isr(void);
-void WEAK dma2_channel4_5_isr(void);
-void WEAK dma2_channel5_isr(void);
-void WEAK eth_isr(void);
-void WEAK eth_wkup_isr(void);
-void WEAK can2_tx_isr(void);
-void WEAK can2_rx0_isr(void);
-void WEAK can2_rx1_isr(void);
-void WEAK can2_sce_isr(void);
-void WEAK otg_fs_isr(void);
-
-
-__attribute__ ((section(".vectors")))
-void (*const vector_table[]) (void) = {
- (void*)&_stack, /* Addr: 0x0000_0000 */
- reset_handler, /* Addr: 0x0000_0004 */
- nmi_handler, /* Addr: 0x0000_0008 */
- hard_fault_handler, /* Addr: 0x0000_000C */
- mem_manage_handler, /* Addr: 0x0000_0010 */
- bus_fault_handler, /* Addr: 0x0000_0014 */
- usage_fault_handler, /* Addr: 0x0000_0018 */
- 0, 0, 0, 0, /* Reserved Addr: 0x0000_001C - 0x0000_002B */
- sv_call_handler, /* Addr: 0x0000_002C */
- debug_monitor_handler, /* Addr: 0x0000_0030*/
- 0, /* Reserved Addr: 0x0000_00034 */
- pend_sv_handler, /* Addr: 0x0000_0038 */
- sys_tick_handler, /* Addr: 0x0000_003C */
- wwdg_isr, /* Addr: 0x0000_0040 */
- pvd_isr, /* Addr: 0x0000_0044 */
- tamper_isr, /* Addr: 0x0000_0048 */
- rtc_isr, /* Addr: 0x0000_004C */
- flash_isr, /* Addr: 0x0000_0050 */
- rcc_isr, /* Addr: 0x0000_0054 */
- exti0_isr, /* Addr: 0x0000_0058 */
- exti1_isr, /* Addr: 0x0000_005C */
- exti2_isr, /* Addr: 0x0000_0060 */
- exti3_isr, /* Addr: 0x0000_0064 */
- exti4_isr, /* Addr: 0x0000_0068 */
- dma1_channel1_isr, /* Addr: 0x0000_006C */
- dma1_channel2_isr, /* Addr: 0x0000_0070 */
- dma1_channel3_isr, /* Addr: 0x0000_0074 */
- dma1_channel4_isr, /* Addr: 0x0000_0078 */
- dma1_channel5_isr, /* Addr: 0x0000_007C */
- dma1_channel6_isr, /* Addr: 0x0000_0080 */
- dma1_channel7_isr, /* Addr: 0x0000_0084 */
- adc1_2_isr, /* Addr: 0x0000_0088 */
- usb_hp_can_tx_isr, /* Addr: 0x0000_008C */
- usb_lp_can_rx0_isr, /* Addr: 0x0000_0090 */
- can_rx1_isr, /* Addr: 0x0000_0094 */
- can_sce_isr, /* Addr: 0x0000_0098 */
- exti9_5_isr, /* Addr: 0x0000_009C */
- tim1_brk_isr, /* Addr: 0x0000_00A0 */
- tim1_up_isr, /* Addr: 0x0000_00A4 */
- tim1_trg_com_isr, /* Addr: 0x0000_00A8 */
- tim1_cc_isr, /* Addr: 0x0000_00AC */
- tim2_isr, /* Addr: 0x0000_00B0 */
- tim3_isr, /* Addr: 0x0000_00B4 */
- tim4_isr, /* Addr: 0x0000_00B8 */
- i2c1_ev_isr, /* Addr: 0x0000_00BC */
- i2c1_er_isr, /* Addr: 0x0000_00C0 */
- i2c2_ev_isr, /* Addr: 0x0000_00C4 */
- i2c2_er_isr, /* Addr: 0x0000_00C8 */
- spi1_isr, /* Addr: 0x0000_00CC */
- spi2_isr, /* Addr: 0x0000_00D0 */
- usart1_isr, /* Addr: 0x0000_00D4 */
- usart2_isr, /* Addr: 0x0000_00D8 */
- usart3_isr, /* Addr: 0x0000_00DC */
- exti15_10_isr, /* Addr: 0x0000_00E0 */
- rtc_alarm_isr, /* Addr: 0x0000_00E4 */
- usb_wakeup_isr, /* Addr: 0x0000_00E8 */
- tim8_brk_isr, /* Addr: 0x0000_00EC */
- tim8_up_isr, /* Addr: 0x0000_00F0 */
- tim8_trg_com_isr, /* Addr: 0x0000_00F4 */
- tim8_cc_isr, /* Addr: 0x0000_00F8 */
- adc3_isr, /* Addr: 0x0000_00FC */
- fsmc_isr, /* Addr: 0x0000_0100 */
- sdio_isr, /* Addr: 0x0000_0104 */
- tim5_isr, /* Addr: 0x0000_0108 */
- spi3_isr, /* Addr: 0x0000_010C */
- uart4_isr, /* Addr: 0x0000_0110 */
- uart5_isr, /* Addr: 0x0000_0114 */
- tim6_isr, /* Addr: 0x0000_0118 */
- tim7_isr, /* Addr: 0x0000_011C */
- dma2_channel1_isr, /* Addr: 0x0000_0120 */
- dma2_channel2_isr, /* Addr: 0x0000_0124 */
- dma2_channel3_isr, /* Addr: 0x0000_0128 */
- dma2_channel4_5_isr, /* Addr: 0x0000_012C */
- dma2_channel5_isr, /* Addr: 0x0000_0130 */
- eth_isr, /* Addr: 0x0000_0134 */
- eth_wkup_isr, /* Addr: 0x0000_0138 */
- can2_tx_isr, /* Addr: 0x0000_013C */
- can2_rx0_isr, /* Addr: 0x0000_0140 */
- can2_rx1_isr, /* Addr: 0x0000_0144 */
- can2_sce_isr, /* Addr: 0x0000_0148 */
- otg_fs_isr, /* Addr: 0x0000_014C */
-};
-
-void WEAK user_reset_hook(void);
-
-void handle_dfu_bootloader(void)
-{
- uint32_t reset_str = *((uint32_t *)0x2000FFF0);
-
- if (reset_str == 0xDEADBEEF) {
- *((uint32_t *)0x2000FFF0) = 0x00;
- asm("ldr r0, =0x1fffb000");
- asm("ldr sp, [r0, #0]");
- asm("ldr r0, [r0, #4]");
- asm("bx r0");
- }
-
-}
-
-void NAKED reset_handler(void)
-{
- volatile unsigned *src, *dest;
-
- __asm__("MSR msp, %0" : : "r"(&_stack));
-
- user_reset_hook();
-
- for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++)
- *dest = *src;
-
- while (dest < &_ebss)
- *dest++ = 0;
-
- /* Call the application's entry point. */
- main();
-}
-
-void blocking_handler(void)
-{
- while (1) ;
-}
-
-void null_handler(void)
-{
- /* Do nothing. */
-}
-
-#pragma weak user_reset_hook = handle_dfu_bootloader
-#pragma weak nmi_handler = null_handler
-#pragma weak hard_fault_handler = blocking_handler
-#pragma weak mem_manage_handler = blocking_handler
-#pragma weak bus_fault_handler = blocking_handler
-#pragma weak usage_fault_handler = blocking_handler
-#pragma weak sv_call_handler = null_handler
-#pragma weak debug_monitor_handler = null_handler
-#pragma weak pend_sv_handler = null_handler
-#pragma weak sys_tick_handler = null_handler
-#pragma weak wwdg_isr = null_handler
-#pragma weak pvd_isr = null_handler
-#pragma weak tamper_isr = null_handler
-#pragma weak rtc_isr = null_handler
-#pragma weak flash_isr = null_handler
-#pragma weak rcc_isr = null_handler
-#pragma weak exti0_isr = null_handler
-#pragma weak exti1_isr = null_handler
-#pragma weak exti2_isr = null_handler
-#pragma weak exti3_isr = null_handler
-#pragma weak exti4_isr = null_handler
-#pragma weak dma1_channel1_isr = null_handler
-#pragma weak dma1_channel2_isr = null_handler
-#pragma weak dma1_channel3_isr = null_handler
-#pragma weak dma1_channel4_isr = null_handler
-#pragma weak dma1_channel5_isr = null_handler
-#pragma weak dma1_channel6_isr = null_handler
-#pragma weak dma1_channel7_isr = null_handler
-#pragma weak adc1_2_isr = null_handler
-#pragma weak usb_hp_can_tx_isr = null_handler
-#pragma weak usb_lp_can_rx0_isr = null_handler
-#pragma weak can_rx1_isr = null_handler
-#pragma weak can_sce_isr = null_handler
-#pragma weak exti9_5_isr = null_handler
-#pragma weak tim1_brk_isr = null_handler
-#pragma weak tim1_up_isr = null_handler
-#pragma weak tim1_trg_com_isr = null_handler
-#pragma weak tim1_cc_isr = null_handler
-#pragma weak tim2_isr = null_handler
-#pragma weak tim3_isr = null_handler
-#pragma weak tim4_isr = null_handler
-#pragma weak i2c1_ev_isr = null_handler
-#pragma weak i2c1_er_isr = null_handler
-#pragma weak i2c2_ev_isr = null_handler
-#pragma weak i2c2_er_isr = null_handler
-#pragma weak spi1_isr = null_handler
-#pragma weak spi2_isr = null_handler
-#pragma weak usart1_isr = null_handler
-#pragma weak usart2_isr = null_handler
-#pragma weak usart3_isr = null_handler
-#pragma weak exti15_10_isr = null_handler
-#pragma weak rtc_alarm_isr = null_handler
-#pragma weak usb_wakeup_isr = null_handler
-#pragma weak tim8_brk_isr = null_handler
-#pragma weak tim8_up_isr = null_handler
-#pragma weak tim8_trg_com_isr = null_handler
-#pragma weak tim8_cc_isr = null_handler
-#pragma weak adc3_isr = null_handler
-#pragma weak fsmc_isr = null_handler
-#pragma weak sdio_isr = null_handler
-#pragma weak tim5_isr = null_handler
-#pragma weak spi3_isr = null_handler
-#pragma weak uart4_isr = null_handler
-#pragma weak uart5_isr = null_handler
-#pragma weak tim6_isr = null_handler
-#pragma weak tim7_isr = null_handler
-#pragma weak dma2_channel1_isr = null_handler
-#pragma weak dma2_channel2_isr = null_handler
-#pragma weak dma2_channel3_isr = null_handler
-#pragma weak dma2_channel4_5_isr = null_handler
-#pragma weak dma2_channel5_isr
-#pragma weak eth_isr = null_handler
-#pragma weak eth_wkup_isr = null_handler
-#pragma weak can2_tx_isr = null_handler
-#pragma weak can2_rx0_isr = null_handler
-#pragma weak can2_rx1_isr = null_handler
-#pragma weak can2_sce_isr = null_handler
-#pragma weak otg_fs_isr = null_handler
diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile
index c127d61..b64a033 100644
--- a/lib/stm32/f2/Makefile
+++ b/lib/stm32/f2/Makefile
@@ -28,8 +28,8 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-ffunction-sections -fdata-sections -MD -DSTM32F2
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \
- i2c.o systick.o exti.o scb.o timer.o assert.o
+OBJS = rcc.o gpio2.o usart.o spi.o flash.o \
+ i2c.o exti2.o timer.o
VPATH += ../../usb:../:../../cm3
diff --git a/lib/stm32/f2/timer.c b/lib/stm32/f2/timer.c
deleted file mode 100644
index 659f8a9..0000000
--- a/lib/stm32/f2/timer.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org>
- * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
- *
- * 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/>.
- */
-
-/*
- * Basic TIMER handling API.
- *
- * Examples:
- * timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT_MUL_2,
- * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP);
- */
-
-#include <libopencm3/stm32/f2/timer.h>
-#include <libopencm3/stm32/f2/rcc.h>
-
-void timer_reset(u32 timer_peripheral)
-{
- switch (timer_peripheral) {
- case TIM1:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST);
- break;
- case TIM2:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST);
- break;
- case TIM3:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST);
- break;
- case TIM4:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST);
- break;
- case TIM5:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST);
- break;
- case TIM6:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST);
- break;
- case TIM7:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST);
- break;
- case TIM8:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST);
- break;
-/* These timers are not supported in libopencm3 yet */
-/*
- case TIM9:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST);
- break;
- case TIM10:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST);
- break;
- case TIM11:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST);
- break;
- case TIM12:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST);
- break;
- case TIM13:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST);
- break;
- case TIM14:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST);
- break;
-*/
- }
-}
-
-void timer_enable_irq(u32 timer_peripheral, u32 irq)
-{
- TIM_DIER(timer_peripheral) |= irq;
-}
-
-void timer_disable_irq(u32 timer_peripheral, u32 irq)
-{
- TIM_DIER(timer_peripheral) &= ~irq;
-}
-
-bool timer_get_flag(u32 timer_peripheral, u32 flag)
-{
- if (((TIM_SR(timer_peripheral) & flag) != 0) &&
- ((TIM_DIER(timer_peripheral) & flag) != 0)) {
- return true;
- }
-
- return false;
-}
-
-void timer_clear_flag(u32 timer_peripheral, u32 flag)
-{
- TIM_SR(timer_peripheral) &= ~flag;
-}
-
-void timer_set_mode(u32 timer_peripheral, u32 clock_div,
- u32 alignment, u32 direction)
-{
- u32 cr1;
-
- cr1 = TIM_CR1(timer_peripheral);
-
- cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | TIM_CR1_CMS_MASK | TIM_CR1_DIR_DOWN);
-
- cr1 |= clock_div | alignment | direction;
-
- TIM_CR1(timer_peripheral) = cr1;
-}
-
-void timer_set_clock_division(u32 timer_peripheral, u32 clock_div)
-{
- clock_div &= TIM_CR1_CKD_CK_INT_MASK;
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK;
- TIM_CR1(timer_peripheral) |= clock_div;
-}
-
-void timer_enable_preload(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE;
-}
-
-void timer_disable_preload(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE;
-}
-
-void timer_set_alignment(u32 timer_peripheral, u32 alignment)
-{
- alignment &= TIM_CR1_CMS_MASK;
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK;
- TIM_CR1(timer_peripheral) |= alignment;
-}
-
-void timer_direction_up(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN;
-}
-
-void timer_direction_down(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN;
-}
-
-void timer_one_shot_mode(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_OPM;
-}
-
-void timer_continuous_mode(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM;
-}
-
-void timer_update_on_any(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS;
-}
-
-void timer_update_on_overflow(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_URS;
-}
-
-void timer_enable_update_event(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS;
-}
-
-void timer_disable_update_event(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS;
-}
-
-void timer_enable_counter(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_CEN;
-}
-
-void timer_disable_counter(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN;
-}
-
-void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs)
-{
- TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK;
-}
-
-void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs)
-{
- TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK);
-}
-
-void timer_set_ti1_ch123_xor(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S;
-}
-
-void timer_set_ti1_ch1(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S;
-}
-
-void timer_set_master_mode(u32 timer_peripheral, u32 mode)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK;
- TIM_CR2(timer_peripheral) |= mode;
-}
-
-void timer_set_dma_on_compare_event(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS;
-}
-
-void timer_set_dma_on_update_event(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS;
-}
-
-void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS;
-}
-
-void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS;
-}
-
-void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC;
-}
-
-void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC;
-}
-
-void timer_set_prescaler(u32 timer_peripheral, u32 value)
-{
- TIM_PSC(timer_peripheral) = value;
-}
-
-void timer_set_repetition_counter(u32 timer_peripheral, u32 value)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_RCR(timer_peripheral) = value;
-}
-
-void timer_set_period(u32 timer_peripheral, u32 period)
-{
- TIM_ARR(timer_peripheral) = period;
-}
-
-void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as fast enable only applies to the whole channel. */
- break;
- }
-}
-
-void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as fast enable only applies to the whole channel. */
- break;
- }
-}
-
-void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as fast enable only applies to the whole channel. */
- break;
- }
-}
-
-void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id,
- enum tim_oc_mode oc_mode)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK;
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT;
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK;
- switch (oc_mode) {
- case TIM_OCM_FROZEN:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FROZEN;
- break;
- case TIM_OCM_ACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_ACTIVE;
- break;
- case TIM_OCM_INACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_INACTIVE;
- break;
- case TIM_OCM_TOGGLE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_TOGGLE;
- break;
- case TIM_OCM_FORCE_LOW:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_LOW;
- break;
- case TIM_OCM_FORCE_HIGH:
- TIM_CCMR1(timer_peripheral) |=
- TIM_CCMR1_OC1M_FORCE_HIGH;
- break;
- case TIM_OCM_PWM1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM1;
- break;
- case TIM_OCM_PWM2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM2;
- break;
- }
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK;
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT;
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK;
- switch (oc_mode) {
- case TIM_OCM_FROZEN:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FROZEN;
- break;
- case TIM_OCM_ACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_ACTIVE;
- break;
- case TIM_OCM_INACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_INACTIVE;
- break;
- case TIM_OCM_TOGGLE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_TOGGLE;
- break;
- case TIM_OCM_FORCE_LOW:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_LOW;
- break;
- case TIM_OCM_FORCE_HIGH:
- TIM_CCMR1(timer_peripheral) |=
- TIM_CCMR1_OC2M_FORCE_HIGH;
- break;
- case TIM_OCM_PWM1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM1;
- break;
- case TIM_OCM_PWM2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM2;
- break;
- }
- break;
- case TIM_OC3:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK;
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC3S_OUT;
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK;
- switch (oc_mode) {
- case TIM_OCM_FROZEN:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FROZEN;
- break;
- case TIM_OCM_ACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC3M_ACTIVE;
- break;
- case TIM_OCM_INACTIVE:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_INACTIVE;
- break;
- case TIM_OCM_TOGGLE:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_TOGGLE;
- break;
- case TIM_OCM_FORCE_LOW:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_LOW;
- break;
- case TIM_OCM_FORCE_HIGH:
- TIM_CCMR2(timer_peripheral) |=
- TIM_CCMR2_OC3M_FORCE_HIGH;
- break;
- case TIM_OCM_PWM1:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM1;
- break;
- case TIM_OCM_PWM2:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM2;
- break;
- }
- break;
- case TIM_OC4:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK;
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC4S_OUT;
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK;
- switch (oc_mode) {
- case TIM_OCM_FROZEN:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FROZEN;
- break;
- case TIM_OCM_ACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC4M_ACTIVE;
- break;
- case TIM_OCM_INACTIVE:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_INACTIVE;
- break;
- case TIM_OCM_TOGGLE:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_TOGGLE;
- break;
- case TIM_OCM_FORCE_LOW:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_LOW;
- break;
- case TIM_OCM_FORCE_HIGH:
- TIM_CCMR2(timer_peripheral) |=
- TIM_CCMR2_OC4M_FORCE_HIGH;
- break;
- case TIM_OCM_PWM1:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM1;
- break;
- case TIM_OCM_PWM2:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM2;
- break;
- }
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P;
- break;
- case TIM_OC2:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P;
- break;
- case TIM_OC3:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P;
- break;
- case TIM_OC4:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to TIM1 and TIM8 only. */
- break;
- }
-
- /* Acting for TIM1 and TIM8 only from here onwards. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP;
- break;
- case TIM_OC2N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP;
- break;
- case TIM_OC3N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP;
- break;
- case TIM_OC1:
- case TIM_OC2:
- case TIM_OC3:
- case TIM_OC4:
- /* Ignoring as this option was already set above. */
- break;
- }
-}
-
-void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P;
- break;
- case TIM_OC2:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P;
- break;
- case TIM_OC3:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P;
- break;
- case TIM_OC4:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to TIM1 and TIM8 only. */
- break;
- }
-
- /* Acting for TIM1 and TIM8 only from here onwards. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP;
- break;
- case TIM_OC2N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP;
- break;
- case TIM_OC3N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP;
- break;
- case TIM_OC1:
- case TIM_OC2:
- case TIM_OC3:
- case TIM_OC4:
- /* Ignoring as this option was already set above. */
- break;
- }
-}
-
-void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E;
- break;
- case TIM_OC2:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E;
- break;
- case TIM_OC3:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E;
- break;
- case TIM_OC4:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to TIM1 and TIM8 only. */
- break;
- }
-
- /* Acting for TIM1 and TIM8 only from here onwards. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE;
- break;
- case TIM_OC2N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE;
- break;
- case TIM_OC3N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE;
- break;
- case TIM_OC1:
- case TIM_OC2:
- case TIM_OC3:
- case TIM_OC4:
- /* Ignoring as this option was already set above. */
- break;
- }
-}
-
-void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E;
- break;
- case TIM_OC2:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E;
- break;
- case TIM_OC3:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E;
- break;
- case TIM_OC4:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to TIM1 and TIM8 only. */
- break;
- }
-
- /* Acting for TIM1 and TIM8 only from here onwards. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE;
- break;
- case TIM_OC2N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE;
- break;
- case TIM_OC3N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE;
- break;
- case TIM_OC1:
- case TIM_OC2:
- case TIM_OC3:
- case TIM_OC4:
- /* Ignoring as this option was already set above. */
- break;
- }
-}
-
-void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- /* Acting for TIM1 and TIM8 only. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1;
- break;
- case TIM_OC1N:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N;
- break;
- case TIM_OC2:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2;
- break;
- case TIM_OC2N:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N;
- break;
- case TIM_OC3:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3;
- break;
- case TIM_OC3N:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N;
- break;
- case TIM_OC4:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4;
- break;
- }
-}
-
-void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- /* Acting for TIM1 and TIM8 only. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1;
- break;
- case TIM_OC1N:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N;
- break;
- case TIM_OC2:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2;
- break;
- case TIM_OC2N:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N;
- break;
- case TIM_OC3:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3;
- break;
- case TIM_OC3N:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N;
- break;
- case TIM_OC4:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4;
- break;
- }
-}
-
-void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCR1(timer_peripheral) = value;
- break;
- case TIM_OC2:
- TIM_CCR2(timer_peripheral) = value;
- break;
- case TIM_OC3:
- TIM_CCR3(timer_peripheral) = value;
- break;
- case TIM_OC4:
- TIM_CCR4(timer_peripheral) = value;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_enable_break_main_output(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE;
-}
-
-void timer_disable_break_main_output(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE;
-}
-
-void timer_enable_break_automatic_output(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE;
-}
-
-void timer_disable_break_automatic_output(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE;
-}
-
-void timer_set_break_polarity_high(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP;
-}
-
-void timer_set_break_polarity_low(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP;
-}
-
-void timer_enable_break(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE;
-}
-
-void timer_disable_break(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE;
-}
-
-void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR;
-}
-
-void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR;
-}
-
-void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI;
-}
-
-void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI;
-}
-
-void timer_set_break_lock(u32 timer_peripheral, u32 lock)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= lock;
-}
-
-void timer_set_deadtime(u32 timer_peripheral, u32 deadtime)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= deadtime;
-}
-
-void timer_generate_event(u32 timer_peripheral, u32 event)
-{
- TIM_EGR(timer_peripheral) |= event;
-}
-
-u32 timer_get_counter(u32 timer_peripheral)
-{
- return TIM_CNT(timer_peripheral);
-}
-
-void timer_set_option(u32 timer_peripheral, u32 option)
-{
- if (timer_peripheral == TIM2) {
- TIM_OR(timer_peripheral) &= ~TIM2_OR_ITR1_RMP_MASK;
- TIM_OR(timer_peripheral) |= option;
- } else if (timer_peripheral == TIM5) {
- TIM_OR(timer_peripheral) &= ~TIM5_OR_TI4_RMP_MASK;
- TIM_OR(timer_peripheral) |= option;
- }
-}
diff --git a/lib/stm32/f2/vector.c b/lib/stm32/f2/vector.c
deleted file mode 100644
index 3429bfb..0000000
--- a/lib/stm32/f2/vector.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
- * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
- *
- * 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/>.
- */
-
-#define WEAK __attribute__ ((weak))
-
-/* Symbols exported by the linker script(s): */
-extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack;
-
-void main(void);
-void reset_handler(void);
-void blocking_handler(void);
-void null_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 wwdg_isr(void);
-void WEAK pvd_isr(void);
-void WEAK tamp_stamp_isr(void);
-void WEAK rtc_wkup_isr(void);
-void WEAK flash_isr(void);
-void WEAK rcc_isr(void);
-void WEAK exti0_isr(void);
-void WEAK exti1_isr(void);
-void WEAK exti2_isr(void);
-void WEAK exti3_isr(void);
-void WEAK exti4_isr(void);
-void WEAK dma1_stream0_isr(void);
-void WEAK dma1_stream1_isr(void);
-void WEAK dma1_stream2_isr(void);
-void WEAK dma1_stream3_isr(void);
-void WEAK dma1_stream4_isr(void);
-void WEAK dma1_stream5_isr(void);
-void WEAK dma1_stream6_isr(void);
-void WEAK adc_isr(void);
-void WEAK can1_tx_isr(void);
-void WEAK can1_rx0_isr(void);
-void WEAK can1_rx1_isr(void);
-void WEAK can1_sce_isr(void);
-void WEAK exti9_5_isr(void);
-void WEAK tim1_brk_tim9_isr(void);
-void WEAK tim1_up_tim10_isr(void);
-void WEAK tim1_trg_com_tim11_isr(void);
-void WEAK tim1_cc_isr(void);
-void WEAK tim2_isr(void);
-void WEAK tim3_isr(void);
-void WEAK tim4_isr(void);
-void WEAK i2c1_ev_isr(void);
-void WEAK i2c1_er_isr(void);
-void WEAK i2c2_ev_isr(void);
-void WEAK i2c2_er_isr(void);
-void WEAK spi1_isr(void);
-void WEAK spi2_isr(void);
-void WEAK usart1_isr(void);
-void WEAK usart2_isr(void);
-void WEAK usart3_isr(void);
-void WEAK exti15_10_isr(void);
-void WEAK rtc_alarm_isr(void);
-void WEAK usb_fs_wkup_isr(void);
-void WEAK tim8_brk_tim12_isr(void);
-void WEAK tim8_up_tim13_isr(void);
-void WEAK tim8_trg_com_tim14_isr(void);
-void WEAK tim8_cc_isr(void);
-void WEAK dma1_stream7_isr(void);
-void WEAK fsmc_isr(void);
-void WEAK sdio_isr(void);
-void WEAK tim5_isr(void);
-void WEAK spi3_isr(void);
-void WEAK uart4_isr(void);
-void WEAK uart5_isr(void);
-void WEAK tim6_dac_isr(void);
-void WEAK tim7_isr(void);
-void WEAK dma2_stream0_isr(void);
-void WEAK dma2_stream1_isr(void);
-void WEAK dma2_stream2_isr(void);
-void WEAK dma2_stream3_isr(void);
-void WEAK dma2_stream4_isr(void);
-void WEAK eth_isr(void);
-void WEAK eth_wkup_isr(void);
-void WEAK can2_tx_isr(void);
-void WEAK can2_rx0_isr(void);
-void WEAK can2_rx1_isr(void);
-void WEAK can2_sce_isr(void);
-void WEAK otg_fs_isr(void);
-void WEAK dma2_stream5_isr(void);
-void WEAK dma2_stream6_isr(void);
-void WEAK dma2_stream7_isr(void);
-void WEAK usart6_isr(void);
-void WEAK i2c3_ev_isr(void);
-void WEAK i2c3_er_isr(void);
-void WEAK otg_hs_ep1_out_isr(void);
-void WEAK otg_hs_ep1_in_isr(void);
-void WEAK otg_hs_wkup_isr(void);
-void WEAK otg_hs_isr(void);
-void WEAK dcmi_isr(void);
-void WEAK cryp_isr(void);
-void WEAK hash_rng_isr(void);
-
-__attribute__ ((section(".vectors")))
-void (*const vector_table[]) (void) = {
- (void *)&_stack,
- reset_handler,
- nmi_handler,
- hard_fault_handler,
- mem_manage_handler,
- bus_fault_handler,
- usage_fault_handler,
- 0, 0, 0, 0, /* Reserved */
- sv_call_handler,
- debug_monitor_handler,
- 0, /* Reserved */
- pend_sv_handler,
- sys_tick_handler,
- wwdg_isr,
- pvd_isr,
- tamp_stamp_isr,
- rtc_wkup_isr,
- flash_isr,
- rcc_isr,
- exti0_isr,
- exti1_isr,
- exti2_isr,
- exti3_isr,
- exti4_isr,
- dma1_stream0_isr,
- dma1_stream1_isr,
- dma1_stream2_isr,
- dma1_stream3_isr,
- dma1_stream4_isr,
- dma1_stream5_isr,
- dma1_stream6_isr,
- adc_isr,
- can1_tx_isr,
- can1_rx0_isr,
- can1_rx1_isr,
- can1_sce_isr,
- exti9_5_isr,
- tim1_brk_tim9_isr,
- tim1_up_tim10_isr,
- tim1_trg_com_tim11_isr,
- tim1_cc_isr,
- tim2_isr,
- tim3_isr,
- tim4_isr,
- i2c1_ev_isr,
- i2c1_er_isr,
- i2c2_ev_isr,
- i2c2_er_isr,
- spi1_isr,
- spi2_isr,
- usart1_isr,
- usart2_isr,
- usart3_isr,
- exti15_10_isr,
- rtc_alarm_isr,
- usb_fs_wkup_isr,
- tim8_brk_tim12_isr,
- tim8_up_tim13_isr,
- tim8_trg_com_tim14_isr,
- tim8_cc_isr,
- dma1_stream7_isr,
- fsmc_isr,
- sdio_isr,
- tim5_isr,
- spi3_isr,
- uart4_isr,
- uart5_isr,
- tim6_dac_isr,
- tim7_isr,
- dma2_stream0_isr,
- dma2_stream1_isr,
- dma2_stream2_isr,
- dma2_stream3_isr,
- dma2_stream4_isr,
- eth_isr,
- eth_wkup_isr,
- can2_tx_isr,
- can2_rx0_isr,
- can2_rx1_isr,
- can2_sce_isr,
- otg_fs_isr,
- dma2_stream5_isr,
- dma2_stream6_isr,
- dma2_stream7_isr,
- usart6_isr,
- i2c3_ev_isr,
- i2c3_er_isr,
- otg_hs_ep1_out_isr,
- otg_hs_ep1_in_isr,
- otg_hs_wkup_isr,
- otg_hs_isr,
- dcmi_isr,
- cryp_isr,
- hash_rng_isr,
-};
-
-void reset_handler(void)
-{
- volatile unsigned *src, *dest;
-
- __asm__("MSR msp, %0" : : "r"(&_stack));
-
- for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++)
- *dest = *src;
-
- while (dest < &_ebss)
- *dest++ = 0;
-
- /* Call the application's entry point. */
- main();
-}
-
-void blocking_handler(void)
-{
- while (1) ;
-}
-
-void null_handler(void)
-{
- /* Do nothing. */
-}
-
-#pragma weak nmi_handler = null_handler
-#pragma weak hard_fault_handler = blocking_handler
-#pragma weak mem_manage_handler = blocking_handler
-#pragma weak bus_fault_handler = blocking_handler
-#pragma weak usage_fault_handler = blocking_handler
-#pragma weak sv_call_handler = null_handler
-#pragma weak debug_monitor_handler = null_handler
-#pragma weak pend_sv_handler = null_handler
-#pragma weak sys_tick_handler = null_handler
-#pragma weak wwdg_isr = null_handler
-#pragma weak pvd_isr = null_handler
-#pragma weak tamp_stamp_isr = null_handler
-#pragma weak rtc_wkup_isr = null_handler
-#pragma weak flash_isr = null_handler
-#pragma weak rcc_isr = null_handler
-#pragma weak exti0_isr = null_handler
-#pragma weak exti1_isr = null_handler
-#pragma weak exti2_isr = null_handler
-#pragma weak exti3_isr = null_handler
-#pragma weak exti4_isr = null_handler
-#pragma weak dma1_stream0_isr = null_handler
-#pragma weak dma1_stream1_isr = null_handler
-#pragma weak dma1_stream2_isr = null_handler
-#pragma weak dma1_stream3_isr = null_handler
-#pragma weak dma1_stream4_isr = null_handler
-#pragma weak dma1_stream5_isr = null_handler
-#pragma weak dma1_stream6_isr = null_handler
-#pragma weak adc_isr = null_handler
-#pragma weak can1_tx_isr = null_handler
-#pragma weak can1_rx0_isr = null_handler
-#pragma weak can1_rx1_isr = null_handler
-#pragma weak can1_sce_isr = null_handler
-#pragma weak exti9_5_isr = null_handler
-#pragma weak tim1_brk_tim9_isr = null_handler
-#pragma weak tim1_up_tim10_isr = null_handler
-#pragma weak tim1_trg_com_tim11_isr = null_handler
-#pragma weak tim1_cc_isr = null_handler
-#pragma weak tim2_isr = null_handler
-#pragma weak tim3_isr = null_handler
-#pragma weak tim4_isr = null_handler
-#pragma weak i2c1_ev_isr = null_handler
-#pragma weak i2c1_er_isr = null_handler
-#pragma weak i2c2_ev_isr = null_handler
-#pragma weak i2c2_er_isr = null_handler
-#pragma weak spi1_isr = null_handler
-#pragma weak spi2_isr = null_handler
-#pragma weak usart1_isr = null_handler
-#pragma weak usart2_isr = null_handler
-#pragma weak usart3_isr = null_handler
-#pragma weak exti15_10_isr = null_handler
-#pragma weak rtc_alarm_isr = null_handler
-#pragma weak usb_fs_wkup_isr = null_handler
-#pragma weak tim8_brk_tim12_isr = null_handler
-#pragma weak tim8_up_tim13_isr = null_handler
-#pragma weak tim8_trg_com_tim14_isr = null_handler
-#pragma weak tim8_cc_isr = null_handler
-#pragma weak dma1_stream7_isr = null_handler
-#pragma weak fsmc_isr = null_handler
-#pragma weak sdio_isr = null_handler
-#pragma weak tim5_isr = null_handler
-#pragma weak spi3_isr = null_handler
-#pragma weak uart4_isr = null_handler
-#pragma weak uart5_isr = null_handler
-#pragma weak tim6_dac_isr = null_handler
-#pragma weak tim7_isr = null_handler
-#pragma weak dma2_stream0_isr = null_handler
-#pragma weak dma2_stream1_isr = null_handler
-#pragma weak dma2_stream2_isr = null_handler
-#pragma weak dma2_stream3_isr = null_handler
-#pragma weak dma2_stream4_isr = null_handler
-#pragma weak eth_isr = null_handler
-#pragma weak eth_wkup_isr = null_handler
-#pragma weak can2_tx_isr = null_handler
-#pragma weak can2_rx0_isr = null_handler
-#pragma weak can2_rx1_isr = null_handler
-#pragma weak can2_sce_isr = null_handler
-#pragma weak otg_fs_isr = null_handler
-#pragma weak dma2_stream5_isr = null_handler
-#pragma weak dma2_stream6_isr = null_handler
-#pragma weak dma2_stream7_isr = null_handler
-#pragma weak usart6_isr = null_handler
-#pragma weak i2c3_ev_isr = null_handler
-#pragma weak i2c3_er_isr = null_handler
-#pragma weak otg_hs_ep1_out_isr = null_handler
-#pragma weak otg_hs_ep1_in_isr = null_handler
-#pragma weak otg_hs_wkup_isr = null_handler
-#pragma weak otg_hs_isr = null_handler
-#pragma weak dcmi_isr = null_handler
-#pragma weak cryp_isr = null_handler
-#pragma weak hash_rng_isr = null_handler
diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile
index fd0b279..09fe573 100644
--- a/lib/stm32/f4/Makefile
+++ b/lib/stm32/f4/Makefile
@@ -29,10 +29,10 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-ffunction-sections -fdata-sections -MD -DSTM32F4
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \
- i2c.o systick.o exti.o scb.o pwr.o timer.o \
- usb.o usb_standard.o usb_control.o usb_f107.o \
- assert.o
+OBJS = rcc.o gpio2.o usart.o spi.o flash.o \
+ i2c.o exti2.o pwr.o timer.o \
+ usb.o usb_standard.o usb_control.o usb_fx07_common.o usb_f107.o \
+ usb_f207.o adc.o dma.o
VPATH += ../../usb:../:../../cm3
diff --git a/lib/stm32/f4/adc.c b/lib/stm32/f4/adc.c
new file mode 100644
index 0000000..7475fac
--- /dev/null
+++ b/lib/stm32/f4/adc.c
@@ -0,0 +1,1027 @@
+/** @defgroup STM32F4xx_adc_file ADC
+
+@ingroup STM32F4xx
+
+@brief <b>libopencm3 STM32F4xx Analog to Digital Converters</b>
+
+@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net>
+
+@date 30 August 2012
+
+This library supports the A/D Converter Control System in the STM32 series
+of ARM Cortex Microcontrollers by ST Microelectronics.
+
+Devices can have up to three A/D converters each with their own set of registers.
+However all the A/D converters share a common clock which is prescaled from the APB2
+clock by default by a minimum factor of 2 to a maximum of 8. The ADC resolution
+can be set to 12, 10, 8 or 6 bits.
+
+Each A/D converter has up to 19 channels:
+@li On ADC1 the analog channels 16 is internally connected to the temperature
+sensor, channel 17 to V<sub>REFINT</sub>, and channel 18 to V<sub>BATT</sub>.
+@li On ADC2 and ADC3 the analog channels 16 - 18 are not used.
+
+The conversions can occur as a one-off conversion whereby the process stops once
+conversion is complete. The conversions can also be continuous wherein a new
+conversion starts immediately the previous conversion has ended.
+
+Conversion can occur as a single channel conversion or a scan of a group of
+channels in either continuous or one-off mode. If more than one channel is converted
+in a scan group, DMA must be used to transfer the data as there is only one
+result register available. An interrupt can be set to occur at the end of
+conversion, which occurs after all channels have been scanned.
+
+A discontinuous mode allows a subgroup of group of a channels to be converted in
+bursts of a given length.
+
+Injected conversions allow a second group of channels to be converted separately
+from the regular group. An interrupt can be set to occur at the end of
+conversion, which occurs after all channels have been scanned.
+
+@section adc_f4_api_ex Basic ADC Handling API.
+
+Example 1: Simple single channel conversion polled. Enable the peripheral clock
+and ADC, reset ADC and set the prescaler divider. Set multiple mode to independent.
+
+@code
+gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1);
+rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN);
+adc_set_clk_prescale(RCC_CFGR_ADCPRE_BY2);
+adc_disable_scan_mode(ADC1);
+adc_set_single_conversion_mode(ADC1);
+adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC);
+u8 channels[] = ADC_CHANNEL0;
+adc_set_regular_sequence(ADC1, 1, channels);
+adc_set_multi_mode(ADC_CCR_MULTI_INDEPENDENT);
+adc_power_on(ADC1);
+adc_start_conversion_regular(ADC1);
+while (! adc_eoc(ADC1));
+reg16 = adc_read_regular(ADC1);
+@endcode
+
+LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Ken Sarkies <ksarkies@internode.on.net>
+ *
+ * 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/stm32/f4/adc.h>
+
+/**@{*/
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Off
+
+Turn off the ADC to reduce power consumption to a few microamps.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_off(u32 adc)
+{
+ ADC_CR2(adc) &= ~ADC_CR2_ADON;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Analog Watchdog for Regular Conversions
+
+The analog watchdog allows the monitoring of an analog signal between two threshold
+levels. The thresholds must be preset. Comparison is done before data alignment
+takes place, so the thresholds are left-aligned.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_analog_watchdog_regular(u32 adc)
+{
+ ADC_CR1(adc) |= ADC_CR1_AWDEN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Analog Watchdog for Regular Conversions
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_analog_watchdog_regular(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_AWDEN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Analog Watchdog for Injected Conversions
+
+The analog watchdog allows the monitoring of an analog signal between two threshold
+levels. The thresholds must be preset. Comparison is done before data alignment
+takes place, so the thresholds are left-aligned.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_analog_watchdog_injected(u32 adc)
+{
+ ADC_CR1(adc) |= ADC_CR1_JAWDEN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Analog Watchdog for Injected Conversions
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_analog_watchdog_injected(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_JAWDEN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Discontinuous Mode for Regular Conversions
+
+In this mode the ADC converts, on each trigger, a subgroup of up to 8 of the
+defined regular channel group. The subgroup is defined by the number of
+consecutive channels to be converted. After a subgroup has been converted
+the next trigger will start conversion of the immediately following subgroup
+of the same length or until the whole group has all been converted. When the
+the whole group has been converted, the next trigger will restart conversion
+of the subgroup at the beginning of the whole group.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] length Unsigned int8. Number of channels in the group @ref adc_cr1_discnum
+*/
+
+void adc_enable_discontinuous_mode_regular(u32 adc, u8 length)
+{
+ if ( (length-1) > 7 ) return;
+ ADC_CR1(adc) |= ADC_CR1_DISCEN;
+ ADC_CR2(adc) |= ((length-1) << ADC_CR1_DISCNUM_SHIFT);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Discontinuous Mode for Regular Conversions
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_discontinuous_mode_regular(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_DISCEN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Discontinuous Mode for Injected Conversions
+
+In this mode the ADC converts sequentially one channel of the defined group of
+injected channels, cycling back to the first channel in the group once the
+entire group has been converted.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_discontinuous_mode_injected(u32 adc)
+{
+ ADC_CR1(adc) |= ADC_CR1_JDISCEN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Discontinuous Mode for Injected Conversions
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_discontinuous_mode_injected(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_JDISCEN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Automatic Injected Conversions
+
+The ADC converts a defined injected group of channels immediately after the
+regular channels have been converted. The external trigger on the injected
+channels is disabled as required.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_automatic_injected_group_conversion(u32 adc)
+{
+ adc_disable_external_trigger_injected(adc);
+ ADC_CR1(adc) |= ADC_CR1_JAUTO;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Automatic Injected Conversions
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_automatic_injected_group_conversion(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_JAUTO;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Analog Watchdog for All Regular and/or Injected Channels
+
+The analog watchdog allows the monitoring of an analog signal between two threshold
+levels. The thresholds must be preset. Comparison is done before data alignment
+takes place, so the thresholds are left-aligned.
+
+@note The analog watchdog must be enabled for either or both of the regular or
+injected channels. If neither are enabled, the analog watchdog feature will be
+disabled.
+@ref adc_enable_analog_watchdog_injected, @ref adc_enable_analog_watchdog_regular.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_analog_watchdog_on_all_channels(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_AWDSGL;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Analog Watchdog for a Selected Channel
+
+The analog watchdog allows the monitoring of an analog signal between two threshold
+levels. The thresholds must be preset. Comparison is done before data alignment
+takes place, so the thresholds are left-aligned.
+
+@note The analog watchdog must be enabled for either or both of the regular or
+injected channels. If neither are enabled, the analog watchdog feature will be
+disabled. If both are enabled, the same channel number is monitored.
+@ref adc_enable_analog_watchdog_injected, @ref adc_enable_analog_watchdog_regular.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] channel Unsigned int8. ADC channel number @ref adc_watchdog_channel
+*/
+
+void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel)
+{
+ u32 reg32;
+
+ reg32 = (ADC_CR1(adc) & ~ADC_CR1_AWDCH_MASK); /* Clear bits [4:0]. */
+ if (channel < 18)
+ reg32 |= channel;
+ ADC_CR1(adc) = reg32;
+ ADC_CR1(adc) |= ADC_CR1_AWDSGL;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set Scan Mode
+
+In this mode a conversion consists of a scan of the predefined set of channels,
+regular and injected, each channel conversion immediately following the
+previous one. It can use single, continuous or discontinuous mode.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_scan_mode(u32 adc)
+{
+ ADC_CR1(adc) |= ADC_CR1_SCAN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Scan Mode
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_scan_mode(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_SCAN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Injected End-Of-Conversion Interrupt
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_eoc_interrupt_injected(u32 adc)
+{
+ ADC_CR1(adc) |= ADC_CR1_JEOCIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Injected End-Of-Conversion Interrupt
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_eoc_interrupt_injected(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_JEOCIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Analog Watchdog Interrupt
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_awd_interrupt(u32 adc)
+{
+ ADC_CR1(adc) |= ADC_CR1_AWDIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Analog Watchdog Interrupt
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_awd_interrupt(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_AWDIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Regular End-Of-Conversion Interrupt
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_eoc_interrupt(u32 adc)
+{
+ ADC_CR1(adc) |= ADC_CR1_EOCIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable Regular End-Of-Conversion Interrupt
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_eoc_interrupt(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_EOCIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Software Triggered Conversion on Regular Channels
+
+This starts conversion on a set of defined regular channels. It is cleared by
+hardware once conversion starts.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_start_conversion_regular(u32 adc)
+{
+ /* Start conversion on regular channels. */
+ ADC_CR2(adc) |= ADC_CR2_SWSTART;
+
+ /* Wait until the ADC starts the conversion. */
+ while (ADC_CR2(adc) & ADC_CR2_SWSTART);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Software Triggered Conversion on Injected Channels
+
+This starts conversion on a set of defined injected channels. It is cleared by
+hardware once conversion starts.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_start_conversion_injected(u32 adc)
+{
+ /* Start conversion on injected channels. */
+ ADC_CR2(adc) |= ADC_CR2_JSWSTART;
+
+ /* Wait until the ADC starts the conversion. */
+ while (ADC_CR2(adc) & ADC_CR2_JSWSTART);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set the Data as Left Aligned
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_set_left_aligned(u32 adc)
+{
+ ADC_CR2(adc) |= ADC_CR2_ALIGN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set the Data as Right Aligned
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_set_right_aligned(u32 adc)
+{
+ ADC_CR2(adc) &= ~ADC_CR2_ALIGN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable DMA Transfers
+
+Only available for ADC1 through DMA1 channel1, and ADC3 through DMA2 channel5.
+ADC2 will use DMA if it is set as slave in dual mode with ADC1 in DMA transfer
+mode.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_dma(u32 adc)
+{
+ if ((adc == ADC1) | (adc == ADC3))
+ ADC_CR2(adc) |= ADC_CR2_DMA;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable DMA Transfers
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_dma(u32 adc)
+{
+ if ((adc == ADC1) | (adc == ADC3))
+ ADC_CR2(adc) &= ~ADC_CR2_DMA;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Continuous Conversion Mode
+
+In this mode the ADC starts a new conversion of a single channel or a channel
+group immediately following completion of the previous channel group conversion.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_set_continuous_conversion_mode(u32 adc)
+{
+ ADC_CR2(adc) |= ADC_CR2_CONT;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable Single Conversion Mode
+
+In this mode the ADC performs a conversion of one channel or a channel group
+and stops.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_set_single_conversion_mode(u32 adc)
+{
+ ADC_CR2(adc) &= ~ADC_CR2_CONT;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set the Sample Time for a Single Channel
+
+The sampling time can be selected in ADC clock cycles from 1.5 to 239.5.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] channel Unsigned int8. ADC Channel integer 0..18 or from @ref adc_channel
+@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg
+*/
+
+void adc_set_sample_time(u32 adc, u8 channel, u8 time)
+{
+ u32 reg32;
+
+ if (channel < 10) {
+ reg32 = ADC_SMPR2(adc);
+ reg32 &= ~(0x7 << (channel * 3));
+ reg32 |= (time << (channel * 3));
+ ADC_SMPR2(adc) = reg32;
+ } else {
+ reg32 = ADC_SMPR1(adc);
+ reg32 &= ~(0x7 << ((channel - 10) * 3));
+ reg32 |= (time << ((channel - 10) * 3));
+ ADC_SMPR1(adc) = reg32;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set the Sample Time for All Channels
+
+The sampling time can be selected in ADC clock cycles from 1.5 to 239.5, same for
+all channels.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg
+*/
+
+void adc_set_sample_time_on_all_channels(u32 adc, u8 time)
+{
+ u8 i;
+ u32 reg32 = 0;
+
+ for (i = 0; i <= 9; i++)
+ reg32 |= (time << (i * 3));
+ ADC_SMPR2(adc) = reg32;
+
+ for (i = 10; i <= 17; i++)
+ reg32 |= (time << ((i - 10) * 3));
+ ADC_SMPR1(adc) = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set Analog Watchdog Upper Threshold
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] threshold Unsigned int8. Upper threshold value
+*/
+
+void adc_set_watchdog_high_threshold(u32 adc, u16 threshold)
+{
+ u32 reg32 = 0;
+
+ reg32 = (u32)threshold;
+ reg32 &= ~0xfffff000; /* Clear all bits above 11. */
+ ADC_HTR(adc) = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set Analog Watchdog Lower Threshold
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] threshold Unsigned int8. Lower threshold value
+*/
+
+void adc_set_watchdog_low_threshold(u32 adc, u16 threshold)
+{
+ u32 reg32 = 0;
+
+ reg32 = (u32)threshold;
+ reg32 &= ~0xfffff000; /* Clear all bits above 11. */
+ ADC_LTR(adc) = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set a Regular Channel Conversion Sequence
+
+Define a sequence of channels to be converted as a regular group with a length
+from 1 to 16 channels. If this is called during conversion, the current conversion
+is reset and conversion begins again with the newly defined group.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] length Unsigned int8. Number of channels in the group.
+@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..18.
+*/
+
+void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[])
+{
+ u32 reg32_1 = 0, reg32_2 = 0, reg32_3 = 0;
+ u8 i = 0;
+
+ /* Maximum sequence length is 16 channels. */
+ if (length > 16)
+ return;
+
+ for (i = 1; i <= length; i++) {
+ if (i <= 6)
+ reg32_3 |= (channel[i - 1] << ((i - 1) * 5));
+ if ((i > 6) & (i <= 12))
+ reg32_2 |= (channel[i - 1] << ((i - 6 - 1) * 5));
+ if ((i > 12) & (i <= 16))
+ reg32_1 |= (channel[i - 1] << ((i - 12 - 1) * 5));
+ }
+ reg32_1 |= ((length -1) << ADC_SQR1_L_LSB);
+
+ ADC_SQR1(adc) = reg32_1;
+ ADC_SQR2(adc) = reg32_2;
+ ADC_SQR3(adc) = reg32_3;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set an Injected Channel Conversion Sequence
+
+Defines a sequence of channels to be converted as an injected group with a length
+from 1 to 4 channels. If this is called during conversion, the current conversion
+is reset and conversion begins again with the newly defined group.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] length Unsigned int8. Number of channels in the group.
+@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..18
+*/
+
+void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[])
+{
+ u32 reg32 = 0;
+ u8 i = 0;
+
+ /* Maximum sequence length is 4 channels. */
+ if ((length-1) > 3)
+ return;
+
+ for (i = 1; i <= length; i++)
+ reg32 |= (channel[4 - i] << ((4 - i) * 5));
+
+ reg32 |= ((length - 1) << ADC_JSQR_JL_LSB);
+
+ ADC_JSQR(adc) = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Read the End-of-Conversion Flag
+
+This flag is set after all channels of a regular or injected group have been
+converted.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@returns bool. End of conversion flag.
+*/
+
+bool adc_eoc(u32 adc)
+{
+ return ((ADC_SR(adc) & ADC_SR_EOC) != 0);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Read the End-of-Conversion Flag for Injected Conversion
+
+This flag is set after all channels of an injected group have been converted.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@returns bool. End of conversion flag.
+*/
+
+bool adc_eoc_injected(u32 adc)
+{
+ return ((ADC_SR(adc) & ADC_SR_JEOC) != 0);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Read from the Regular Conversion Result Register
+
+The result read back is 12 bits, right or left aligned within the first 16 bits.
+For ADC1 only, the higher 16 bits will hold the result from ADC2 if
+an appropriate dual mode has been set @see adc_set_dual_mode.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@returns Unsigned int32 conversion result.
+*/
+
+u32 adc_read_regular(u32 adc)
+{
+ return ADC_DR(adc);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Read from an Injected Conversion Result Register
+
+The result read back from the selected injected result register (one of four) is
+12 bits, right or left aligned within the first 16 bits. The result can have a
+negative value if the injected channel offset has been set @see adc_set_injected_offset.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] reg Unsigned int8. Register number (1 ... 4).
+@returns Unsigned int32 conversion result.
+*/
+
+u32 adc_read_injected(u32 adc, u8 reg)
+{
+ switch (reg) {
+ case 1:
+ return ADC_JDR1(adc);
+ case 2:
+ return ADC_JDR2(adc);
+ case 3:
+ return ADC_JDR3(adc);
+ case 4:
+ return ADC_JDR4(adc);
+ }
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set the Injected Channel Data Offset
+
+This value is subtracted from the injected channel results after conversion
+is complete, and can result in negative results. A separate value can be specified
+for each injected data register.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] reg Unsigned int8. Register number (1 ... 4).
+@param[in] offset Unsigned int32.
+*/
+
+void adc_set_injected_offset(u32 adc, u8 reg, u32 offset)
+{
+ switch (reg) {
+ case 1:
+ ADC_JOFR1(adc) = offset;
+ break;
+ case 2:
+ ADC_JOFR2(adc) = offset;
+ break;
+ case 3:
+ ADC_JOFR3(adc) = offset;
+ break;
+ case 4:
+ ADC_JOFR4(adc) = offset;
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Power On
+
+If the ADC is in power-down mode then it is powered up. The application needs
+to wait a time of about 3 microseconds for stabilization before using the ADC.
+If the ADC is already on this function call will have no effect.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_power_on(u32 adc)
+{
+ ADC_CR2(adc) |= ADC_CR2_ADON;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set Clock Prescale
+
+The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8.
+
+@param[in] prescale Unsigned int32. Prescale value for ADC Clock @ref adc_ccr_adcpre
+*/
+
+void adc_set_clk_prescale(u32 prescale)
+{
+ u32 reg32 = ((ADC_CCR & ~ADC_CCR_ADCPRE_MASK) | prescale);
+ ADC_CCR = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set Dual/Triple Mode
+
+The multiple mode uses ADC1 as master, ADC2 and optionally ADC3 in a slave
+arrangement. This setting is applied to ADC1 only.
+
+The various modes possible are described in the reference manual.
+
+@param[in] mode Unsigned int32. Multiple mode selection from @ref adc_multi_mode
+*/
+
+void adc_set_multi_mode(u32 mode)
+{
+ ADC_CCR |= mode;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable an External Trigger for Regular Channels
+
+This enables an external trigger for set of defined regular channels, and sets the
+polarity of the trigger event: rising or falling edge or both. Note that if the
+trigger polarity is zero, triggering is disabled.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] trigger Unsigned int32. Trigger identifier @ref adc_trigger_regular
+@param[in] polarity Unsigned int32. Trigger polarity @ref adc_trigger_polarity_regular
+*/
+
+void adc_enable_external_trigger_regular(u32 adc, u32 trigger, u32 polarity)
+{
+ u32 reg32 = ADC_CR2(adc);
+
+ reg32 &= ~(ADC_CR2_EXTSEL_MASK | ADC_CR2_EXTEN_MASK);
+ reg32 |= (trigger | polarity);
+ ADC_CR2(adc) = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable an External Trigger for Regular Channels
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_external_trigger_regular(u32 adc)
+{
+ ADC_CR2(adc) &= ~ADC_CR2_EXTEN_MASK;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable an External Trigger for Injected Channels
+
+This enables an external trigger for set of defined injected channels, and sets the
+polarity of the trigger event: rising or falling edge or both.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_injected
+@param[in] polarity Unsigned int32. Trigger polarity @ref adc_trigger_polarity_injected
+*/
+
+void adc_enable_external_trigger_injected(u32 adc, u32 trigger, u32 polarity)
+{
+ u32 reg32 = ADC_CR2(adc);
+
+ reg32 &= ~(ADC_CR2_JEXTSEL_MASK | ADC_CR2_JEXTEN_MASK);
+ reg32 |= (trigger | polarity);
+ ADC_CR2(adc) = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable an External Trigger for Injected Channels
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_external_trigger_injected(u32 adc)
+{
+ ADC_CR2(adc) &= ~ADC_CR2_JEXTEN_MASK;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set Resolution
+
+ADC Resolution can be reduced from 12 bits to 10, 8 or 6 bits for a corresponding
+reduction in conversion time (resolution + 3 ADC clock cycles).
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] resolution Unsigned int8. Resolution value @ref adc_cr1_res
+*/
+
+void adc_set_resolution(u32 adc, u16 resolution)
+{
+ u32 reg32 = ADC_CR1(adc);
+
+ reg32 &= ~ADC_CR1_RES_MASK;
+ reg32 |= resolution;
+ ADC_CR1(adc) = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable the Overrun Interrupt
+
+The overrun interrupt is generated when data is not read from a result register
+before the next conversion is written. If DMA is enabled, all transfers are
+terminated and any conversion sequence is aborted.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_overrun_interrupt(u32 adc)
+{
+ ADC_CR1(adc) |= ADC_CR1_OVRIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable the Overrun Interrupt
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_overrun_interrupt(u32 adc)
+{
+ ADC_CR1(adc) &= ~ADC_CR1_OVRIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Read the Overrun Flag
+
+The overrun flag is set when data is not read from a result register before the next
+conversion is written. If DMA is enabled, all transfers are terminated and any
+conversion sequence is aborted.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@returns Unsigned int32 conversion result.
+*/
+
+bool adc_get_overrun_flag(u32 adc)
+{
+ return (ADC_SR(adc) & ADC_SR_OVR);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Clear Overrun Flags
+
+The overrun flag is cleared. Note that if an overrun occurs, DMA is terminated.
+The flag must be cleared and the DMA stream and ADC reinitialised to resume
+conversions (see the reference manual).
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@returns Unsigned int32 conversion result.
+*/
+
+void adc_clear_overrun_flag(u32 adc)
+{
+/* need to write zero to clear this */
+ ADC_SR(adc) &= ~ADC_SR_OVR;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable an EOC for Each Conversion
+
+The EOC is set after each conversion in a sequence rather than at the end of the
+sequence. Overrun detection is enabled only if DMA is enabled.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_eoc_after_each(u32 adc)
+{
+ ADC_CR2(adc) |= ADC_CR2_EOCS;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable the EOC for Each Conversion
+
+The EOC is set at the end of each sequence rather than after each conversion in the
+sequence. Overrun detection is enabled always.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_eoc_after_group(u32 adc)
+{
+ ADC_CR2(adc) &= ~ADC_CR2_EOCS;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set DMA to Continue
+
+This must be set to allow DMA to continue to operate after the last conversion in
+the DMA sequence. This allows DMA to be used in continuous circular mode.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_set_dma_continue(u32 adc)
+{
+ ADC_CR2(adc) |= ADC_CR2_DDS;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Set DMA to Terminate
+
+This must be set to allow DMA to terminate after the last conversion in the DMA
+sequence. This can avoid overrun errors.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_set_dma_terminate(u32 adc)
+{
+ ADC_CR2(adc) &= ~ADC_CR2_DDS;
+}
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Read the Analog Watchdog Flag
+
+This flag is set when the converted voltage crosses the high or low thresholds.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@returns bool. AWD flag.
+*/
+
+bool adc_awd(u32 adc)
+{
+ return (ADC_SR(adc) & ADC_SR_AWD);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Enable The Temperature Sensor
+
+This enables both the sensor and the reference voltage measurements on channels
+16 and 17. These are only available on ADC1 channel 16 and 17 respectively.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_enable_temperature_sensor()
+{
+ ADC_CCR |= ADC_CCR_TSVREFE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief ADC Disable The Temperature Sensor
+
+Disabling this will reduce power consumption from the sensor and the reference
+voltage measurements.
+
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+*/
+
+void adc_disable_temperature_sensor()
+{
+ ADC_CCR &= ~ADC_CCR_TSVREFE;
+}
+
+/*-----------------------------------------------------------------------------*/
+
+/**@}*/
+
diff --git a/lib/stm32/f4/dma.c b/lib/stm32/f4/dma.c
new file mode 100644
index 0000000..7c80dcf
--- /dev/null
+++ b/lib/stm32/f4/dma.c
@@ -0,0 +1,772 @@
+/** @defgroup STM32F4xx-dma-file DMA
+
+@ingroup STM32F4xx
+
+@brief <b>libopencm3 STM32F4xx DMA Controller</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net>
+
+@date 18 October 2012
+
+This library supports the DMA Control System in the STM32F2 and STM32F4
+series of ARM Cortex Microcontrollers by ST Microelectronics.
+
+Up to two DMA controllers are supported each with 8 streams, and each stream
+having up to 8 channels hardware dedicated to various peripheral DMA signals.
+
+DMA transfers can be configured to occur between peripheral and memory in
+either direction, and memory to memory. Peripheral to peripheral transfer
+is not supported. Circular mode transfers are also supported in transfers
+involving a peripheral. An arbiter is provided to resolve priority DMA
+requests. Transfers can be made with 8, 16 or 32 bit words.
+
+Each stream has access to a 4 word deep FIFO and can use double buffering
+by means of two memory pointers. When using the FIFO it is possible to
+configure transfers to occur in indivisible bursts.
+
+It is also possible to select a peripheral to control the flow of data rather
+than the DMA controller. This limits the functionality but is udeful when the
+number of transfers is unknown.
+
+LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Ken Sarkies <ksarkies@internode.on.net>
+ *
+ * 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/stm32/f4/dma.h>
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Reset
+
+The specified stream is disabled and configuration registers are cleared.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_stream_reset(u32 dma, u8 stream)
+{
+/* Disable stream (must be done before register is otherwise changed). */
+ DMA_SCR(dma, stream) &= ~DMA_SCR_EN;
+/* Reset all config bits. */
+ DMA_SCR(dma, stream) = 0;
+/* Reset data transfer number. */
+ DMA_SNDTR(dma, stream) = 0;
+/* Reset peripheral and memory addresses. */
+ DMA_SPAR(dma, stream) = 0;
+ DMA_SM0AR(dma, stream) = 0;
+ DMA_SM1AR(dma, stream) = 0;
+/* This is the default setting */
+ DMA_SFCR(dma, stream) = 0x21;
+/* Reset all stream interrupt flags using the interrupt flag clear register. */
+ u32 mask = DMA_ISR_MASK(stream);
+ if (stream < 4)
+ {
+ DMA_LIFCR(dma) |= mask;
+ }
+ else
+ {
+ DMA_HIFCR(dma) |= mask;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Clear Interrupt Flag
+
+The interrupt flag for the stream is cleared. More than one interrupt for the
+same stream may be cleared by using the logical OR of the interrupt flags.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] interrupts unsigned int32. Logical OR of interrupt numbers: @ref dma_if_offset
+*/
+
+void dma_clear_interrupt_flags(u32 dma, u8 stream, u32 interrupts)
+{
+/* Get offset to interrupt flag location in stream field */
+ u32 flags = (interrupts << DMA_ISR_OFFSET(stream));
+/* First four streams are in low register. Flag clear must be set then reset. */
+ if (stream < 4)
+ {
+ DMA_LIFCR(dma) = flags;
+ }
+ else
+ {
+ DMA_HIFCR(dma) = flags;
+ }
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Read Interrupt Flag
+
+The interrupt flag for the stream is returned.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] interrupt unsigned int32. Interrupt number: @ref dma_if_offset
+@returns bool interrupt flag is set.
+*/
+
+bool dma_get_interrupt_flag(u32 dma, u8 stream, u32 interrupt)
+{
+/* get offset to interrupt flag location in stream field.
+Assumes stream and interrupt parameters are integers */
+ u32 flag = (interrupt << DMA_ISR_OFFSET(stream));
+/* First four streams are in low register */
+ if (stream < 4) return ((DMA_LISR(dma) & flag) > 0);
+ else return ((DMA_HISR(dma) & flag) > 0);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable Transfer Direction
+
+Set peripheral to memory, memory to peripheral or memory to memory. If memory
+to memory mode is selected, circular mode and double buffer modes are disabled.
+Ensure that these modes are not enabled at a later time.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] direction unsigned int32. Data transfer direction @ref dma_st_dir
+*/
+
+void dma_set_transfer_mode(u32 dma, u8 stream, u32 direction)
+{
+ u32 reg32 = (DMA_SCR(dma, stream) & ~DMA_SCR_DIR_MASK);
+/* Disable circular and double buffer modes if memory to memory transfers
+are in effect (Direct Mode is automatically disabled by hardware) */
+ if (direction == DMA_SCR_DIR_MEM2MEM)
+ {
+ reg32 &= ~(DMA_SCR_CIRC | DMA_SCR_DBM);
+ }
+ DMA_SCR(dma, stream) = (reg32 | direction);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set Priority
+
+Stream Priority has four levels: low to very high. This has precedence over the
+hardware priority. In the event of equal software priority the lower numbered
+stream has priority.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] prio unsigned int32. Priority level @ref dma_st_pri.
+*/
+
+void dma_set_priority(u32 dma, u8 stream, u32 prio)
+{
+ DMA_SCR(dma, stream) &= ~(DMA_SCR_PL_MASK);
+ DMA_SCR(dma, stream) |= prio;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set Memory Word Width
+
+Set the memory word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for
+alignment information if the source and destination widths do not match.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] mem_size unsigned int32. Memory word width @ref dma_st_memwidth.
+*/
+
+void dma_set_memory_size(u32 dma, u8 stream, u32 mem_size)
+{
+
+ DMA_SCR(dma, stream) &= ~(DMA_SCR_MSIZE_MASK);
+ DMA_SCR(dma, stream) |= mem_size;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set Peripheral Word Width
+
+Set the peripheral word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for
+alignment information if the source and destination widths do not match, or
+if the peripheral does not support byte or half-word writes.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] peripheral_size unsigned int32. Peripheral word width @ref dma_st_perwidth.
+*/
+
+void dma_set_peripheral_size(u32 dma, u8 stream, u32 peripheral_size)
+{
+ DMA_SCR(dma, stream) &= ~(DMA_SCR_PSIZE_MASK);
+ DMA_SCR(dma, stream) |= peripheral_size;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable Memory Increment after Transfer
+
+Following each transfer the current memory address is incremented by
+1, 2 or 4 depending on the data size set in @ref dma_set_memory_size. The
+value held by the base memory address register is unchanged.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_memory_increment_mode(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) |= DMA_SCR_MINC;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Channel Disable Memory Increment after Transfer
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_disable_memory_increment_mode(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) &= ~DMA_SCR_MINC;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Channel Enable Variable Sized Peripheral Increment after Transfer
+
+Following each transfer the current peripheral address is incremented by
+1, 2 or 4 depending on the data size set in @ref dma_set_peripheral_size. The
+value held by the base peripheral address register is unchanged.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_peripheral_increment_mode(u32 dma, u8 stream)
+{
+ u32 reg32 = (DMA_SCR(dma, stream) | DMA_SCR_PINC);
+ DMA_SCR(dma, stream) = (reg32 & ~DMA_SCR_PINCOS);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Channel Disable Peripheral Increment after Transfer
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_disable_peripheral_increment_mode(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) &= ~DMA_SCR_PINC;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Channel Enable Fixed Sized Peripheral Increment after Transfer
+
+Following each transfer the current peripheral address is incremented by
+4 regardless of the data size. The value held by the base peripheral address
+register is unchanged.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_fixed_peripheral_increment_mode(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) |= (DMA_SCR_PINC | DMA_SCR_PINCOS);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable Memory Circular Mode
+
+After the number of bytes/words to be transferred has been completed, the
+original transfer block size, memory and peripheral base addresses are
+reloaded and the process repeats.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@note This cannot be used with memory to memory mode. It is disabled
+automatically if the peripheral is selected as the flow controller.
+It is enabled automatically if double buffered mode is selected.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_circular_mode(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) |= DMA_SCR_CIRC;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Channel Select
+
+Associate an input channel to the stream. Not every channel is allocated to a
+hardware DMA request signal. The allocations for each stream are given in the
+STM32F4 Reference Manual.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] channel unsigned int8. Channel selection @ref dma_ch_sel
+*/
+
+void dma_channel_select(u32 dma, u8 stream, u32 channel)
+{
+ DMA_SCR(dma, stream) |= channel;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set Memory Burst Configuration
+
+Set the memory burst type to none, 4 8 or 16 word length. This is forced to none
+if direct mode is used.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] burst unsigned int8. Memory Burst selection @ref dma_mburst
+*/
+
+void dma_set_memory_burst(u32 dma, u8 stream, u32 burst)
+{
+ u32 reg32 = (DMA_SCR(dma, stream) & ~DMA_SCR_MBURST_MASK);
+ DMA_SCR(dma, stream) = (reg32 | burst);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set Peripheral Burst Configuration
+
+Set the memory burst type to none, 4 8 or 16 word length. This is forced to none
+if direct mode is used.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] burst unsigned int8. Peripheral Burst selection @ref dma_pburst
+*/
+
+void dma_set_peripheral_burst(u32 dma, u8 stream, u32 burst)
+{
+ u32 reg32 = (DMA_SCR(dma, stream) & ~DMA_SCR_PBURST_MASK);
+ DMA_SCR(dma, stream) = (reg32 | burst);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set Initial Target Memory
+
+In double buffered mode, set the target memory (M0 or M1) to be used for the first
+transfer.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] memory unsigned int8. Initial memory pointer to use: 0 or 1
+*/
+
+void dma_set_initial_target(u32 dma, u8 stream, u8 memory)
+{
+ u32 reg32 = (DMA_SCR(dma, stream) & ~DMA_SCR_CT);
+ if (memory == 1) reg32 |= DMA_SCR_CT;
+ DMA_SCR(dma, stream) = reg32;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Read Current Memory Target
+
+In double buffer mode, return the current memory target (M0 or M1). It is possible
+to update the memory pointer in the register that is <b> not </b> currently in
+use. An attempt to change the register currently in use will cause the stream
+to be disabled and the transfer error flag to be set.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@returns unsigned int8. Memory buffer in use: 0 or 1
+*/
+
+u8 dma_get_target(u32 dma, u8 stream)
+{
+ if (DMA_SCR(dma, stream) & DMA_SCR_CT) return 1;
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable Double Buffer Mode
+
+Double buffer mode is used for memory to/from peripheral transfers only, and in
+circular mode which is automatically enabled. Two memory buffers must be
+established with pointers stored in the memory pointer registers.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@note This cannot be used with memory to memory mode.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_double_buffer_mode(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) |= DMA_SCR_DBM;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set Peripheral Flow Control
+
+Set the peripheral to control DMA flow. Useful when the number of transfers is
+unknown. This is forced off when memory to memory mode is selected.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_set_peripheral_flow_control(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) |= DMA_SCR_PFCTRL;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set DMA Flow Control
+
+Set the DMA controller to control DMA flow. This is the default.
+
+Ensure that the stream is disabled otherwise the setting will not be changed.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_set_dma_flow_control(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) &= ~DMA_SCR_PFCTRL;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable Interrupt on Transfer Error
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_transfer_error_interrupt(u32 dma, u8 stream)
+{
+ dma_clear_interrupt_flags(dma, stream, DMA_ISR_TEIF);
+ DMA_SCR(dma, stream) |= DMA_SCR_TEIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Disable Interrupt on Transfer Error
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_disable_transfer_error_interrupt(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) &= ~DMA_SCR_TEIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable Interrupt on Transfer Half Complete
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_half_transfer_interrupt(u32 dma, u8 stream)
+{
+ dma_clear_interrupt_flags(dma, stream, DMA_ISR_HTIF);
+ DMA_SCR(dma, stream) |= DMA_SCR_HTIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Disable Interrupt on Transfer Half Complete
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_disable_half_transfer_interrupt(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) &= ~DMA_SCR_HTIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable Interrupt on Transfer Complete
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_transfer_complete_interrupt(u32 dma, u8 stream)
+{
+ dma_clear_interrupt_flags(dma, stream, DMA_ISR_TCIF);
+ DMA_SCR(dma, stream) |= DMA_SCR_TCIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Disable Interrupt on Transfer Complete
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_disable_transfer_complete_interrupt(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) &= ~DMA_SCR_TCIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable Interrupt on Direct Mode Error
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_direct_mode_error_interrupt(u32 dma, u8 stream)
+{
+ dma_clear_interrupt_flags(dma, stream, DMA_ISR_DMEIF);
+ DMA_SCR(dma, stream) |= DMA_SCR_DMEIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Disable Interrupt on Direct Mode Error
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_disable_direct_mode_error_interrupt(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) &= ~DMA_SCR_DMEIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Enable Interrupt on FIFO Error
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_fifo_error_interrupt(u32 dma, u8 stream)
+{
+ dma_clear_interrupt_flags(dma, stream, DMA_ISR_FEIF);
+ DMA_SFCR(dma, stream) |= DMA_FCR_FEIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Disable Interrupt on FIFO Error
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_disable_fifo_error_interrupt(u32 dma, u8 stream)
+{
+ DMA_SFCR(dma, stream) &= ~DMA_FCR_FEIE;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Get FIFO Status
+
+Status of FIFO (empty. full or partial filled states) is returned. This has no
+meaning if direct mode is enabled (as the FIFO is not used).
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@returns u32 FIFO Status @ref dma_fifo_status
+*/
+
+u32 dma_fifo_status(u32 dma, u8 stream)
+{
+ return (DMA_SFCR(dma, stream) & DMA_FCR_FS_MASK);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Enable Direct Mode
+
+Direct mode is the default. Data is transferred as soon as a DMA request is
+received. The FIFO is not used. This must not be set when memory to memory
+mode is selected.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_direct_mode(u32 dma, u8 stream)
+{
+ DMA_SFCR(dma, stream) &= ~DMA_FCR_DMDIS;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Enable FIFO Mode
+
+Data is transferred via a FIFO.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_fifo_mode(u32 dma, u8 stream)
+{
+ DMA_SFCR(dma, stream) |= DMA_FCR_DMDIS;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Set FIFO Threshold
+
+This is the filled level at which data is transferred out of the FIFO to the
+destination.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] threshold unsigned int8. Threshold setting @ref dma_fifo_thresh
+*/
+
+void dma_set_fifo_threshold(u32 dma, u8 stream, u32 threshold)
+{
+ u32 reg32 = (DMA_SFCR(dma, stream) & ~DMA_FCR_FTH_MASK);
+ DMA_SFCR(dma, stream) = (reg32 | threshold);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Enable
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_enable_stream(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) |= DMA_SCR_EN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Disable
+
+@note The DMA stream registers retain their values when the stream is disabled.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+*/
+
+void dma_disable_stream(u32 dma, u8 stream)
+{
+ DMA_SCR(dma, stream) &= ~DMA_SCR_EN;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set the Peripheral Address
+
+Set the address of the peripheral register to or from which data is to be transferred.
+Refer to the documentation for the specific peripheral.
+
+@note The DMA stream must be disabled before setting this address. This function
+has no effect if the stream is enabled.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] address unsigned int32. Peripheral Address.
+*/
+
+void dma_set_peripheral_address(u32 dma, u8 stream, u32 address)
+{
+ if (!(DMA_SCR(dma, stream) & DMA_SCR_EN))
+ DMA_SPAR(dma, stream) = (u32) address;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set the Base Memory Address 0
+
+Set the address pointer to the memory location for DMA transfers. The DMA stream
+must normally be disabled before setting this address, however it is possible
+to change this in double buffer mode when the current target is memory area 1
+(see @ref dma_get_target).
+
+This is the default base memory address used in direct mode.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] address unsigned int32. Memory Initial Address.
+*/
+
+void dma_set_memory_address(u32 dma, u8 stream, u32 address)
+{
+ u32 reg32 = DMA_SCR(dma, stream);
+ if ( !(reg32 & DMA_SCR_EN) || ((reg32 & DMA_SCR_CT) && (reg32 & DMA_SCR_DBM)) )
+ DMA_SM0AR(dma, stream) = (u32) address;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set the Base Memory Address 1
+
+Set the address pointer to the memory location for DMA transfers. The DMA stream
+must normally be disabled before setting this address, however it is possible
+to change this in double buffer mode when the current target is memory area 0
+(see @ref dma_get_target).
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] address unsigned int32. Memory Initial Address.
+*/
+
+void dma_set_memory_address_1(u32 dma, u8 stream, u32 address)
+{
+ u32 reg32 = DMA_SCR(dma, stream);
+ if ( !(reg32 & DMA_SCR_EN) || (!(reg32 & DMA_SCR_CT) && (reg32 & DMA_SCR_DBM)) )
+ DMA_SM1AR(dma, stream) = (u32) address;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief DMA Stream Set the Transfer Block Size
+
+@note The DMA stream must be disabled before setting this count value. The count
+is not changed if the stream is enabled.
+
+@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
+@param[in] stream unsigned int8. Stream number: @ref dma_st_number
+@param[in] number unsigned int16. Number of data words to transfer (65535 maximum).
+*/
+
+void dma_set_number_of_data(u32 dma, u8 stream, u16 number)
+{
+ DMA_SNDTR(dma, stream) = number;
+}
+/**@}*/
+
diff --git a/lib/stm32/f4/exti.c b/lib/stm32/f4/exti.c
deleted file mode 100644
index 155c21f..0000000
--- a/lib/stm32/f4/exti.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz>
- *
- * 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/stm32/exti.h>
-#include <libopencm3/stm32/f4/syscfg.h>
-#include <libopencm3/stm32/f4/gpio.h>
-
-void exti_set_trigger(u32 extis, exti_trigger_type trig)
-{
- switch (trig) {
- case EXTI_TRIGGER_RISING:
- EXTI_RTSR |= extis;
- EXTI_FTSR &= ~extis;
- break;
- case EXTI_TRIGGER_FALLING:
- EXTI_RTSR &= ~extis;
- EXTI_FTSR |= extis;
- break;
- case EXTI_TRIGGER_BOTH:
- EXTI_RTSR |= extis;
- EXTI_FTSR |= extis;
- break;
- }
-}
-
-void exti_enable_request(u32 extis)
-{
- /* Enable interrupts. */
- EXTI_IMR |= extis;
-
- /* Enable events. */
- EXTI_EMR |= extis;
-}
-
-void exti_disable_request(u32 extis)
-{
- /* Disable interrupts. */
- EXTI_IMR &= ~extis;
-
- /* Disable events. */
- EXTI_EMR &= ~extis;
-}
-
-/*
- * Reset the interrupt request by writing a 1 to the corresponding
- * pending bit register.
- */
-void exti_reset_request(u32 extis)
-{
- EXTI_PR = extis;
-}
-
-/*
- * Remap an external interrupt line to the corresponding pin on the
- * specified GPIO port.
- *
- * TODO: This could be rewritten in fewer lines of code.
- */
-void exti_select_source(u32 exti, u32 gpioport)
-{
- u8 shift, bits;
-
- shift = bits = 0;
-
- switch (exti) {
- case EXTI0:
- case EXTI4:
- case EXTI8:
- case EXTI12:
- shift = 0;
- break;
- case EXTI1:
- case EXTI5:
- case EXTI9:
- case EXTI13:
- shift = 4;
- break;
- case EXTI2:
- case EXTI6:
- case EXTI10:
- case EXTI14:
- shift = 8;
- break;
- case EXTI3:
- case EXTI7:
- case EXTI11:
- case EXTI15:
- shift = 12;
- break;
- }
-
- switch (gpioport) {
- case GPIOA:
- bits = 0xf;
- break;
- case GPIOB:
- bits = 0xe;
- break;
- case GPIOC:
- bits = 0xd;
- break;
- case GPIOD:
- bits = 0xc;
- break;
- case GPIOE:
- bits = 0xb;
- break;
- case GPIOF:
- bits = 0xa;
- break;
- case GPIOG:
- bits = 0x9;
- break;
- }
-
- /* Ensure that only valid EXTI lines are used. */
- if (exti < EXTI4) {
- SYSCFG_EXTICR1 &= ~(0x000F << shift);
- SYSCFG_EXTICR1 |= (~bits << shift);
- } else if (exti < EXTI8) {
- SYSCFG_EXTICR2 &= ~(0x000F << shift);
- SYSCFG_EXTICR2 |= (~bits << shift);
- } else if (exti < EXTI12) {
- SYSCFG_EXTICR3 &= ~(0x000F << shift);
- SYSCFG_EXTICR3 |= (~bits << shift);
- } else if (exti < EXTI16) {
- SYSCFG_EXTICR4 &= ~(0x000F << shift);
- SYSCFG_EXTICR4 |= (~bits << shift);
- }
-}
diff --git a/lib/stm32/f4/gpio.c b/lib/stm32/f4/gpio.c
deleted file mode 100644
index 1d7739d..0000000
--- a/lib/stm32/f4/gpio.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
- *
- * 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/stm32/f4/gpio.h>
-
-void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios)
-{
- u16 i;
- u32 moder, pupd;
-
- /*
- * We want to set the config only for the pins mentioned in gpios,
- * but keeping the others, so read out the actual config first.
- */
- moder = GPIO_MODER(gpioport);
- pupd = GPIO_PUPDR(gpioport);
-
- for (i = 0; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
-
- moder &= ~GPIO_MODE_MASK(i);
- moder |= GPIO_MODE(i, mode);
- pupd &= ~GPIO_PUPD_MASK(i);
- pupd |= GPIO_PUPD(i, pull_up_down);
- }
-
- /* Set mode and pull up/down control registers. */
- GPIO_MODER(gpioport) = moder;
- GPIO_PUPDR(gpioport) = pupd;
-}
-
-void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios)
-{
- u16 i;
- u32 ospeedr;
-
- if (otype == 0x1)
- GPIO_OTYPER(gpioport) |= gpios;
- else
- GPIO_OTYPER(gpioport) &= ~gpios;
-
- ospeedr = GPIO_OSPEEDR(gpioport);
-
- for (i = 0; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
- ospeedr &= ~GPIO_OSPEED_MASK(i);
- ospeedr |= GPIO_OSPEED(i, speed);
- }
-
- GPIO_OSPEEDR(gpioport) = ospeedr;
-}
-
-void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios)
-{
- u16 i;
- u32 afrl, afrh;
-
- afrl = GPIO_AFRL(gpioport);
- afrh = GPIO_AFRH(gpioport);
-
- for (i = 0; i < 8; i++) {
- if (!((1 << i) & gpios))
- continue;
- afrl &= ~GPIO_AFR_MASK(i);
- afrl |= GPIO_AFR(i, alt_func_num);
- }
-
- for (i = 8; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
- afrl &= ~GPIO_AFR_MASK(i - 8);
- afrh |= GPIO_AFR(i - 8, alt_func_num);
- }
-
- GPIO_AFRL(gpioport) = afrl;
- GPIO_AFRH(gpioport) = afrh;
-}
-
-void gpio_set(u32 gpioport, u16 gpios)
-{
- GPIO_BSRR(gpioport) = gpios;
-}
-
-void gpio_clear(u32 gpioport, u16 gpios)
-{
- GPIO_BSRR(gpioport) = gpios << 16;
-}
-
-u16 gpio_get(u32 gpioport, u16 gpios)
-{
- return gpio_port_read(gpioport) & gpios;
-}
-
-void gpio_toggle(u32 gpioport, u16 gpios)
-{
- GPIO_ODR(gpioport) ^= gpios;
-}
-
-u16 gpio_port_read(u32 gpioport)
-{
- return (u16)GPIO_IDR(gpioport);
-}
-
-void gpio_port_write(u32 gpioport, u16 data)
-{
- GPIO_ODR(gpioport) = data;
-}
-
-void gpio_port_config_lock(u32 gpioport, u16 gpios)
-{
- u32 reg32;
-
- /* Special "Lock Key Writing Sequence", see datasheet. */
- GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
- GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */
- GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
- reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */
- reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */
-
- /* Tell the compiler the variable is actually used. It will get optimized out anyways. */
- reg32 = reg32;
-
- /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */
-}
diff --git a/lib/stm32/f4/timer.c b/lib/stm32/f4/timer.c
deleted file mode 100644
index 6d5ab9d..0000000
--- a/lib/stm32/f4/timer.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org>
- * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
- *
- * 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/>.
- */
-
-/*
- * Basic TIMER handling API.
- *
- * Examples:
- * timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT_MUL_2,
- * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP);
- */
-
-#include <libopencm3/stm32/f4/timer.h>
-#include <libopencm3/stm32/f4/rcc.h>
-
-void timer_reset(u32 timer_peripheral)
-{
- switch (timer_peripheral) {
- case TIM1:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST);
- break;
- case TIM2:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST);
- break;
- case TIM3:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST);
- break;
- case TIM4:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST);
- break;
- case TIM5:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST);
- break;
- case TIM6:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST);
- break;
- case TIM7:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST);
- break;
- case TIM8:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST);
- break;
-/* These timers are not supported in libopencm3 yet */
-/*
- case TIM9:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST);
- break;
- case TIM10:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST);
- break;
- case TIM11:
- rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST);
- rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST);
- break;
- case TIM12:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST);
- break;
- case TIM13:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST);
- break;
- case TIM14:
- rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST);
- rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST);
- break;
-*/
- }
-}
-
-void timer_enable_irq(u32 timer_peripheral, u32 irq)
-{
- TIM_DIER(timer_peripheral) |= irq;
-}
-
-void timer_disable_irq(u32 timer_peripheral, u32 irq)
-{
- TIM_DIER(timer_peripheral) &= ~irq;
-}
-
-bool timer_get_flag(u32 timer_peripheral, u32 flag)
-{
- if (((TIM_SR(timer_peripheral) & flag) != 0) &&
- ((TIM_DIER(timer_peripheral) & flag) != 0)) {
- return true;
- }
-
- return false;
-}
-
-void timer_clear_flag(u32 timer_peripheral, u32 flag)
-{
- TIM_SR(timer_peripheral) &= ~flag;
-}
-
-void timer_set_mode(u32 timer_peripheral, u32 clock_div,
- u32 alignment, u32 direction)
-{
- u32 cr1;
-
- cr1 = TIM_CR1(timer_peripheral);
-
- cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | TIM_CR1_CMS_MASK | TIM_CR1_DIR_DOWN);
-
- cr1 |= clock_div | alignment | direction;
-
- TIM_CR1(timer_peripheral) = cr1;
-}
-
-void timer_set_clock_division(u32 timer_peripheral, u32 clock_div)
-{
- clock_div &= TIM_CR1_CKD_CK_INT_MASK;
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK;
- TIM_CR1(timer_peripheral) |= clock_div;
-}
-
-void timer_enable_preload(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE;
-}
-
-void timer_disable_preload(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE;
-}
-
-void timer_set_alignment(u32 timer_peripheral, u32 alignment)
-{
- alignment &= TIM_CR1_CMS_MASK;
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK;
- TIM_CR1(timer_peripheral) |= alignment;
-}
-
-void timer_direction_up(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN;
-}
-
-void timer_direction_down(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN;
-}
-
-void timer_one_shot_mode(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_OPM;
-}
-
-void timer_continuous_mode(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM;
-}
-
-void timer_update_on_any(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS;
-}
-
-void timer_update_on_overflow(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_URS;
-}
-
-void timer_enable_update_event(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS;
-}
-
-void timer_disable_update_event(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS;
-}
-
-void timer_enable_counter(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) |= TIM_CR1_CEN;
-}
-
-void timer_disable_counter(u32 timer_peripheral)
-{
- TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN;
-}
-
-void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs)
-{
- TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK;
-}
-
-void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs)
-{
- TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK);
-}
-
-void timer_set_ti1_ch123_xor(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S;
-}
-
-void timer_set_ti1_ch1(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S;
-}
-
-void timer_set_master_mode(u32 timer_peripheral, u32 mode)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK;
- TIM_CR2(timer_peripheral) |= mode;
-}
-
-void timer_set_dma_on_compare_event(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS;
-}
-
-void timer_set_dma_on_update_event(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS;
-}
-
-void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS;
-}
-
-void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS;
-}
-
-void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC;
-}
-
-void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral)
-{
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC;
-}
-
-void timer_set_prescaler(u32 timer_peripheral, u32 value)
-{
- TIM_PSC(timer_peripheral) = value;
-}
-
-void timer_set_repetition_counter(u32 timer_peripheral, u32 value)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_RCR(timer_peripheral) = value;
-}
-
-void timer_set_period(u32 timer_peripheral, u32 period)
-{
- TIM_ARR(timer_peripheral) = period;
-}
-
-void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as fast enable only applies to the whole channel. */
- break;
- }
-}
-
-void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as fast enable only applies to the whole channel. */
- break;
- }
-}
-
-void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as fast enable only applies to the whole channel. */
- break;
- }
-}
-
-void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id,
- enum tim_oc_mode oc_mode)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK;
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT;
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK;
- switch (oc_mode) {
- case TIM_OCM_FROZEN:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FROZEN;
- break;
- case TIM_OCM_ACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_ACTIVE;
- break;
- case TIM_OCM_INACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_INACTIVE;
- break;
- case TIM_OCM_TOGGLE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_TOGGLE;
- break;
- case TIM_OCM_FORCE_LOW:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_LOW;
- break;
- case TIM_OCM_FORCE_HIGH:
- TIM_CCMR1(timer_peripheral) |=
- TIM_CCMR1_OC1M_FORCE_HIGH;
- break;
- case TIM_OCM_PWM1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM1;
- break;
- case TIM_OCM_PWM2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM2;
- break;
- }
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK;
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT;
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK;
- switch (oc_mode) {
- case TIM_OCM_FROZEN:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FROZEN;
- break;
- case TIM_OCM_ACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_ACTIVE;
- break;
- case TIM_OCM_INACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_INACTIVE;
- break;
- case TIM_OCM_TOGGLE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_TOGGLE;
- break;
- case TIM_OCM_FORCE_LOW:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_LOW;
- break;
- case TIM_OCM_FORCE_HIGH:
- TIM_CCMR1(timer_peripheral) |=
- TIM_CCMR1_OC2M_FORCE_HIGH;
- break;
- case TIM_OCM_PWM1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM1;
- break;
- case TIM_OCM_PWM2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM2;
- break;
- }
- break;
- case TIM_OC3:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK;
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC3S_OUT;
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK;
- switch (oc_mode) {
- case TIM_OCM_FROZEN:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FROZEN;
- break;
- case TIM_OCM_ACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC3M_ACTIVE;
- break;
- case TIM_OCM_INACTIVE:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_INACTIVE;
- break;
- case TIM_OCM_TOGGLE:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_TOGGLE;
- break;
- case TIM_OCM_FORCE_LOW:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_LOW;
- break;
- case TIM_OCM_FORCE_HIGH:
- TIM_CCMR2(timer_peripheral) |=
- TIM_CCMR2_OC3M_FORCE_HIGH;
- break;
- case TIM_OCM_PWM1:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM1;
- break;
- case TIM_OCM_PWM2:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM2;
- break;
- }
- break;
- case TIM_OC4:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK;
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC4S_OUT;
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK;
- switch (oc_mode) {
- case TIM_OCM_FROZEN:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FROZEN;
- break;
- case TIM_OCM_ACTIVE:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC4M_ACTIVE;
- break;
- case TIM_OCM_INACTIVE:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_INACTIVE;
- break;
- case TIM_OCM_TOGGLE:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_TOGGLE;
- break;
- case TIM_OCM_FORCE_LOW:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_LOW;
- break;
- case TIM_OCM_FORCE_HIGH:
- TIM_CCMR2(timer_peripheral) |=
- TIM_CCMR2_OC4M_FORCE_HIGH;
- break;
- case TIM_OCM_PWM1:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM1;
- break;
- case TIM_OCM_PWM2:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM2;
- break;
- }
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE;
- break;
- case TIM_OC2:
- TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE;
- break;
- case TIM_OC3:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE;
- break;
- case TIM_OC4:
- TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P;
- break;
- case TIM_OC2:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P;
- break;
- case TIM_OC3:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P;
- break;
- case TIM_OC4:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to TIM1 and TIM8 only. */
- break;
- }
-
- /* Acting for TIM1 and TIM8 only from here onwards. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP;
- break;
- case TIM_OC2N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP;
- break;
- case TIM_OC3N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP;
- break;
- case TIM_OC1:
- case TIM_OC2:
- case TIM_OC3:
- case TIM_OC4:
- /* Ignoring as this option was already set above. */
- break;
- }
-}
-
-void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P;
- break;
- case TIM_OC2:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P;
- break;
- case TIM_OC3:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P;
- break;
- case TIM_OC4:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to TIM1 and TIM8 only. */
- break;
- }
-
- /* Acting for TIM1 and TIM8 only from here onwards. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP;
- break;
- case TIM_OC2N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP;
- break;
- case TIM_OC3N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP;
- break;
- case TIM_OC1:
- case TIM_OC2:
- case TIM_OC3:
- case TIM_OC4:
- /* Ignoring as this option was already set above. */
- break;
- }
-}
-
-void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E;
- break;
- case TIM_OC2:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E;
- break;
- case TIM_OC3:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E;
- break;
- case TIM_OC4:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to TIM1 and TIM8 only. */
- break;
- }
-
- /* Acting for TIM1 and TIM8 only from here onwards. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE;
- break;
- case TIM_OC2N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE;
- break;
- case TIM_OC3N:
- TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE;
- break;
- case TIM_OC1:
- case TIM_OC2:
- case TIM_OC3:
- case TIM_OC4:
- /* Ignoring as this option was already set above. */
- break;
- }
-}
-
-void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E;
- break;
- case TIM_OC2:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E;
- break;
- case TIM_OC3:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E;
- break;
- case TIM_OC4:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to TIM1 and TIM8 only. */
- break;
- }
-
- /* Acting for TIM1 and TIM8 only from here onwards. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE;
- break;
- case TIM_OC2N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE;
- break;
- case TIM_OC3N:
- TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE;
- break;
- case TIM_OC1:
- case TIM_OC2:
- case TIM_OC3:
- case TIM_OC4:
- /* Ignoring as this option was already set above. */
- break;
- }
-}
-
-void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- /* Acting for TIM1 and TIM8 only. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1;
- break;
- case TIM_OC1N:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N;
- break;
- case TIM_OC2:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2;
- break;
- case TIM_OC2N:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N;
- break;
- case TIM_OC3:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3;
- break;
- case TIM_OC3N:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N;
- break;
- case TIM_OC4:
- TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4;
- break;
- }
-}
-
-void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id)
-{
- /* Acting for TIM1 and TIM8 only. */
- if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
- return;
-
- switch (oc_id) {
- case TIM_OC1:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1;
- break;
- case TIM_OC1N:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N;
- break;
- case TIM_OC2:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2;
- break;
- case TIM_OC2N:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N;
- break;
- case TIM_OC3:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3;
- break;
- case TIM_OC3N:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N;
- break;
- case TIM_OC4:
- TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4;
- break;
- }
-}
-
-void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value)
-{
- switch (oc_id) {
- case TIM_OC1:
- TIM_CCR1(timer_peripheral) = value;
- break;
- case TIM_OC2:
- TIM_CCR2(timer_peripheral) = value;
- break;
- case TIM_OC3:
- TIM_CCR3(timer_peripheral) = value;
- break;
- case TIM_OC4:
- TIM_CCR4(timer_peripheral) = value;
- break;
- case TIM_OC1N:
- case TIM_OC2N:
- case TIM_OC3N:
- /* Ignoring as this option applies to the whole channel. */
- break;
- }
-}
-
-void timer_enable_break_main_output(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE;
-}
-
-void timer_disable_break_main_output(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE;
-}
-
-void timer_enable_break_automatic_output(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE;
-}
-
-void timer_disable_break_automatic_output(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE;
-}
-
-void timer_set_break_polarity_high(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP;
-}
-
-void timer_set_break_polarity_low(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP;
-}
-
-void timer_enable_break(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE;
-}
-
-void timer_disable_break(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE;
-}
-
-void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR;
-}
-
-void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR;
-}
-
-void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI;
-}
-
-void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI;
-}
-
-void timer_set_break_lock(u32 timer_peripheral, u32 lock)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= lock;
-}
-
-void timer_set_deadtime(u32 timer_peripheral, u32 deadtime)
-{
- if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
- TIM_BDTR(timer_peripheral) |= deadtime;
-}
-
-void timer_generate_event(u32 timer_peripheral, u32 event)
-{
- TIM_EGR(timer_peripheral) |= event;
-}
-
-u32 timer_get_counter(u32 timer_peripheral)
-{
- return TIM_CNT(timer_peripheral);
-}
-
-void timer_set_option(u32 timer_peripheral, u32 option)
-{
- if (timer_peripheral == TIM2) {
- TIM_OR(timer_peripheral) &= ~TIM2_OR_ITR1_RMP_MASK;
- TIM_OR(timer_peripheral) |= option;
- } else if (timer_peripheral == TIM5) {
- TIM_OR(timer_peripheral) &= ~TIM5_OR_TI4_RMP_MASK;
- TIM_OR(timer_peripheral) |= option;
- }
-}
diff --git a/lib/stm32/f4/vector.c b/lib/stm32/f4/vector.c
deleted file mode 100644
index 01b5e64..0000000
--- a/lib/stm32/f4/vector.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
- * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
- *
- * 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/stm32/f4/scb.h>
-
-#define WEAK __attribute__ ((weak))
-
-/* Symbols exported by the linker script(s): */
-extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack;
-
-void main(void);
-void reset_handler(void);
-void blocking_handler(void);
-void null_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 wwdg_isr(void);
-void WEAK pvd_isr(void);
-void WEAK tamp_stamp_isr(void);
-void WEAK rtc_wkup_isr(void);
-void WEAK flash_isr(void);
-void WEAK rcc_isr(void);
-void WEAK exti0_isr(void);
-void WEAK exti1_isr(void);
-void WEAK exti2_isr(void);
-void WEAK exti3_isr(void);
-void WEAK exti4_isr(void);
-void WEAK dma1_stream0_isr(void);
-void WEAK dma1_stream1_isr(void);
-void WEAK dma1_stream2_isr(void);
-void WEAK dma1_stream3_isr(void);
-void WEAK dma1_stream4_isr(void);
-void WEAK dma1_stream5_isr(void);
-void WEAK dma1_stream6_isr(void);
-void WEAK adc_isr(void);
-void WEAK can1_tx_isr(void);
-void WEAK can1_rx0_isr(void);
-void WEAK can1_rx1_isr(void);
-void WEAK can1_sce_isr(void);
-void WEAK exti9_5_isr(void);
-void WEAK tim1_brk_tim9_isr(void);
-void WEAK tim1_up_tim10_isr(void);
-void WEAK tim1_trg_com_tim11_isr(void);
-void WEAK tim1_cc_isr(void);
-void WEAK tim2_isr(void);
-void WEAK tim3_isr(void);
-void WEAK tim4_isr(void);
-void WEAK i2c1_ev_isr(void);
-void WEAK i2c1_er_isr(void);
-void WEAK i2c2_ev_isr(void);
-void WEAK i2c2_er_isr(void);
-void WEAK spi1_isr(void);
-void WEAK spi2_isr(void);
-void WEAK usart1_isr(void);
-void WEAK usart2_isr(void);
-void WEAK usart3_isr(void);
-void WEAK exti15_10_isr(void);
-void WEAK rtc_alarm_isr(void);
-void WEAK usb_fs_wkup_isr(void);
-void WEAK tim8_brk_tim12_isr(void);
-void WEAK tim8_up_tim13_isr(void);
-void WEAK tim8_trg_com_tim14_isr(void);
-void WEAK tim8_cc_isr(void);
-void WEAK dma1_stream7_isr(void);
-void WEAK fsmc_isr(void);
-void WEAK sdio_isr(void);
-void WEAK tim5_isr(void);
-void WEAK spi3_isr(void);
-void WEAK uart4_isr(void);
-void WEAK uart5_isr(void);
-void WEAK tim6_dac_isr(void);
-void WEAK tim7_isr(void);
-void WEAK dma2_stream0_isr(void);
-void WEAK dma2_stream1_isr(void);
-void WEAK dma2_stream2_isr(void);
-void WEAK dma2_stream3_isr(void);
-void WEAK dma2_stream4_isr(void);
-void WEAK eth_isr(void);
-void WEAK eth_wkup_isr(void);
-void WEAK can2_tx_isr(void);
-void WEAK can2_rx0_isr(void);
-void WEAK can2_rx1_isr(void);
-void WEAK can2_sce_isr(void);
-void WEAK otg_fs_isr(void);
-void WEAK dma2_stream5_isr(void);
-void WEAK dma2_stream6_isr(void);
-void WEAK dma2_stream7_isr(void);
-void WEAK usart6_isr(void);
-void WEAK i2c3_ev_isr(void);
-void WEAK i2c3_er_isr(void);
-void WEAK otg_hs_ep1_out_isr(void);
-void WEAK otg_hs_ep1_in_isr(void);
-void WEAK otg_hs_wkup_isr(void);
-void WEAK otg_hs_isr(void);
-void WEAK dcmi_isr(void);
-void WEAK cryp_isr(void);
-void WEAK hash_rng_isr(void);
-
-__attribute__ ((section(".vectors")))
-void (*const vector_table[]) (void) = {
- (void *)&_stack,
- reset_handler,
- nmi_handler,
- hard_fault_handler,
- mem_manage_handler,
- bus_fault_handler,
- usage_fault_handler,
- 0, 0, 0, 0, /* Reserved */
- sv_call_handler,
- debug_monitor_handler,
- 0, /* Reserved */
- pend_sv_handler,
- sys_tick_handler,
- wwdg_isr,
- pvd_isr,
- tamp_stamp_isr,
- rtc_wkup_isr,
- flash_isr,
- rcc_isr,
- exti0_isr,
- exti1_isr,
- exti2_isr,
- exti3_isr,
- exti4_isr,
- dma1_stream0_isr,
- dma1_stream1_isr,
- dma1_stream2_isr,
- dma1_stream3_isr,
- dma1_stream4_isr,
- dma1_stream5_isr,
- dma1_stream6_isr,
- adc_isr,
- can1_tx_isr,
- can1_rx0_isr,
- can1_rx1_isr,
- can1_sce_isr,
- exti9_5_isr,
- tim1_brk_tim9_isr,
- tim1_up_tim10_isr,
- tim1_trg_com_tim11_isr,
- tim1_cc_isr,
- tim2_isr,
- tim3_isr,
- tim4_isr,
- i2c1_ev_isr,
- i2c1_er_isr,
- i2c2_ev_isr,
- i2c2_er_isr,
- spi1_isr,
- spi2_isr,
- usart1_isr,
- usart2_isr,
- usart3_isr,
- exti15_10_isr,
- rtc_alarm_isr,
- usb_fs_wkup_isr,
- tim8_brk_tim12_isr,
- tim8_up_tim13_isr,
- tim8_trg_com_tim14_isr,
- tim8_cc_isr,
- dma1_stream7_isr,
- fsmc_isr,
- sdio_isr,
- tim5_isr,
- spi3_isr,
- uart4_isr,
- uart5_isr,
- tim6_dac_isr,
- tim7_isr,
- dma2_stream0_isr,
- dma2_stream1_isr,
- dma2_stream2_isr,
- dma2_stream3_isr,
- dma2_stream4_isr,
- eth_isr,
- eth_wkup_isr,
- can2_tx_isr,
- can2_rx0_isr,
- can2_rx1_isr,
- can2_sce_isr,
- otg_fs_isr,
- dma2_stream5_isr,
- dma2_stream6_isr,
- dma2_stream7_isr,
- usart6_isr,
- i2c3_ev_isr,
- i2c3_er_isr,
- otg_hs_ep1_out_isr,
- otg_hs_ep1_in_isr,
- otg_hs_wkup_isr,
- otg_hs_isr,
- dcmi_isr,
- cryp_isr,
- hash_rng_isr,
-};
-
-void reset_handler(void)
-{
- volatile unsigned *src, *dest;
-
- __asm__("MSR msp, %0" : : "r"(&_stack));
-
- /* Enable access to Floating-Point coprocessor. */
- SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11);
-
- for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++)
- *dest = *src;
-
- while (dest < &_ebss)
- *dest++ = 0;
-
- /* Call the application's entry point. */
- main();
-}
-
-void blocking_handler(void)
-{
- while (1) ;
-}
-
-void null_handler(void)
-{
- /* Do nothing. */
-}
-
-#pragma weak nmi_handler = null_handler
-#pragma weak hard_fault_handler = blocking_handler
-#pragma weak mem_manage_handler = blocking_handler
-#pragma weak bus_fault_handler = blocking_handler
-#pragma weak usage_fault_handler = blocking_handler
-#pragma weak sv_call_handler = null_handler
-#pragma weak debug_monitor_handler = null_handler
-#pragma weak pend_sv_handler = null_handler
-#pragma weak sys_tick_handler = null_handler
-#pragma weak wwdg_isr = null_handler
-#pragma weak pvd_isr = null_handler
-#pragma weak tamp_stamp_isr = null_handler
-#pragma weak rtc_wkup_isr = null_handler
-#pragma weak flash_isr = null_handler
-#pragma weak rcc_isr = null_handler
-#pragma weak exti0_isr = null_handler
-#pragma weak exti1_isr = null_handler
-#pragma weak exti2_isr = null_handler
-#pragma weak exti3_isr = null_handler
-#pragma weak exti4_isr = null_handler
-#pragma weak dma1_stream0_isr = null_handler
-#pragma weak dma1_stream1_isr = null_handler
-#pragma weak dma1_stream2_isr = null_handler
-#pragma weak dma1_stream3_isr = null_handler
-#pragma weak dma1_stream4_isr = null_handler
-#pragma weak dma1_stream5_isr = null_handler
-#pragma weak dma1_stream6_isr = null_handler
-#pragma weak adc_isr = null_handler
-#pragma weak can1_tx_isr = null_handler
-#pragma weak can1_rx0_isr = null_handler
-#pragma weak can1_rx1_isr = null_handler
-#pragma weak can1_sce_isr = null_handler
-#pragma weak exti9_5_isr = null_handler
-#pragma weak tim1_brk_tim9_isr = null_handler
-#pragma weak tim1_up_tim10_isr = null_handler
-#pragma weak tim1_trg_com_tim11_isr = null_handler
-#pragma weak tim1_cc_isr = null_handler
-#pragma weak tim2_isr = null_handler
-#pragma weak tim3_isr = null_handler
-#pragma weak tim4_isr = null_handler
-#pragma weak i2c1_ev_isr = null_handler
-#pragma weak i2c1_er_isr = null_handler
-#pragma weak i2c2_ev_isr = null_handler
-#pragma weak i2c2_er_isr = null_handler
-#pragma weak spi1_isr = null_handler
-#pragma weak spi2_isr = null_handler
-#pragma weak usart1_isr = null_handler
-#pragma weak usart2_isr = null_handler
-#pragma weak usart3_isr = null_handler
-#pragma weak exti15_10_isr = null_handler
-#pragma weak rtc_alarm_isr = null_handler
-#pragma weak usb_fs_wkup_isr = null_handler
-#pragma weak tim8_brk_tim12_isr = null_handler
-#pragma weak tim8_up_tim13_isr = null_handler
-#pragma weak tim8_trg_com_tim14_isr = null_handler
-#pragma weak tim8_cc_isr = null_handler
-#pragma weak dma1_stream7_isr = null_handler
-#pragma weak fsmc_isr = null_handler
-#pragma weak sdio_isr = null_handler
-#pragma weak tim5_isr = null_handler
-#pragma weak spi3_isr = null_handler
-#pragma weak uart4_isr = null_handler
-#pragma weak uart5_isr = null_handler
-#pragma weak tim6_dac_isr = null_handler
-#pragma weak tim7_isr = null_handler
-#pragma weak dma2_stream0_isr = null_handler
-#pragma weak dma2_stream1_isr = null_handler
-#pragma weak dma2_stream2_isr = null_handler
-#pragma weak dma2_stream3_isr = null_handler
-#pragma weak dma2_stream4_isr = null_handler
-#pragma weak eth_isr = null_handler
-#pragma weak eth_wkup_isr = null_handler
-#pragma weak can2_tx_isr = null_handler
-#pragma weak can2_rx0_isr = null_handler
-#pragma weak can2_rx1_isr = null_handler
-#pragma weak can2_sce_isr = null_handler
-#pragma weak otg_fs_isr = null_handler
-#pragma weak dma2_stream5_isr = null_handler
-#pragma weak dma2_stream6_isr = null_handler
-#pragma weak dma2_stream7_isr = null_handler
-#pragma weak usart6_isr = null_handler
-#pragma weak i2c3_ev_isr = null_handler
-#pragma weak i2c3_er_isr = null_handler
-#pragma weak otg_hs_ep1_out_isr = null_handler
-#pragma weak otg_hs_ep1_in_isr = null_handler
-#pragma weak otg_hs_wkup_isr = null_handler
-#pragma weak otg_hs_isr = null_handler
-#pragma weak dcmi_isr = null_handler
-#pragma weak cryp_isr = null_handler
-#pragma weak hash_rng_isr = null_handler
diff --git a/lib/stm32/f4/vector_chipset.c b/lib/stm32/f4/vector_chipset.c
new file mode 100644
index 0000000..145be05
--- /dev/null
+++ b/lib/stm32/f4/vector_chipset.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
+ * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
+ *
+ * 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/cm3/scb.h>
+
+static void pre_main(void)
+{
+ /* Enable access to Floating-Point coprocessor. */
+ SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11);
+}
diff --git a/lib/stm32/f2/gpio.c b/lib/stm32/gpio2.c
index 984cddb..c185e98 100644
--- a/lib/stm32/f2/gpio.c
+++ b/lib/stm32/gpio2.c
@@ -17,7 +17,15 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#if defined(STM32F2)
#include <libopencm3/stm32/f2/gpio.h>
+#elif defined(STM32F4)
+#include <libopencm3/stm32/f4/gpio.h>
+#elif defined(STM32L1)
+#include <libopencm3/stm32/l1/gpio.h>
+#else
+#error "invalid/unknown stm32 family for this code"
+#endif
void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios)
{
@@ -86,7 +94,7 @@ void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios)
for (i = 8; i < 16; i++) {
if (!((1 << i) & gpios))
continue;
- afrl &= ~GPIO_AFR_MASK(i - 8);
+ afrh &= ~GPIO_AFR_MASK(i - 8);
afrh |= GPIO_AFR(i - 8, alt_func_num);
}
diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile
new file mode 100644
index 0000000..9e07b2d
--- /dev/null
+++ b/lib/stm32/l1/Makefile
@@ -0,0 +1,36 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## 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_stm32l1
+
+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 -DSTM32L1
+# ARFLAGS = rcsv
+ARFLAGS = rcs
+OBJS = rcc.o gpio2.o desig.o crc.o usart.o exti2.o
+
+VPATH += ../../usb:../:../../cm3
+
+include ../../Makefile.include
+
diff --git a/lib/stm32/l1/libopencm3_stm32l1.ld b/lib/stm32/l1/libopencm3_stm32l1.ld
new file mode 100644
index 0000000..9d165f6
--- /dev/null
+++ b/lib/stm32/l1/libopencm3_stm32l1.ld
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * 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 STM32 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
+{
+ .text : {
+ *(.vectors) /* Vector table */
+ *(.text*) /* Program code */
+ . = ALIGN(4);
+ *(.rodata*) /* Read-only data */
+ . = ALIGN(4);
+ } >rom
+
+ /*
+ * Another section used by C++ stuff, appears when using newlib with
+ * 64bit (long long) printf support
+ */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >rom
+ .ARM.exidx : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >rom
+
+ . = ALIGN(4);
+ _etext = .;
+
+ .data : {
+ _data = .;
+ *(.data*) /* Read-write initialized data */
+ . = ALIGN(4);
+ _edata = .;
+ } >ram AT >rom
+ _data_loadaddr = LOADADDR(.data);
+
+ .bss : {
+ *(.bss*) /* Read-write zero initialized data */
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram
+
+ /*
+ * 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) }
+
+ . = ALIGN(4);
+ end = .;
+}
+
+PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
+
diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c
new file mode 100644
index 0000000..a023622
--- /dev/null
+++ b/lib/stm32/l1/rcc.c
@@ -0,0 +1,357 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Federico Ruiz-Ugalde <memeruiz at gmail dot com>
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
+ *
+ * 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/>.
+ * Based on the F4 code...
+ */
+
+#include <libopencm3/stm32/l1/rcc.h>
+
+/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset. */
+u32 rcc_ppre1_frequency = 2097000;
+u32 rcc_ppre2_frequency = 2097000;
+
+void rcc_osc_ready_int_clear(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CIR |= RCC_CIR_PLLRDYC;
+ break;
+ case HSE:
+ RCC_CIR |= RCC_CIR_HSERDYC;
+ break;
+ case HSI:
+ RCC_CIR |= RCC_CIR_HSIRDYC;
+ break;
+ case LSE:
+ RCC_CIR |= RCC_CIR_LSERDYC;
+ break;
+ case LSI:
+ RCC_CIR |= RCC_CIR_LSIRDYC;
+ break;
+ case MSI:
+ RCC_CIR |= RCC_CIR_MSIRDYC;
+ break;
+ }
+}
+
+void rcc_osc_ready_int_enable(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CIR |= RCC_CIR_PLLRDYIE;
+ break;
+ case HSE:
+ RCC_CIR |= RCC_CIR_HSERDYIE;
+ break;
+ case HSI:
+ RCC_CIR |= RCC_CIR_HSIRDYIE;
+ break;
+ case LSE:
+ RCC_CIR |= RCC_CIR_LSERDYIE;
+ break;
+ case LSI:
+ RCC_CIR |= RCC_CIR_LSIRDYIE;
+ break;
+ case MSI:
+ RCC_CIR |= RCC_CIR_MSIRDYIE;
+ break;
+ }
+}
+
+void rcc_osc_ready_int_disable(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CIR &= ~RCC_CIR_PLLRDYIE;
+ break;
+ case HSE:
+ RCC_CIR &= ~RCC_CIR_HSERDYIE;
+ break;
+ case HSI:
+ RCC_CIR &= ~RCC_CIR_HSIRDYIE;
+ break;
+ case LSE:
+ RCC_CIR &= ~RCC_CIR_LSERDYIE;
+ break;
+ case LSI:
+ RCC_CIR &= ~RCC_CIR_LSIRDYIE;
+ break;
+ case MSI:
+ RCC_CIR &= ~RCC_CIR_MSIRDYIE;
+ break;
+ }
+}
+
+int rcc_osc_ready_int_flag(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
+ break;
+ case HSE:
+ return ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
+ break;
+ case HSI:
+ return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0);
+ break;
+ case LSE:
+ return ((RCC_CIR & RCC_CIR_LSERDYF) != 0);
+ break;
+ case LSI:
+ return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0);
+ break;
+ case MSI:
+ return ((RCC_CIR & RCC_CIR_MSIRDYF) != 0);
+ break;
+ }
+
+ /* Shouldn't be reached. */
+ return -1;
+}
+
+void rcc_css_int_clear(void)
+{
+ RCC_CIR |= RCC_CIR_CSSC;
+}
+
+int rcc_css_int_flag(void)
+{
+ return ((RCC_CIR & RCC_CIR_CSSF) != 0);
+}
+
+void rcc_wait_for_osc_ready(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ while ((RCC_CR & RCC_CR_PLLRDY) == 0);
+ break;
+ case HSE:
+ while ((RCC_CR & RCC_CR_HSERDY) == 0);
+ break;
+ case HSI:
+ while ((RCC_CR & RCC_CR_HSIRDY) == 0);
+ break;
+ case MSI:
+ while ((RCC_CR & RCC_CR_MSIRDY) == 0);
+ break;
+ case LSE:
+ while ((RCC_CSR & RCC_CSR_LSERDY) == 0);
+ break;
+ case LSI:
+ while ((RCC_CSR & RCC_CSR_LSIRDY) == 0);
+ break;
+ }
+}
+
+void rcc_wait_for_sysclk_status(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_PLLCLK);
+ break;
+ case HSE:
+ while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_HSECLK);
+ break;
+ case HSI:
+ while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_HSICLK);
+ break;
+ case MSI:
+ while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_MSICLK);
+ break;
+ default:
+ /* Shouldn't be reached. */
+ break;
+ }
+}
+
+void rcc_osc_on(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CR |= RCC_CR_PLLON;
+ break;
+ case MSI:
+ RCC_CR |= RCC_CR_MSION;
+ break;
+ case HSE:
+ RCC_CR |= RCC_CR_HSEON;
+ break;
+ case HSI:
+ RCC_CR |= RCC_CR_HSION;
+ break;
+ case LSE:
+ RCC_CSR |= RCC_CSR_LSEON;
+ break;
+ case LSI:
+ RCC_CSR |= RCC_CSR_LSION;
+ break;
+ }
+}
+
+void rcc_osc_off(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CR &= ~RCC_CR_PLLON;
+ break;
+ case MSI:
+ RCC_CR &= ~RCC_CR_MSION;
+ break;
+ case HSE:
+ RCC_CR &= ~RCC_CR_HSEON;
+ break;
+ case HSI:
+ RCC_CR &= ~RCC_CR_HSION;
+ break;
+ case LSE:
+ RCC_CSR &= ~RCC_CSR_LSEON;
+ break;
+ case LSI:
+ RCC_CSR &= ~RCC_CSR_LSION;
+ break;
+ }
+}
+
+void rcc_css_enable(void)
+{
+ RCC_CR |= RCC_CR_CSSON;
+}
+
+void rcc_css_disable(void)
+{
+ RCC_CR &= ~RCC_CR_CSSON;
+}
+
+void rcc_osc_bypass_enable(osc_t osc)
+{
+ switch (osc) {
+ case HSE:
+ RCC_CR |= RCC_CR_HSEBYP;
+ break;
+ case LSE:
+ RCC_CSR |= RCC_CSR_LSEBYP;
+ break;
+ case PLL:
+ case HSI:
+ case LSI:
+ case MSI:
+ /* Do nothing, only HSE/LSE allowed here. */
+ break;
+ }
+}
+
+void rcc_osc_bypass_disable(osc_t osc)
+{
+ switch (osc) {
+ case HSE:
+ RCC_CR &= ~RCC_CR_HSEBYP;
+ break;
+ case LSE:
+ RCC_CSR &= ~RCC_CSR_LSEBYP;
+ break;
+ case PLL:
+ case HSI:
+ case LSI:
+ case MSI:
+ /* Do nothing, only HSE/LSE allowed here. */
+ break;
+ }
+}
+
+void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en)
+{
+ *reg |= en;
+}
+
+void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en)
+{
+ *reg &= ~en;
+}
+
+void rcc_peripheral_reset(volatile u32 *reg, u32 reset)
+{
+ *reg |= reset;
+}
+
+void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset)
+{
+ *reg &= ~clear_reset;
+}
+
+void rcc_set_sysclk_source(u32 clk)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~((1 << 1) | (1 << 0));
+ RCC_CFGR = (reg32 | clk);
+}
+
+void rcc_set_pll_source(u32 pllsrc)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~(1 << 16);
+ RCC_CFGR = (reg32 | (pllsrc << 16));
+}
+
+void rcc_set_ppre2(u32 ppre2)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~((1 << 13) | (1 << 12) | (1 << 11));
+ RCC_CFGR = (reg32 | (ppre2 << 11));
+}
+
+void rcc_set_ppre1(u32 ppre1)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~((1 << 10) | (1 << 9) | (1 << 8));
+ RCC_CFGR = (reg32 | (ppre1 << 8));
+}
+
+void rcc_set_hpre(u32 hpre)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
+ RCC_CFGR = (reg32 | (hpre << 4));
+}
+
+void rcc_set_rtcpre(u32 rtcpre)
+{
+ u32 reg32;
+
+ reg32 = RCC_CR;
+ reg32 &= ~((1 << 30) | (1 << 29));
+ RCC_CR = (reg32 | (rtcpre << 29));
+}
+
+u32 rcc_system_clock_source(void)
+{
+ /* Return the clock source which is used as system clock. */
+ return ((RCC_CFGR & 0x000c) >> 2);
+}
+
diff --git a/lib/stm32/f1/scb.c b/lib/stm32/l1/stm32l15xx8.ld
index e59134e..1f20f57 100644
--- a/lib/stm32/f1/scb.c
+++ b/lib/stm32/l1/stm32l15xx8.ld
@@ -1,7 +1,7 @@
/*
* This file is part of the libopencm3 project.
*
- * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au
*
* 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
@@ -17,19 +17,15 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libopencm3/stm32/f1/scb.h>
+/* Linker script for STM32L15xx8, 64K flash, 10K RAM. */
-void scb_reset_core(void)
+/* Define memory regions. */
+MEMORY
{
- SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_VECTRESET;
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
}
-void scb_reset_system(void)
-{
- SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ;
-}
+/* Include the common ld script. */
+INCLUDE libopencm3_stm32l1.ld
-void scb_set_priority_grouping(u32 prigroup)
-{
- SCB_AIRCR = SCB_AIRCR_VECTKEY | prigroup;
-}
diff --git a/lib/stm32/l1/stm32l15xxb.ld b/lib/stm32/l1/stm32l15xxb.ld
new file mode 100644
index 0000000..4c14b71
--- /dev/null
+++ b/lib/stm32/l1/stm32l15xxb.ld
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au
+ *
+ * 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/>.
+ */
+
+/* Linker script for STM32L15xxB, 128K flash, 16K RAM. */
+
+/* Define memory regions. */
+MEMORY
+{
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
+}
+
+/* Include the common ld script. */
+INCLUDE libopencm3_stm32l1.ld
+
diff --git a/lib/stm32/f1/timer.c b/lib/stm32/timer.c
index 384eaaf..a5cf99d 100644
--- a/lib/stm32/f1/timer.c
+++ b/lib/stm32/timer.c
@@ -2,7 +2,7 @@
@ingroup STM32F1xx
-@brief <b>libopencm3 STM32F1xx Timers</b>
+@brief <b>libopencm3 STM32 Timers</b>
@version 1.0.0
@@ -11,9 +11,9 @@
@date 18 August 2012
This library supports the General Purpose and Advanced Control Timers for
-the STM32F1xx series of ARM Cortex Microcontrollers by ST Microelectronics.
+the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics.
-The STM32F1xx series have four general purpose timers (2-5), while some have
+The STM32 series have four general purpose timers (2-5), while some have
an additional two advanced timers (1,8), and some have two basic timers (6,7).
Some of the larger devices have additional general purpose timers (9-14).
@@ -70,6 +70,7 @@ push-pull outputs where the PWM output will appear.
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org>
+ * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
*
* 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
@@ -96,7 +97,18 @@ push-pull outputs where the PWM output will appear.
/**@{*/
#include <libopencm3/stm32/timer.h>
-#include <libopencm3/stm32/f1/rcc.h>
+
+#if defined(STM32F1)
+# include <libopencm3/stm32/f1/rcc.h>
+#elif defined(STM32F2)
+# include <libopencm3/stm32/f2/timer.h>
+# include <libopencm3/stm32/f2/rcc.h>
+#elif defined(STM32F4)
+# include <libopencm3/stm32/f4/timer.h>
+# include <libopencm3/stm32/f4/rcc.h>
+#else
+# error "stm32 family not defined."
+#endif
/*---------------------------------------------------------------------------*/
/** @brief Reset a Timer.
@@ -1697,6 +1709,29 @@ u32 timer_get_counter(u32 timer_peripheral)
}
/*---------------------------------------------------------------------------*/
+/** @brief Set Timer Option
+
+Set timer options register on TIM2 or TIM5, used for oscillator calibration
+on TIM5 and trigger remapping on TIM2. Only available on F4 and F2.
+
+@param[in] timer_peripheral Unsigned int32. Timer register address base
+@returns Unsigned int32. Option flags.
+*/
+
+#if (defined(STM32F4) || defined(STM32F2))
+void timer_set_option(u32 timer_peripheral, u32 option)
+{
+ if (timer_peripheral == TIM2) {
+ TIM_OR(timer_peripheral) &= ~TIM2_OR_ITR1_RMP_MASK;
+ TIM_OR(timer_peripheral) |= option;
+ } else if (timer_peripheral == TIM5) {
+ TIM_OR(timer_peripheral) &= ~TIM5_OR_TI4_RMP_MASK;
+ TIM_OR(timer_peripheral) |= option;
+ }
+}
+#endif
+
+/*---------------------------------------------------------------------------*/
/** @brief Set Counter
Set the value of a timer's counter register contents.
diff --git a/lib/stm32/usart.c b/lib/stm32/usart.c
index 5cf861b..1faf486 100644
--- a/lib/stm32/usart.c
+++ b/lib/stm32/usart.c
@@ -46,6 +46,8 @@ LGPL License Terms @ref lgpl_license
# include <libopencm3/stm32/f2/rcc.h>
#elif defined(STM32F4)
# include <libopencm3/stm32/f4/rcc.h>
+#elif defined(STM32L1)
+# include <libopencm3/stm32/l1/rcc.h>
#else
# error "stm32 family not defined."
#endif
diff --git a/lib/usb/usb.c b/lib/usb/usb.c
index d5ec980..0799202 100644
--- a/lib/usb/usb.c
+++ b/lib/usb/usb.c
@@ -21,8 +21,6 @@
#include <libopencm3/usb/usbd.h>
#include "usb_private.h"
-struct _usbd_device _usbd_device;
-
u8 usbd_control_buffer[128] __attribute__((weak));
/**
@@ -43,106 +41,112 @@ u8 usbd_control_buffer[128] __attribute__((weak));
* @param strings TODO
* @return Zero on success (currently cannot fail).
*/
-int usbd_init(const usbd_driver *driver,
- const struct usb_device_descriptor *dev,
- const struct usb_config_descriptor *conf,
- const char **strings, int num_strings)
+usbd_device *usbd_init(const usbd_driver *driver,
+ const struct usb_device_descriptor *dev,
+ const struct usb_config_descriptor *conf,
+ const char **strings, int num_strings)
{
- _usbd_device.driver = driver;
- _usbd_device.desc = dev;
- _usbd_device.config = conf;
- _usbd_device.strings = strings;
- _usbd_device.num_strings = num_strings;
- _usbd_device.ctrl_buf = usbd_control_buffer;
- _usbd_device.ctrl_buf_len = sizeof(usbd_control_buffer);
+ usbd_device *usbd_dev;
+
+ usbd_dev = driver->init();
- _usbd_hw_init();
+ usbd_dev->driver = driver;
+ usbd_dev->desc = dev;
+ usbd_dev->config = conf;
+ usbd_dev->strings = strings;
+ usbd_dev->num_strings = num_strings;
+ usbd_dev->ctrl_buf = usbd_control_buffer;
+ usbd_dev->ctrl_buf_len = sizeof(usbd_control_buffer);
- _usbd_device.user_callback_ctr[0][USB_TRANSACTION_SETUP] =
+ usbd_dev->user_callback_ctr[0][USB_TRANSACTION_SETUP] =
_usbd_control_setup;
- _usbd_device.user_callback_ctr[0][USB_TRANSACTION_OUT] =
+ usbd_dev->user_callback_ctr[0][USB_TRANSACTION_OUT] =
_usbd_control_out;
- _usbd_device.user_callback_ctr[0][USB_TRANSACTION_IN] =
+ usbd_dev->user_callback_ctr[0][USB_TRANSACTION_IN] =
_usbd_control_in;
- return 0;
+ return usbd_dev;
}
-void usbd_register_reset_callback(void (*callback)(void))
+void usbd_register_reset_callback(usbd_device *usbd_dev, void (*callback)(void))
{
- _usbd_device.user_callback_reset = callback;
+ usbd_dev->user_callback_reset = callback;
}
-void usbd_register_suspend_callback(void (*callback)(void))
+void usbd_register_suspend_callback(usbd_device *usbd_dev,
+ void (*callback)(void))
{
- _usbd_device.user_callback_suspend = callback;
+ usbd_dev->user_callback_suspend = callback;
}
-void usbd_register_resume_callback(void (*callback)(void))
+void usbd_register_resume_callback(usbd_device *usbd_dev,
+ void (*callback)(void))
{
- _usbd_device.user_callback_resume = callback;
+ usbd_dev->user_callback_resume = callback;
}
-void usbd_register_sof_callback(void (*callback)(void))
+void usbd_register_sof_callback(usbd_device *usbd_dev, void (*callback)(void))
{
- _usbd_device.user_callback_sof = callback;
+ usbd_dev->user_callback_sof = callback;
}
-void usbd_set_control_buffer_size(u16 size)
+void usbd_set_control_buffer_size(usbd_device *usbd_dev, u16 size)
{
- _usbd_device.ctrl_buf_len = size;
+ usbd_dev->ctrl_buf_len = size;
}
-void _usbd_reset(void)
+void _usbd_reset(usbd_device *usbd_dev)
{
- _usbd_device.current_address = 0;
- _usbd_device.current_config = 0;
- usbd_ep_setup(0, USB_ENDPOINT_ATTR_CONTROL, 64, NULL);
- _usbd_hw_set_address(0);
+ usbd_dev->current_address = 0;
+ usbd_dev->current_config = 0;
+ usbd_ep_setup(usbd_dev, 0, USB_ENDPOINT_ATTR_CONTROL, 64, NULL);
+ usbd_dev->driver->set_address(usbd_dev, 0);
- if (_usbd_device.user_callback_reset)
- _usbd_device.user_callback_reset();
+ if (usbd_dev->user_callback_reset)
+ usbd_dev->user_callback_reset();
}
/* Functions to wrap the low-level driver */
-void usbd_poll(void)
+void usbd_poll(usbd_device *usbd_dev)
{
- _usbd_device.driver->poll();
+ usbd_dev->driver->poll(usbd_dev);
}
-void usbd_disconnect(bool disconnected)
+void usbd_disconnect(usbd_device *usbd_dev, bool disconnected)
{
/* not all drivers support disconnection */
- if (_usbd_device.driver->disconnect)
- _usbd_device.driver->disconnect(disconnected);
+ if (usbd_dev->driver->disconnect)
+ usbd_dev->driver->disconnect(usbd_dev, disconnected);
}
-void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback)(u8 ep))
+void usbd_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size,
+ void (*callback)(usbd_device *usbd_dev, u8 ep))
{
- _usbd_device.driver->ep_setup(addr, type, max_size, callback);
+ usbd_dev->driver->ep_setup(usbd_dev, addr, type, max_size, callback);
}
-u16 usbd_ep_write_packet(u8 addr, const void *buf, u16 len)
+u16 usbd_ep_write_packet(usbd_device *usbd_dev, u8 addr,
+ const void *buf, u16 len)
{
- return _usbd_device.driver->ep_write_packet(addr, buf, len);
+ return usbd_dev->driver->ep_write_packet(usbd_dev, addr, buf, len);
}
-u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len)
+u16 usbd_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, u16 len)
{
- return _usbd_device.driver->ep_read_packet(addr, buf, len);
+ return usbd_dev->driver->ep_read_packet(usbd_dev, addr, buf, len);
}
-void usbd_ep_stall_set(u8 addr, u8 stall)
+void usbd_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall)
{
- _usbd_device.driver->ep_stall_set(addr, stall);
+ usbd_dev->driver->ep_stall_set(usbd_dev, addr, stall);
}
-u8 usbd_ep_stall_get(u8 addr)
+u8 usbd_ep_stall_get(usbd_device *usbd_dev, u8 addr)
{
- return _usbd_device.driver->ep_stall_get(addr);
+ return usbd_dev->driver->ep_stall_get(usbd_dev, addr);
}
-void usbd_ep_nak_set(u8 addr, u8 nak)
+void usbd_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak)
{
- _usbd_device.driver->ep_nak_set(addr, nak);
+ usbd_dev->driver->ep_nak_set(usbd_dev, addr, nak);
}
diff --git a/lib/usb/usb_control.c b/lib/usb/usb_control.c
index b4ac57e..82843df 100644
--- a/lib/usb/usb_control.c
+++ b/lib/usb/usb_control.c
@@ -21,77 +21,73 @@
#include <libopencm3/usb/usbd.h>
#include "usb_private.h"
-static struct usb_control_state {
- enum {
- IDLE, STALLED,
- DATA_IN, LAST_DATA_IN, STATUS_IN,
- DATA_OUT, LAST_DATA_OUT, STATUS_OUT,
- } state;
- struct usb_setup_data req;
- u8 *ctrl_buf;
- u16 ctrl_len;
- void (*complete)(struct usb_setup_data *req);
-} control_state;
-
/* Register application callback function for handling USB control requests. */
-int usbd_register_control_callback(u8 type, u8 type_mask,
+int usbd_register_control_callback(usbd_device *usbd_dev, u8 type, u8 type_mask,
usbd_control_callback callback)
{
int i;
for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) {
- if (_usbd_device.user_control_callback[i].cb)
+ if (usbd_dev->user_control_callback[i].cb)
continue;
- _usbd_device.user_control_callback[i].type = type;
- _usbd_device.user_control_callback[i].type_mask = type_mask;
- _usbd_device.user_control_callback[i].cb = callback;
+ usbd_dev->user_control_callback[i].type = type;
+ usbd_dev->user_control_callback[i].type_mask = type_mask;
+ usbd_dev->user_control_callback[i].cb = callback;
return 0;
}
return -1;
}
-static void usb_control_send_chunk(void)
+static void usb_control_send_chunk(usbd_device *usbd_dev)
{
- if (_usbd_device.desc->bMaxPacketSize0 < control_state.ctrl_len) {
+ if (usbd_dev->desc->bMaxPacketSize0 < usbd_dev->control_state.ctrl_len) {
/* Data stage, normal transmission */
- usbd_ep_write_packet(0, control_state.ctrl_buf,
- _usbd_device.desc->bMaxPacketSize0);
- control_state.state = DATA_IN;
- control_state.ctrl_buf += _usbd_device.desc->bMaxPacketSize0;
- control_state.ctrl_len -= _usbd_device.desc->bMaxPacketSize0;
+ usbd_ep_write_packet(usbd_dev, 0,
+ usbd_dev->control_state.ctrl_buf,
+ usbd_dev->desc->bMaxPacketSize0);
+ usbd_dev->control_state.state = DATA_IN;
+ usbd_dev->control_state.ctrl_buf +=
+ usbd_dev->desc->bMaxPacketSize0;
+ usbd_dev->control_state.ctrl_len -=
+ usbd_dev->desc->bMaxPacketSize0;
} else {
/* Data stage, end of transmission */
- usbd_ep_write_packet(0, control_state.ctrl_buf,
- control_state.ctrl_len);
- control_state.state = LAST_DATA_IN;
- control_state.ctrl_len = 0;
- control_state.ctrl_buf = NULL;
+ usbd_ep_write_packet(usbd_dev, 0,
+ usbd_dev->control_state.ctrl_buf,
+ usbd_dev->control_state.ctrl_len);
+ usbd_dev->control_state.state = LAST_DATA_IN;
+ usbd_dev->control_state.ctrl_len = 0;
+ usbd_dev->control_state.ctrl_buf = NULL;
}
}
-static int usb_control_recv_chunk(void)
+static int usb_control_recv_chunk(usbd_device *usbd_dev)
{
- u16 packetsize = MIN(_usbd_device.desc->bMaxPacketSize0,
- control_state.req.wLength - control_state.ctrl_len);
- u16 size = usbd_ep_read_packet(0, control_state.ctrl_buf +
- control_state.ctrl_len, packetsize);
+ u16 packetsize = MIN(usbd_dev->desc->bMaxPacketSize0,
+ usbd_dev->control_state.req.wLength -
+ usbd_dev->control_state.ctrl_len);
+ u16 size = usbd_ep_read_packet(usbd_dev, 0,
+ usbd_dev->control_state.ctrl_buf +
+ usbd_dev->control_state.ctrl_len,
+ packetsize);
if (size != packetsize) {
- usbd_ep_stall_set(0, 1);
+ usbd_ep_stall_set(usbd_dev, 0, 1);
return -1;
}
- control_state.ctrl_len += size;
+ usbd_dev->control_state.ctrl_len += size;
return packetsize;
}
-static int usb_control_request_dispatch(struct usb_setup_data *req)
+static int usb_control_request_dispatch(usbd_device *usbd_dev,
+ struct usb_setup_data *req)
{
int i, result = 0;
- struct user_control_callback *cb = _usbd_device.user_control_callback;
+ struct user_control_callback *cb = usbd_dev->user_control_callback;
/* Call user command hook function. */
for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) {
@@ -99,141 +95,149 @@ static int usb_control_request_dispatch(struct usb_setup_data *req)
break;
if ((req->bmRequestType & cb[i].type_mask) == cb[i].type) {
- result = cb[i].cb(req, &control_state.ctrl_buf,
- &control_state.ctrl_len,
- &control_state.complete);
+ result = cb[i].cb(usbd_dev, req,
+ &(usbd_dev->control_state.ctrl_buf),
+ &(usbd_dev->control_state.ctrl_len),
+ &(usbd_dev->control_state.complete));
if (result == USBD_REQ_HANDLED ||
result == USBD_REQ_NOTSUPP)
return result;
}
}
-
+
/* Try standard request if not already handled. */
- return _usbd_standard_request(req, &control_state.ctrl_buf,
- &control_state.ctrl_len);
+ return _usbd_standard_request(usbd_dev, req,
+ &(usbd_dev->control_state.ctrl_buf),
+ &(usbd_dev->control_state.ctrl_len));
}
/* Handle commands and read requests. */
-static void usb_control_setup_read(struct usb_setup_data *req)
+static void usb_control_setup_read(usbd_device *usbd_dev,
+ struct usb_setup_data *req)
{
- control_state.ctrl_buf = _usbd_device.ctrl_buf;
- control_state.ctrl_len = req->wLength;
+ usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf;
+ usbd_dev->control_state.ctrl_len = req->wLength;
- if (usb_control_request_dispatch(req)) {
- if (control_state.ctrl_len) {
+ if (usb_control_request_dispatch(usbd_dev, req)) {
+ if (usbd_dev->control_state.ctrl_len) {
/* Go to data out stage if handled. */
- usb_control_send_chunk();
+ usb_control_send_chunk(usbd_dev);
} else {
/* Go to status stage if handled. */
- usbd_ep_write_packet(0, NULL, 0);
- control_state.state = STATUS_IN;
+ usbd_ep_write_packet(usbd_dev, 0, NULL, 0);
+ usbd_dev->control_state.state = STATUS_IN;
}
} else {
/* Stall endpoint on failure. */
- usbd_ep_stall_set(0, 1);
+ usbd_ep_stall_set(usbd_dev, 0, 1);
}
}
-static void usb_control_setup_write(struct usb_setup_data *req)
+static void usb_control_setup_write(usbd_device *usbd_dev,
+ struct usb_setup_data *req)
{
- if (req->wLength > _usbd_device.ctrl_buf_len) {
- usbd_ep_stall_set(0, 1);
+ if (req->wLength > usbd_dev->ctrl_buf_len) {
+ usbd_ep_stall_set(usbd_dev, 0, 1);
return;
}
/* Buffer into which to write received data. */
- control_state.ctrl_buf = _usbd_device.ctrl_buf;
- control_state.ctrl_len = 0;
+ usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf;
+ usbd_dev->control_state.ctrl_len = 0;
/* Wait for DATA OUT stage. */
- if (req->wLength > _usbd_device.desc->bMaxPacketSize0)
- control_state.state = DATA_OUT;
+ if (req->wLength > usbd_dev->desc->bMaxPacketSize0)
+ usbd_dev->control_state.state = DATA_OUT;
else
- control_state.state = LAST_DATA_OUT;
+ usbd_dev->control_state.state = LAST_DATA_OUT;
}
-void _usbd_control_setup(u8 ea)
+void _usbd_control_setup(usbd_device *usbd_dev, u8 ea)
{
- struct usb_setup_data *req = &control_state.req;
+ struct usb_setup_data *req = &usbd_dev->control_state.req;
(void)ea;
- control_state.complete = NULL;
+ usbd_dev->control_state.complete = NULL;
- if (usbd_ep_read_packet(0, req, 8) != 8) {
- usbd_ep_stall_set(0, 1);
+ if (usbd_ep_read_packet(usbd_dev, 0, req, 8) != 8) {
+ usbd_ep_stall_set(usbd_dev, 0, 1);
return;
}
if (req->wLength == 0) {
- usb_control_setup_read(req);
+ usb_control_setup_read(usbd_dev, req);
} else if (req->bmRequestType & 0x80) {
- usb_control_setup_read(req);
+ usb_control_setup_read(usbd_dev, req);
} else {
- usb_control_setup_write(req);
+ usb_control_setup_write(usbd_dev, req);
}
}
-void _usbd_control_out(u8 ea)
+void _usbd_control_out(usbd_device *usbd_dev, u8 ea)
{
(void)ea;
- switch (control_state.state) {
+ switch (usbd_dev->control_state.state) {
case DATA_OUT:
- if (usb_control_recv_chunk() < 0)
+ if (usb_control_recv_chunk(usbd_dev) < 0)
break;
- if ((control_state.req.wLength - control_state.ctrl_len) <=
- _usbd_device.desc->bMaxPacketSize0)
- control_state.state = LAST_DATA_OUT;
+ if ((usbd_dev->control_state.req.wLength -
+ usbd_dev->control_state.ctrl_len) <=
+ usbd_dev->desc->bMaxPacketSize0)
+ usbd_dev->control_state.state = LAST_DATA_OUT;
break;
case LAST_DATA_OUT:
- if (usb_control_recv_chunk() < 0)
+ if (usb_control_recv_chunk(usbd_dev) < 0)
break;
/*
* We have now received the full data payload.
* Invoke callback to process.
*/
- if (usb_control_request_dispatch(&control_state.req)) {
+ if (usb_control_request_dispatch(usbd_dev,
+ &(usbd_dev->control_state.req))) {
/* Got to status stage on success. */
- usbd_ep_write_packet(0, NULL, 0);
- control_state.state = STATUS_IN;
+ usbd_ep_write_packet(usbd_dev, 0, NULL, 0);
+ usbd_dev->control_state.state = STATUS_IN;
} else {
- usbd_ep_stall_set(0, 1);
+ usbd_ep_stall_set(usbd_dev, 0, 1);
}
break;
case STATUS_OUT:
- usbd_ep_read_packet(0, NULL, 0);
- control_state.state = IDLE;
- if (control_state.complete)
- control_state.complete(&control_state.req);
- control_state.complete = NULL;
+ usbd_ep_read_packet(usbd_dev, 0, NULL, 0);
+ usbd_dev->control_state.state = IDLE;
+ if (usbd_dev->control_state.complete)
+ usbd_dev->control_state.complete(usbd_dev,
+ &(usbd_dev->control_state.req));
+ usbd_dev->control_state.complete = NULL;
break;
default:
- usbd_ep_stall_set(0, 1);
+ usbd_ep_stall_set(usbd_dev, 0, 1);
}
}
-void _usbd_control_in(u8 ea)
+void _usbd_control_in(usbd_device *usbd_dev, u8 ea)
{
(void)ea;
- struct usb_setup_data *req = &control_state.req;
+ struct usb_setup_data *req = &(usbd_dev->control_state.req);
- switch (control_state.state) {
+ switch (usbd_dev->control_state.state) {
case DATA_IN:
- usb_control_send_chunk();
+ usb_control_send_chunk(usbd_dev);
break;
case LAST_DATA_IN:
- control_state.state = STATUS_OUT;
+ usbd_dev->control_state.state = STATUS_OUT;
break;
case STATUS_IN:
- if (control_state.complete)
- control_state.complete(&control_state.req);
+ if (usbd_dev->control_state.complete)
+ usbd_dev->control_state.complete(usbd_dev,
+ &(usbd_dev->control_state.req));
/* Exception: Handle SET ADDRESS function here... */
if ((req->bmRequestType == 0) &&
(req->bRequest == USB_REQ_SET_ADDRESS))
- _usbd_hw_set_address(req->wValue);
- control_state.state = IDLE;
+ usbd_dev->driver->set_address(usbd_dev, req->wValue);
+ usbd_dev->control_state.state = IDLE;
break;
default:
- usbd_ep_stall_set(0, 1);
+ usbd_ep_stall_set(usbd_dev, 0, 1);
}
}
diff --git a/lib/usb/usb_f103.c b/lib/usb/usb_f103.c
index 22db8cc..aa323d9 100644
--- a/lib/usb/usb_f103.c
+++ b/lib/usb/usb_f103.c
@@ -24,19 +24,23 @@
#include <libopencm3/usb/usbd.h>
#include "usb_private.h"
-static void stm32f103_usbd_init(void);
-static void stm32f103_set_address(u8 addr);
-static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size,
- void (*callback) (u8 ep));
-static void stm32f103_endpoints_reset(void);
-static void stm32f103_ep_stall_set(u8 addr, u8 stall);
-static u8 stm32f103_ep_stall_get(u8 addr);
-static void stm32f103_ep_nak_set(u8 addr, u8 nak);
-static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len);
-static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len);
-static void stm32f103_poll(void);
+static usbd_device *stm32f103_usbd_init(void);
+static void stm32f103_set_address(usbd_device *usbd_dev, u8 addr);
+static void stm32f103_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type,
+ u16 max_size,
+ void (*callback) (usbd_device *usbd_dev, u8 ep));
+static void stm32f103_endpoints_reset(usbd_device *usbd_dev);
+static void stm32f103_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall);
+static u8 stm32f103_ep_stall_get(usbd_device *usbd_dev, u8 addr);
+static void stm32f103_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak);
+static u16 stm32f103_ep_write_packet(usbd_device *usbd_dev, u8 addr,
+ const void *buf, u16 len);
+static u16 stm32f103_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf,
+ u16 len);
+static void stm32f103_poll(usbd_device *usbd_dev);
static u8 force_nak[8];
+static struct _usbd_device usbd_dev;
const struct _usbd_driver stm32f103_usb_driver = {
.init = stm32f103_usbd_init,
@@ -52,7 +56,7 @@ const struct _usbd_driver stm32f103_usb_driver = {
};
/** Initialize the USB device controller hardware of the STM32. */
-static void stm32f103_usbd_init(void)
+static usbd_device *stm32f103_usbd_init(void)
{
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN);
SET_REG(USB_CNTR_REG, 0);
@@ -62,10 +66,12 @@ static void stm32f103_usbd_init(void)
/* Enable RESET, SUSPEND, RESUME and CTR interrupts. */
SET_REG(USB_CNTR_REG, USB_CNTR_RESETM | USB_CNTR_CTRM |
USB_CNTR_SUSPM | USB_CNTR_WKUPM);
+ return &usbd_dev;
}
-static void stm32f103_set_address(u8 addr)
+static void stm32f103_set_address(usbd_device *usbd_dev, u8 addr)
{
+ (void)usbd_dev;
/* Set device address and enable. */
SET_REG(USB_DADDR_REG, (addr & USB_DADDR_ADDR) | USB_DADDR_ENABLE);
}
@@ -76,8 +82,9 @@ static void stm32f103_set_address(u8 addr)
* @param ep Index of endpoint to configure.
* @param size Size in bytes of the RX buffer.
*/
-static void usb_set_ep_rx_bufsize(u8 ep, u32 size)
+static void usb_set_ep_rx_bufsize(usbd_device *usbd_dev, u8 ep, u32 size)
{
+ (void)usbd_dev;
if (size > 62) {
if (size & 0x1f)
size -= 32;
@@ -89,8 +96,9 @@ static void usb_set_ep_rx_bufsize(u8 ep, u32 size)
}
}
-static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size,
- void (*callback) (u8 ep))
+static void stm32f103_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type,
+ u16 max_size,
+ void (*callback) (usbd_device *usbd_dev, u8 ep))
{
/* Translate USB standard type codes to STM32. */
const u16 typelookup[] = {
@@ -107,32 +115,30 @@ static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size,
USB_SET_EP_TYPE(addr, typelookup[type]);
if (dir || (addr == 0)) {
- USB_SET_EP_TX_ADDR(addr, _usbd_device.pm_top);
+ USB_SET_EP_TX_ADDR(addr, usbd_dev->pm_top);
if (callback) {
- _usbd_device.
- user_callback_ctr[addr][USB_TRANSACTION_IN] =
+ usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] =
(void *)callback;
}
USB_CLR_EP_TX_DTOG(addr);
USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_NAK);
- _usbd_device.pm_top += max_size;
+ usbd_dev->pm_top += max_size;
}
if (!dir) {
- USB_SET_EP_RX_ADDR(addr, _usbd_device.pm_top);
- usb_set_ep_rx_bufsize(addr, max_size);
+ USB_SET_EP_RX_ADDR(addr, usbd_dev->pm_top);
+ usb_set_ep_rx_bufsize(usbd_dev, addr, max_size);
if (callback) {
- _usbd_device.
- user_callback_ctr[addr][USB_TRANSACTION_OUT] =
+ usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] =
(void *)callback;
}
USB_CLR_EP_RX_DTOG(addr);
USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID);
- _usbd_device.pm_top += max_size;
+ usbd_dev->pm_top += max_size;
}
}
-static void stm32f103_endpoints_reset(void)
+static void stm32f103_endpoints_reset(usbd_device *usbd_dev)
{
int i;
@@ -141,11 +147,12 @@ static void stm32f103_endpoints_reset(void)
USB_SET_EP_TX_STAT(i, USB_EP_TX_STAT_DISABLED);
USB_SET_EP_RX_STAT(i, USB_EP_RX_STAT_DISABLED);
}
- _usbd_device.pm_top = 0x40 + (2 * _usbd_device.desc->bMaxPacketSize0);
+ usbd_dev->pm_top = 0x40 + (2 * usbd_dev->desc->bMaxPacketSize0);
}
-static void stm32f103_ep_stall_set(u8 addr, u8 stall)
+static void stm32f103_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall)
{
+ (void)usbd_dev;
if (addr == 0)
USB_SET_EP_TX_STAT(addr, stall ? USB_EP_TX_STAT_STALL :
USB_EP_TX_STAT_NAK);
@@ -169,8 +176,9 @@ static void stm32f103_ep_stall_set(u8 addr, u8 stall)
}
}
-static u8 stm32f103_ep_stall_get(u8 addr)
+static u8 stm32f103_ep_stall_get(usbd_device *usbd_dev, u8 addr)
{
+ (void)usbd_dev;
if (addr & 0x80) {
if ((*USB_EP_REG(addr & 0x7F) & USB_EP_TX_STAT) ==
USB_EP_TX_STAT_STALL)
@@ -183,8 +191,9 @@ static u8 stm32f103_ep_stall_get(u8 addr)
return 0;
}
-static void stm32f103_ep_nak_set(u8 addr, u8 nak)
+static void stm32f103_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak)
{
+ (void)usbd_dev;
/* It does not make sence to force NAK on IN endpoints. */
if (addr & 0x80)
return;
@@ -213,8 +222,10 @@ static void usb_copy_to_pm(volatile void *vPM, const void *buf, u16 len)
*PM = *lbuf;
}
-static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len)
+static u16 stm32f103_ep_write_packet(usbd_device *usbd_dev, u8 addr,
+ const void *buf, u16 len)
{
+ (void)usbd_dev;
addr &= 0x7F;
if ((*USB_EP_REG(addr) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID)
@@ -247,8 +258,10 @@ static void usb_copy_from_pm(void *buf, const volatile void *vPM, u16 len)
*(u8 *) lbuf = *(u8 *) PM;
}
-static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len)
+static u16 stm32f103_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf,
+ u16 len)
{
+ (void)usbd_dev;
if ((*USB_EP_REG(addr) & USB_EP_RX_STAT) == USB_EP_RX_STAT_VALID)
return 0;
@@ -262,13 +275,13 @@ static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len)
return len;
}
-static void stm32f103_poll(void)
+static void stm32f103_poll(usbd_device *usbd_dev)
{
u16 istr = *USB_ISTR_REG;
if (istr & USB_ISTR_RESET) {
- _usbd_device.pm_top = 0x40;
- _usbd_reset();
+ usbd_dev->pm_top = 0x40;
+ _usbd_reset(usbd_dev);
USB_CLR_ISTR_RESET();
return;
}
@@ -282,27 +295,27 @@ static void stm32f103_poll(void)
else /* IN transaction */
USB_CLR_EP_TX_CTR(ep);
- if (_usbd_device.user_callback_ctr[ep][type])
- _usbd_device.user_callback_ctr[ep][type] (ep);
+ if (usbd_dev->user_callback_ctr[ep][type])
+ usbd_dev->user_callback_ctr[ep][type] (usbd_dev, ep);
else
USB_CLR_EP_RX_CTR(ep);
}
if (istr & USB_ISTR_SUSP) {
USB_CLR_ISTR_SUSP();
- if (_usbd_device.user_callback_suspend)
- _usbd_device.user_callback_suspend();
+ if (usbd_dev->user_callback_suspend)
+ usbd_dev->user_callback_suspend();
}
if (istr & USB_ISTR_WKUP) {
USB_CLR_ISTR_WKUP();
- if (_usbd_device.user_callback_resume)
- _usbd_device.user_callback_resume();
+ if (usbd_dev->user_callback_resume)
+ usbd_dev->user_callback_resume();
}
if (istr & USB_ISTR_SOF) {
- if (_usbd_device.user_callback_sof)
- _usbd_device.user_callback_sof();
+ if (usbd_dev->user_callback_sof)
+ usbd_dev->user_callback_sof();
USB_CLR_ISTR_SOF();
}
}
diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c
index a5a4a6c..009979d 100644
--- a/lib/usb/usb_f107.c
+++ b/lib/usb/usb_f107.c
@@ -23,49 +23,34 @@
#include <libopencm3/stm32/otg_fs.h>
#include <libopencm3/usb/usbd.h>
#include "usb_private.h"
+#include "usb_fx07_common.h"
/* Receive FIFO size in 32-bit words. */
#define RX_FIFO_SIZE 128
-static uint16_t fifo_mem_top;
-static uint16_t fifo_mem_top_ep0;
-static u8 force_nak[4];
+static usbd_device *stm32f107_usbd_init(void);
-static void stm32f107_usbd_init(void);
-static void stm32f107_set_address(u8 addr);
-static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
- void (*callback)(u8 ep));
-static void stm32f107_endpoints_reset(void);
-static void stm32f107_ep_stall_set(u8 addr, u8 stall);
-static u8 stm32f107_ep_stall_get(u8 addr);
-static void stm32f107_ep_nak_set(u8 addr, u8 nak);
-static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len);
-static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len);
-static void stm32f107_poll(void);
-static void stm32f107_disconnect(bool disconnected);
-
-/*
- * We keep a backup copy of the out endpoint size registers to restore them
- * after a transaction.
- */
-static u32 doeptsiz[4];
+static struct _usbd_device usbd_dev;
const struct _usbd_driver stm32f107_usb_driver = {
.init = stm32f107_usbd_init,
- .set_address = stm32f107_set_address,
- .ep_setup = stm32f107_ep_setup,
- .ep_reset = stm32f107_endpoints_reset,
- .ep_stall_set = stm32f107_ep_stall_set,
- .ep_stall_get = stm32f107_ep_stall_get,
- .ep_nak_set = stm32f107_ep_nak_set,
- .ep_write_packet = stm32f107_ep_write_packet,
- .ep_read_packet = stm32f107_ep_read_packet,
- .poll = stm32f107_poll,
- .disconnect = stm32f107_disconnect,
+ .set_address = stm32fx07_set_address,
+ .ep_setup = stm32fx07_ep_setup,
+ .ep_reset = stm32fx07_endpoints_reset,
+ .ep_stall_set = stm32fx07_ep_stall_set,
+ .ep_stall_get = stm32fx07_ep_stall_get,
+ .ep_nak_set = stm32fx07_ep_nak_set,
+ .ep_write_packet = stm32fx07_ep_write_packet,
+ .ep_read_packet = stm32fx07_ep_read_packet,
+ .poll = stm32fx07_poll,
+ .disconnect = stm32fx07_disconnect,
+ .base_address = USB_OTG_FS_BASE,
+ .set_address_before_status = 1,
+ .rx_fifo_size = RX_FIFO_SIZE,
};
/** Initialize the USB device controller hardware of the STM32. */
-static void stm32f107_usbd_init(void)
+static usbd_device *stm32f107_usbd_init(void)
{
OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS;
@@ -88,8 +73,8 @@ static void stm32f107_usbd_init(void)
/* Restart the PHY clock. */
OTG_FS_PCGCCTL = 0;
- OTG_FS_GRXFSIZ = RX_FIFO_SIZE;
- fifo_mem_top = RX_FIFO_SIZE;
+ OTG_FS_GRXFSIZ = stm32f107_usb_driver.rx_fifo_size;
+ usbd_dev.fifo_mem_top = stm32f107_usb_driver.rx_fifo_size;
/* Unmask interrupts for TX and RX. */
OTG_FS_GAHBCFG |= OTG_FS_GAHBCFG_GINT;
@@ -101,289 +86,6 @@ static void stm32f107_usbd_init(void)
OTG_FS_GINTMSK_SOFM;
OTG_FS_DAINTMSK = 0xF;
OTG_FS_DIEPMSK = OTG_FS_DIEPMSK_XFRCM;
-}
-
-static void stm32f107_set_address(u8 addr)
-{
- OTG_FS_DCFG = (OTG_FS_DCFG & ~OTG_FS_DCFG_DAD) | (addr << 4);
-}
-
-static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
- void (*callback) (u8 ep))
-{
- /*
- * Configure endpoint address and type. Allocate FIFO memory for
- * endpoint. Install callback funciton.
- */
- u8 dir = addr & 0x80;
- addr &= 0x7f;
-
- if (addr == 0) { /* For the default control endpoint */
- /* Configure IN part. */
- if (max_size >= 64) {
- OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_64;
- } else if (max_size >= 32) {
- OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_32;
- } else if (max_size >= 16) {
- OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_16;
- } else {
- OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_8;
- }
- OTG_FS_DIEPTSIZ0 = (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
- OTG_FS_DIEPCTL0 |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK;
-
- /* Configure OUT part. */
- doeptsiz[0] = OTG_FS_DIEPSIZ0_STUPCNT_1 | (1 << 19) |
- (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
- OTG_FS_DOEPTSIZ(0) = doeptsiz[0];
- OTG_FS_DOEPCTL(0) |=
- OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK;
-
- OTG_FS_GNPTXFSIZ = ((max_size / 4) << 16) | RX_FIFO_SIZE;
- fifo_mem_top += max_size / 4;
- fifo_mem_top_ep0 = fifo_mem_top;
-
- return;
- }
-
- if (dir) {
- OTG_FS_DIEPTXF(addr) = ((max_size / 4) << 16) | fifo_mem_top;
- fifo_mem_top += max_size / 4;
-
- OTG_FS_DIEPTSIZ(addr) =
- (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
- OTG_FS_DIEPCTL(addr) |=
- OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK | (type << 18)
- | OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID
- | (addr << 22) | max_size;
-
- if (callback) {
- _usbd_device.
- user_callback_ctr[addr][USB_TRANSACTION_IN] =
- (void *)callback;
- }
- }
-
- if (!dir) {
- doeptsiz[addr] = (1 << 19) |
- (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
- OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
- OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
- OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK |
- OTG_FS_DOEPCTLX_SD0PID | (type << 18) | max_size;
-
- if (callback) {
- _usbd_device.
- user_callback_ctr[addr][USB_TRANSACTION_OUT] =
- (void *)callback;
- }
- }
-}
-
-static void stm32f107_endpoints_reset(void)
-{
- /* The core resets the endpoints automatically on reset. */
- fifo_mem_top = fifo_mem_top_ep0;
-}
-
-static void stm32f107_ep_stall_set(u8 addr, u8 stall)
-{
- if (addr == 0) {
- if (stall)
- OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL;
- else
- OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL;
- }
-
- if (addr & 0x80) {
- addr &= 0x7F;
-
- if (stall) {
- OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL;
- } else {
- OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL;
- OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTLX_SD0PID;
- }
- } else {
- if (stall) {
- OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_STALL;
- } else {
- OTG_FS_DOEPCTL(addr) &= ~OTG_FS_DOEPCTL0_STALL;
- OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTLX_SD0PID;
- }
- }
-}
-
-static u8 stm32f107_ep_stall_get(u8 addr)
-{
- /* Return non-zero if STALL set. */
- if (addr & 0x80)
- return
- (OTG_FS_DIEPCTL(addr & 0x7f) & OTG_FS_DIEPCTL0_STALL) ? 1 : 0;
- else
- return (OTG_FS_DOEPCTL(addr) & OTG_FS_DOEPCTL0_STALL) ? 1 : 0;
-}
-
-static void stm32f107_ep_nak_set(u8 addr, u8 nak)
-{
- /* It does not make sence to force NAK on IN endpoints. */
- if (addr & 0x80)
- return;
-
- force_nak[addr] = nak;
-
- if (nak)
- OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_SNAK;
- else
- OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_CNAK;
-}
-static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len)
-{
- const u32 *buf32 = buf;
- int i;
-
- addr &= 0x7F;
-
- /* Return if endpoint is already enabled. */
- if (OTG_FS_DIEPTSIZ(addr) & OTG_FS_DIEPSIZ0_PKTCNT)
- return 0;
-
- /* Enable endpoint for transmission. */
- OTG_FS_DIEPTSIZ(addr) = (1 << 19) | len;
- OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_CNAK;
-
- /* Copy buffer to endpoint FIFO. */
- volatile u32 *fifo = OTG_FS_FIFO(addr);
- for (i = len; i > 0; i -= 4)
- *fifo++ = *buf32++;
-
- return len;
-}
-
-/*
- * Received packet size for each endpoint. This is assigned in
- * stm32f107_poll() which reads the packet status push register GRXSTSP
- * for use in stm32f107_ep_read_packet().
- */
-static uint16_t rxbcnt;
-
-static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len)
-{
- int i;
- u32 *buf32 = buf;
- u32 extra;
-
- len = MIN(len, rxbcnt);
- rxbcnt -= len;
-
- volatile u32 *fifo = OTG_FS_FIFO(addr);
- for (i = len; i >= 4; i -= 4)
- *buf32++ = *fifo++;
-
- if (i) {
- extra = *fifo++;
- memcpy(buf32, &extra, i);
- }
-
- OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
- OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
- (force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK);
-
- return len;
-}
-
-static void stm32f107_poll(void)
-{
- /* Read interrupt status register. */
- u32 intsts = OTG_FS_GINTSTS;
- int i;
-
- if (intsts & OTG_FS_GINTSTS_ENUMDNE) {
- /* Handle USB RESET condition. */
- OTG_FS_GINTSTS = OTG_FS_GINTSTS_ENUMDNE;
- fifo_mem_top = RX_FIFO_SIZE;
- _usbd_reset();
- return;
- }
-
- /* Note: RX and TX handled differently in this device. */
- if (intsts & OTG_FS_GINTSTS_RXFLVL) {
- /* Receive FIFO non-empty. */
- u32 rxstsp = OTG_FS_GRXSTSP;
- u32 pktsts = rxstsp & OTG_FS_GRXSTSP_PKTSTS_MASK;
- if ((pktsts != OTG_FS_GRXSTSP_PKTSTS_OUT) &&
- (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP))
- return;
-
- u8 ep = rxstsp & OTG_FS_GRXSTSP_EPNUM_MASK;
- u8 type;
- if (pktsts == OTG_FS_GRXSTSP_PKTSTS_SETUP)
- type = USB_TRANSACTION_SETUP;
- else
- type = USB_TRANSACTION_OUT;
-
- /* Save packet size for stm32f107_ep_read_packet(). */
- rxbcnt = (rxstsp & OTG_FS_GRXSTSP_BCNT_MASK) >> 4;
-
- /*
- * FIXME: Why is a delay needed here?
- * This appears to fix a problem where the first 4 bytes
- * of the DATA OUT stage of a control transaction are lost.
- */
- for (i = 0; i < 1000; i++)
- __asm__("nop");
-
- if (_usbd_device.user_callback_ctr[ep][type])
- _usbd_device.user_callback_ctr[ep][type] (ep);
-
- /* Discard unread packet data. */
- for (i = 0; i < rxbcnt; i += 4)
- (void)*OTG_FS_FIFO(ep);
-
- rxbcnt = 0;
- }
-
- /*
- * There is no global interrupt flag for transmit complete.
- * The XFRC bit must be checked in each OTG_FS_DIEPINT(x).
- */
- for (i = 0; i < 4; i++) { /* Iterate over endpoints. */
- if (OTG_FS_DIEPINT(i) & OTG_FS_DIEPINTX_XFRC) {
- /* Transfer complete. */
- if (_usbd_device.
- user_callback_ctr[i][USB_TRANSACTION_IN]) {
- _usbd_device.
- user_callback_ctr[i][USB_TRANSACTION_IN](i);
- }
- OTG_FS_DIEPINT(i) = OTG_FS_DIEPINTX_XFRC;
- }
- }
-
- if (intsts & OTG_FS_GINTSTS_USBSUSP) {
- if (_usbd_device.user_callback_suspend)
- _usbd_device.user_callback_suspend();
- OTG_FS_GINTSTS = OTG_FS_GINTSTS_USBSUSP;
- }
-
- if (intsts & OTG_FS_GINTSTS_WKUPINT) {
- if (_usbd_device.user_callback_resume)
- _usbd_device.user_callback_resume();
- OTG_FS_GINTSTS = OTG_FS_GINTSTS_WKUPINT;
- }
-
- if (intsts & OTG_FS_GINTSTS_SOF) {
- if (_usbd_device.user_callback_sof)
- _usbd_device.user_callback_sof();
- OTG_FS_GINTSTS = OTG_FS_GINTSTS_SOF;
- }
-}
-
-static void stm32f107_disconnect(bool disconnected)
-{
- if (disconnected) {
- OTG_FS_DCTL |= OTG_FS_DCTL_SDIS;
- } else {
- OTG_FS_DCTL &= ~OTG_FS_DCTL_SDIS;
- }
+ return &usbd_dev;
}
diff --git a/lib/usb/usb_f207.c b/lib/usb/usb_f207.c
new file mode 100644
index 0000000..b2509e5
--- /dev/null
+++ b/lib/usb/usb_f207.c
@@ -0,0 +1,91 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * 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 <string.h>
+#include <libopencm3/cm3/common.h>
+#include <libopencm3/stm32/tools.h>
+#include <libopencm3/stm32/otg_hs.h>
+#include <libopencm3/usb/usbd.h>
+#include "usb_private.h"
+#include "usb_fx07_common.h"
+
+/* Receive FIFO size in 32-bit words. */
+#define RX_FIFO_SIZE 512
+
+static usbd_device *stm32f207_usbd_init(void);
+
+static struct _usbd_device usbd_dev;
+
+const struct _usbd_driver stm32f207_usb_driver = {
+ .init = stm32f207_usbd_init,
+ .set_address = stm32fx07_set_address,
+ .ep_setup = stm32fx07_ep_setup,
+ .ep_reset = stm32fx07_endpoints_reset,
+ .ep_stall_set = stm32fx07_ep_stall_set,
+ .ep_stall_get = stm32fx07_ep_stall_get,
+ .ep_nak_set = stm32fx07_ep_nak_set,
+ .ep_write_packet = stm32fx07_ep_write_packet,
+ .ep_read_packet = stm32fx07_ep_read_packet,
+ .poll = stm32fx07_poll,
+ .disconnect = stm32fx07_disconnect,
+ .base_address = USB_OTG_HS_BASE,
+ .set_address_before_status = 1,
+ .rx_fifo_size = RX_FIFO_SIZE,
+};
+
+/** Initialize the USB device controller hardware of the STM32. */
+static usbd_device *stm32f207_usbd_init(void)
+{
+ OTG_HS_GINTSTS = OTG_HS_GINTSTS_MMIS;
+
+ OTG_HS_GUSBCFG |= OTG_HS_GUSBCFG_PHYSEL;
+ /* Enable VBUS sensing in device mode and power down the PHY. */
+ OTG_HS_GCCFG |= OTG_HS_GCCFG_VBUSBSEN | OTG_HS_GCCFG_PWRDWN;
+
+ /* Wait for AHB idle. */
+ while (!(OTG_HS_GRSTCTL & OTG_HS_GRSTCTL_AHBIDL)) ;
+ /* Do core soft reset. */
+ OTG_HS_GRSTCTL |= OTG_HS_GRSTCTL_CSRST;
+ while (OTG_HS_GRSTCTL & OTG_HS_GRSTCTL_CSRST) ;
+
+ /* Force peripheral only mode. */
+ OTG_HS_GUSBCFG |= OTG_HS_GUSBCFG_FDMOD | OTG_HS_GUSBCFG_TRDT_MASK;
+
+ /* Full speed device. */
+ OTG_HS_DCFG |= OTG_HS_DCFG_DSPD;
+
+ /* Restart the PHY clock. */
+ OTG_HS_PCGCCTL = 0;
+
+ OTG_HS_GRXFSIZ = stm32f207_usb_driver.rx_fifo_size;
+ usbd_dev.fifo_mem_top = stm32f207_usb_driver.rx_fifo_size;
+
+ /* Unmask interrupts for TX and RX. */
+ OTG_HS_GAHBCFG |= OTG_HS_GAHBCFG_GINT;
+ OTG_HS_GINTMSK = OTG_HS_GINTMSK_ENUMDNEM |
+ OTG_HS_GINTMSK_RXFLVLM |
+ OTG_HS_GINTMSK_IEPINT |
+ OTG_HS_GINTMSK_USBSUSPM |
+ OTG_HS_GINTMSK_WUIM |
+ OTG_HS_GINTMSK_SOFM;
+ OTG_HS_DAINTMSK = 0xF;
+ OTG_HS_DIEPMSK = OTG_HS_DIEPMSK_XFRCM;
+
+ return &usbd_dev;
+}
diff --git a/lib/usb/usb_fx07_common.c b/lib/usb/usb_fx07_common.c
new file mode 100644
index 0000000..9178092
--- /dev/null
+++ b/lib/usb/usb_fx07_common.c
@@ -0,0 +1,318 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * 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 <string.h>
+#include <libopencm3/cm3/common.h>
+#include <libopencm3/stm32/tools.h>
+#include <libopencm3/stm32/otg_fs.h>
+#include <libopencm3/stm32/otg_hs.h>
+#include <libopencm3/usb/usbd.h>
+#include "usb_private.h"
+#include "usb_fx07_common.h"
+
+/* The FS core and the HS core have the same register layout.
+ * As the code can be used on both cores, the registers offset is modified
+ * according to the selected cores base address. */
+#define dev_base_address (usbd_dev->driver->base_address)
+#define REBASE(x) MMIO32((x)+(dev_base_address))
+#define REBASE_FIFO(x) ((volatile u32*)((dev_base_address) + (OTG_FIFO(x))))
+
+void stm32fx07_set_address(usbd_device *usbd_dev, u8 addr)
+{
+ REBASE(OTG_DCFG) = (REBASE(OTG_DCFG) & ~OTG_FS_DCFG_DAD) | (addr << 4);
+}
+
+void stm32fx07_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size,
+ void (*callback) (usbd_device *usbd_dev, u8 ep))
+{
+ /*
+ * Configure endpoint address and type. Allocate FIFO memory for
+ * endpoint. Install callback funciton.
+ */
+ u8 dir = addr & 0x80;
+ addr &= 0x7f;
+
+ if (addr == 0) { /* For the default control endpoint */
+ /* Configure IN part. */
+ if (max_size >= 64) {
+ REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_64;
+ } else if (max_size >= 32) {
+ REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_32;
+ } else if (max_size >= 16) {
+ REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_16;
+ } else {
+ REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_8;
+ }
+ REBASE(OTG_DIEPTSIZ0) =
+ (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
+ REBASE(OTG_DIEPCTL0) |=
+ OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK;
+
+ /* Configure OUT part. */
+ usbd_dev->doeptsiz[0] = OTG_FS_DIEPSIZ0_STUPCNT_1 |
+ OTG_FS_DIEPSIZ0_PKTCNT |
+ (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
+ REBASE(OTG_DOEPTSIZ(0)) = usbd_dev->doeptsiz[0];
+ REBASE(OTG_DOEPCTL(0)) |=
+ OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK;
+
+ REBASE(OTG_GNPTXFSIZ) = ((max_size / 4) << 16) |
+ usbd_dev->driver->rx_fifo_size;
+ usbd_dev->fifo_mem_top += max_size / 4;
+ usbd_dev->fifo_mem_top_ep0 = usbd_dev->fifo_mem_top;
+
+ return;
+ }
+
+ if (dir) {
+ REBASE(OTG_DIEPTXF(addr)) = ((max_size / 4) << 16) |
+ usbd_dev->fifo_mem_top;
+ usbd_dev->fifo_mem_top += max_size / 4;
+
+ REBASE(OTG_DIEPTSIZ(addr)) =
+ (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
+ REBASE(OTG_DIEPCTL(addr)) |=
+ OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK | (type << 18)
+ | OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID
+ | (addr << 22) | max_size;
+
+ if (callback) {
+ usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] =
+ (void *)callback;
+ }
+ }
+
+ if (!dir) {
+ usbd_dev->doeptsiz[addr] = OTG_FS_DIEPSIZ0_PKTCNT |
+ (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
+ REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr];
+ REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_EPENA |
+ OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK |
+ OTG_FS_DOEPCTLX_SD0PID | (type << 18) | max_size;
+
+ if (callback) {
+ usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] =
+ (void *)callback;
+ }
+ }
+}
+
+void stm32fx07_endpoints_reset(usbd_device *usbd_dev)
+{
+ /* The core resets the endpoints automatically on reset. */
+ usbd_dev->fifo_mem_top = usbd_dev->fifo_mem_top_ep0;
+}
+
+void stm32fx07_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall)
+{
+ if (addr == 0) {
+ if (stall)
+ REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_STALL;
+ else
+ REBASE(OTG_DIEPCTL(addr)) &= ~OTG_FS_DIEPCTL0_STALL;
+ }
+
+ if (addr & 0x80) {
+ addr &= 0x7F;
+
+ if (stall) {
+ REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_STALL;
+ } else {
+ REBASE(OTG_DIEPCTL(addr)) &= ~OTG_FS_DIEPCTL0_STALL;
+ REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTLX_SD0PID;
+ }
+ } else {
+ if (stall) {
+ REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_STALL;
+ } else {
+ REBASE(OTG_DOEPCTL(addr)) &= ~OTG_FS_DOEPCTL0_STALL;
+ REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTLX_SD0PID;
+ }
+ }
+}
+
+u8 stm32fx07_ep_stall_get(usbd_device *usbd_dev, u8 addr)
+{
+ /* Return non-zero if STALL set. */
+ if (addr & 0x80)
+ return (REBASE(OTG_DIEPCTL(addr & 0x7f)) &
+ OTG_FS_DIEPCTL0_STALL) ? 1 : 0;
+ else
+ return (REBASE(OTG_DOEPCTL(addr)) &
+ OTG_FS_DOEPCTL0_STALL) ? 1 : 0;
+}
+
+void stm32fx07_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak)
+{
+ /* It does not make sence to force NAK on IN endpoints. */
+ if (addr & 0x80)
+ return;
+
+ usbd_dev->force_nak[addr] = nak;
+
+ if (nak)
+ REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_SNAK;
+ else
+ REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_CNAK;
+}
+
+u16 stm32fx07_ep_write_packet(usbd_device *usbd_dev, u8 addr,
+ const void *buf, u16 len)
+{
+ const u32 *buf32 = buf;
+ int i;
+
+ addr &= 0x7F;
+
+ /* Return if endpoint is already enabled. */
+ if (REBASE(OTG_DIEPTSIZ(addr)) & OTG_FS_DIEPSIZ0_PKTCNT)
+ return 0;
+
+ /* Enable endpoint for transmission. */
+ REBASE(OTG_DIEPTSIZ(addr)) = OTG_FS_DIEPSIZ0_PKTCNT | len;
+ REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_EPENA |
+ OTG_FS_DIEPCTL0_CNAK;
+ volatile u32 *fifo = REBASE_FIFO(addr);
+
+ /* Copy buffer to endpoint FIFO, note - memcpy does not work */
+ for (i = len; i > 0; i -= 4)
+ *fifo++ = *buf32++;
+
+ return len;
+}
+
+u16 stm32fx07_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, u16 len)
+{
+ int i;
+ u32 *buf32 = buf;
+ u32 extra;
+
+ len = MIN(len, usbd_dev->rxbcnt);
+ usbd_dev->rxbcnt -= len;
+
+ volatile u32 *fifo = REBASE_FIFO(addr);
+ for (i = len; i >= 4; i -= 4)
+ *buf32++ = *fifo++;
+
+ if (i) {
+ extra = *fifo++;
+ memcpy(buf32, &extra, i);
+ }
+
+ REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr];
+ REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_EPENA |
+ (usbd_dev->force_nak[addr] ?
+ OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK);
+
+ return len;
+}
+
+void stm32fx07_poll(usbd_device *usbd_dev)
+{
+ /* Read interrupt status register. */
+ u32 intsts = REBASE(OTG_GINTSTS);
+ int i;
+
+ if (intsts & OTG_FS_GINTSTS_ENUMDNE) {
+ /* Handle USB RESET condition. */
+ REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_ENUMDNE;
+ usbd_dev->fifo_mem_top = usbd_dev->driver->rx_fifo_size;
+ _usbd_reset(usbd_dev);
+ return;
+ }
+
+ /* Note: RX and TX handled differently in this device. */
+ if (intsts & OTG_FS_GINTSTS_RXFLVL) {
+ /* Receive FIFO non-empty. */
+ u32 rxstsp = REBASE(OTG_GRXSTSP);
+ u32 pktsts = rxstsp & OTG_FS_GRXSTSP_PKTSTS_MASK;
+ if ((pktsts != OTG_FS_GRXSTSP_PKTSTS_OUT) &&
+ (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP))
+ return;
+
+ u8 ep = rxstsp & OTG_FS_GRXSTSP_EPNUM_MASK;
+ u8 type;
+ if (pktsts == OTG_FS_GRXSTSP_PKTSTS_SETUP)
+ type = USB_TRANSACTION_SETUP;
+ else
+ type = USB_TRANSACTION_OUT;
+
+ /* Save packet size for stm32f107_ep_read_packet(). */
+ usbd_dev->rxbcnt = (rxstsp & OTG_FS_GRXSTSP_BCNT_MASK) >> 4;
+
+ /*
+ * FIXME: Why is a delay needed here?
+ * This appears to fix a problem where the first 4 bytes
+ * of the DATA OUT stage of a control transaction are lost.
+ */
+ for (i = 0; i < 1000; i++)
+ __asm__("nop");
+
+ if (usbd_dev->user_callback_ctr[ep][type])
+ usbd_dev->user_callback_ctr[ep][type] (usbd_dev, ep);
+
+ /* Discard unread packet data. */
+ for (i = 0; i < usbd_dev->rxbcnt; i += 4)
+ (void)*REBASE_FIFO(ep);
+
+ usbd_dev->rxbcnt = 0;
+ }
+
+ /*
+ * There is no global interrupt flag for transmit complete.
+ * The XFRC bit must be checked in each OTG_FS_DIEPINT(x).
+ */
+ for (i = 0; i < 4; i++) { /* Iterate over endpoints. */
+ if (REBASE(OTG_DIEPINT(i)) & OTG_FS_DIEPINTX_XFRC) {
+ /* Transfer complete. */
+ if (usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN])
+ usbd_dev->user_callback_ctr[i]
+ [USB_TRANSACTION_IN](usbd_dev, i);
+
+ REBASE(OTG_DIEPINT(i)) = OTG_FS_DIEPINTX_XFRC;
+ }
+ }
+
+ if (intsts & OTG_FS_GINTSTS_USBSUSP) {
+ if (usbd_dev->user_callback_suspend)
+ usbd_dev->user_callback_suspend();
+ REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_USBSUSP;
+ }
+
+ if (intsts & OTG_FS_GINTSTS_WKUPINT) {
+ if (usbd_dev->user_callback_resume)
+ usbd_dev->user_callback_resume();
+ REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_WKUPINT;
+ }
+
+ if (intsts & OTG_FS_GINTSTS_SOF) {
+ if (usbd_dev->user_callback_sof)
+ usbd_dev->user_callback_sof();
+ REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_SOF;
+ }
+}
+
+void stm32fx07_disconnect(usbd_device *usbd_dev, bool disconnected)
+{
+ if (disconnected) {
+ REBASE(OTG_DCTL) |= OTG_FS_DCTL_SDIS;
+ } else {
+ REBASE(OTG_DCTL) &= ~OTG_FS_DCTL_SDIS;
+ }
+}
diff --git a/lib/usb/usb_fx07_common.h b/lib/usb/usb_fx07_common.h
new file mode 100644
index 0000000..4d8d38e
--- /dev/null
+++ b/lib/usb/usb_fx07_common.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * 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/>.
+ */
+
+#ifndef __USB_FX07_COMMON_H_
+#define __USB_FX07_COMMON_H_
+
+void stm32fx07_set_address(usbd_device *usbd_dev, u8 addr);
+void stm32fx07_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size,
+ void (*callback)(usbd_device *usbd_dev, u8 ep));
+void stm32fx07_endpoints_reset(usbd_device *usbd_dev);
+void stm32fx07_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall);
+u8 stm32fx07_ep_stall_get(usbd_device *usbd_dev, u8 addr);
+void stm32fx07_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak);
+u16 stm32fx07_ep_write_packet(usbd_device *usbd_dev, u8 addr, const void *buf,
+ u16 len);
+u16 stm32fx07_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf,
+ u16 len);
+void stm32fx07_poll(usbd_device *usbd_dev);
+void stm32fx07_disconnect(usbd_device *usbd_dev, bool disconnected);
+
+
+#endif /* __USB_FX07_COMMON_H_ */
diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h
index 238f14f..454e8c6 100644
--- a/lib/usb/usb_private.h
+++ b/lib/usb/usb_private.h
@@ -25,7 +25,7 @@
#define MIN(a, b) ((a)<(b) ? (a) : (b))
/** Internal collection of device information. */
-extern struct _usbd_device {
+struct _usbd_device {
const struct usb_device_descriptor *desc;
const struct usb_config_descriptor *config;
const char **strings;
@@ -45,19 +45,49 @@ extern struct _usbd_device {
void (*user_callback_resume)(void);
void (*user_callback_sof)(void);
+ struct usb_control_state {
+ enum {
+ IDLE, STALLED,
+ DATA_IN, LAST_DATA_IN, STATUS_IN,
+ DATA_OUT, LAST_DATA_OUT, STATUS_OUT,
+ } state;
+ struct usb_setup_data req __attribute__((aligned(4)));
+ u8 *ctrl_buf;
+ u16 ctrl_len;
+ void (*complete)(usbd_device *usbd_dev,
+ struct usb_setup_data *req);
+ } control_state;
+
struct user_control_callback {
usbd_control_callback cb;
u8 type;
u8 type_mask;
} user_control_callback[MAX_USER_CONTROL_CALLBACK];
- void (*user_callback_ctr[8][3])(u8 ea);
+ void (*user_callback_ctr[8][3])(usbd_device *usbd_dev, u8 ea);
/* User callback function for some standard USB function hooks */
- void (*user_callback_set_config)(u16 wValue);
+ void (*user_callback_set_config)(usbd_device *usbd_dev, u16 wValue);
const struct _usbd_driver *driver;
-} _usbd_device;
+
+ /* private driver data */
+
+ uint16_t fifo_mem_top;
+ uint16_t fifo_mem_top_ep0;
+ u8 force_nak[4];
+ /*
+ * We keep a backup copy of the out endpoint size registers to restore them
+ * after a transaction.
+ */
+ u32 doeptsiz[4];
+ /*
+ * Received packet size for each endpoint. This is assigned in
+ * stm32f107_poll() which reads the packet status push register GRXSTSP
+ * for use in stm32f107_ep_read_packet().
+ */
+ uint16_t rxbcnt;
+};
enum _usbd_transaction {
USB_TRANSACTION_IN,
@@ -65,31 +95,34 @@ enum _usbd_transaction {
USB_TRANSACTION_SETUP,
};
-void _usbd_control_in(u8 ea);
-void _usbd_control_out(u8 ea);
-void _usbd_control_setup(u8 ea);
+void _usbd_control_in(usbd_device *usbd_dev, u8 ea);
+void _usbd_control_out(usbd_device *usbd_dev, u8 ea);
+void _usbd_control_setup(usbd_device *usbd_dev, u8 ea);
-int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len);
+int _usbd_standard_request(usbd_device *usbd_dev, struct usb_setup_data *req,
+ u8 **buf, u16 *len);
-void _usbd_reset(void);
+void _usbd_reset(usbd_device *usbd_dev);
/* Functions provided by the hardware abstraction. */
struct _usbd_driver {
- void (*init)(void);
- void (*set_address)(u8 addr);
- void (*ep_setup)(u8 addr, u8 type, u16 max_size, void (*cb)(u8 ep));
- void (*ep_reset)(void);
- void (*ep_stall_set)(u8 addr, u8 stall);
- void (*ep_nak_set)(u8 addr, u8 nak);
- u8 (*ep_stall_get)(u8 addr);
- u16 (*ep_write_packet)(u8 addr, const void *buf, u16 len);
- u16 (*ep_read_packet)(u8 addr, void *buf, u16 len);
- void (*poll)(void);
- void (*disconnect)(bool disconnected);
+ usbd_device *(*init)(void);
+ void (*set_address)(usbd_device *usbd_dev, u8 addr);
+ void (*ep_setup)(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size,
+ void (*cb)(usbd_device *usbd_dev, u8 ep));
+ void (*ep_reset)(usbd_device *usbd_dev);
+ void (*ep_stall_set)(usbd_device *usbd_dev, u8 addr, u8 stall);
+ void (*ep_nak_set)(usbd_device *usbd_dev, u8 addr, u8 nak);
+ u8 (*ep_stall_get)(usbd_device *usbd_dev, u8 addr);
+ u16 (*ep_write_packet)(usbd_device *usbd_dev, u8 addr, const void *buf,
+ u16 len);
+ u16 (*ep_read_packet)(usbd_device *usbd_dev, u8 addr, void *buf,
+ u16 len);
+ void (*poll)(usbd_device *usbd_dev);
+ void (*disconnect)(usbd_device *usbd_dev, bool disconnected);
+ u32 base_address;
+ bool set_address_before_status;
+ u16 rx_fifo_size;
};
-#define _usbd_hw_init() _usbd_device.driver->init()
-#define _usbd_hw_set_address(addr) _usbd_device.driver->set_address(addr)
-#define _usbd_hw_endpoints_reset() _usbd_device.driver->ep_reset()
-
#endif
diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c
index 08923d8..e14fee3 100644
--- a/lib/usb/usb_standard.c
+++ b/lib/usb/usb_standard.c
@@ -21,15 +21,18 @@
#include <libopencm3/usb/usbd.h>
#include "usb_private.h"
-void usbd_register_set_config_callback(void (*callback)(u16 wValue))
+void usbd_register_set_config_callback(usbd_device *usbd_dev,
+ void (*callback)(usbd_device *usbd_dev,
+ u16 wValue))
{
- _usbd_device.user_callback_set_config = callback;
+ usbd_dev->user_callback_set_config = callback;
}
-static u16 build_config_descriptor(u8 index, u8 *buf, u16 len)
+static u16 build_config_descriptor(usbd_device *usbd_dev,
+ u8 index, u8 *buf, u16 len)
{
u8 *tmpbuf = buf;
- const struct usb_config_descriptor *cfg = &_usbd_device.config[index];
+ const struct usb_config_descriptor *cfg = &usbd_dev->config[index];
u16 count, total = 0, totallen = 0;
u16 i, j, k;
@@ -43,7 +46,7 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len)
for (i = 0; i < cfg->bNumInterfaces; i++) {
/* Interface Association Descriptor, if any */
if (cfg->interface[i].iface_assoc) {
- const struct usb_iface_assoc_descriptor *assoc =
+ const struct usb_iface_assoc_descriptor *assoc =
cfg->interface[i].iface_assoc;
memcpy(buf, assoc, count = MIN(len, assoc->bLength));
buf += count;
@@ -97,7 +100,8 @@ static int usb_descriptor_index(u16 wValue)
return wValue & 0xFF;
}
-static int usb_standard_get_descriptor(struct usb_setup_data *req,
+static int usb_standard_get_descriptor(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
int i, array_idx, descr_idx;
@@ -107,15 +111,15 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
switch (usb_descriptor_type(req->wValue)) {
case USB_DT_DEVICE:
- *buf = (u8 *) _usbd_device.desc;
- *len = MIN(*len, _usbd_device.desc->bLength);
+ *buf = (u8 *) usbd_dev->desc;
+ *len = MIN(*len, usbd_dev->desc->bLength);
return USBD_REQ_HANDLED;
case USB_DT_CONFIGURATION:
- *buf = _usbd_device.ctrl_buf;
- *len = build_config_descriptor(descr_idx, *buf, *len);
+ *buf = usbd_dev->ctrl_buf;
+ *len = build_config_descriptor(usbd_dev, descr_idx, *buf, *len);
return USBD_REQ_HANDLED;
case USB_DT_STRING:
- sd = (struct usb_string_descriptor *)_usbd_device.ctrl_buf;
+ sd = (struct usb_string_descriptor *)usbd_dev->ctrl_buf;
if (descr_idx == 0) {
/* Send sane Language ID descriptor... */
@@ -127,10 +131,10 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
} else {
array_idx = descr_idx - 1;
- if (!_usbd_device.strings)
+ if (!usbd_dev->strings)
return USBD_REQ_NOTSUPP; /* Device doesn't support strings. */
/* Check that string index is in range. */
- if (array_idx >= _usbd_device.num_strings)
+ if (array_idx >= usbd_dev->num_strings)
return USBD_REQ_NOTSUPP;
/* Strings with Language ID differnet from
@@ -139,14 +143,14 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
return USBD_REQ_NOTSUPP;
/* Ths string is returned as UTF16, hence the multiplication */
- sd->bLength = strlen(_usbd_device.strings[array_idx]) * 2 +
+ sd->bLength = strlen(usbd_dev->strings[array_idx]) * 2 +
sizeof(sd->bLength) + sizeof(sd->bDescriptorType);
*len = MIN(*len, sd->bLength);
for (i = 0; i < (*len / 2) - 1; i++)
sd->wData[i] =
- _usbd_device.strings[array_idx][i];
+ usbd_dev->strings[array_idx][i];
}
sd->bDescriptorType = USB_DT_STRING;
@@ -157,7 +161,8 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
return USBD_REQ_NOTSUPP;
}
-static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf,
+static int usb_standard_set_address(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf,
u16 *len)
{
(void)req;
@@ -168,19 +173,20 @@ static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf,
if ((req->bmRequestType != 0) || (req->wValue >= 128))
return 0;
- _usbd_device.current_address = req->wValue;
+ usbd_dev->current_address = req->wValue;
/*
* Special workaround for STM32F10[57] that require the address
* to be set here. This is undocumented!
*/
- if (_usbd_device.driver == &stm32f107_usb_driver)
- _usbd_device.driver->set_address(req->wValue);
+ if ( usbd_dev->driver->set_address_before_status)
+ usbd_dev->driver->set_address(usbd_dev, req->wValue);
return 1;
}
-static int usb_standard_set_configuration(struct usb_setup_data *req,
+static int usb_standard_set_configuration(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
int i;
@@ -190,43 +196,46 @@ static int usb_standard_set_configuration(struct usb_setup_data *req,
(void)len;
/* Is this correct, or should we reset alternate settings. */
- if (req->wValue == _usbd_device.current_config)
+ if (req->wValue == usbd_dev->current_config)
return 1;
- _usbd_device.current_config = req->wValue;
+ usbd_dev->current_config = req->wValue;
/* Reset all endpoints. */
- _usbd_hw_endpoints_reset();
+ usbd_dev->driver->ep_reset(usbd_dev);
- if (_usbd_device.user_callback_set_config) {
+ if (usbd_dev->user_callback_set_config) {
/*
* Flush control callbacks. These will be reregistered
* by the user handler.
*/
for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++)
- _usbd_device.user_control_callback[i].cb = NULL;
+ usbd_dev->user_control_callback[i].cb = NULL;
- _usbd_device.user_callback_set_config(req->wValue);
+ usbd_dev->user_callback_set_config(usbd_dev, req->wValue);
}
return 1;
}
-static int usb_standard_get_configuration(struct usb_setup_data *req,
+static int usb_standard_get_configuration(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
(void)req;
if (*len > 1)
*len = 1;
- (*buf)[0] = _usbd_device.current_config;
+ (*buf)[0] = usbd_dev->current_config;
return 1;
}
-static int usb_standard_set_interface(struct usb_setup_data *req,
+static int usb_standard_set_interface(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
+ (void)usbd_dev;
(void)req;
(void)buf;
@@ -238,9 +247,11 @@ static int usb_standard_set_interface(struct usb_setup_data *req,
return 1;
}
-static int usb_standard_get_interface(struct usb_setup_data *req,
+static int usb_standard_get_interface(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
+ (void)usbd_dev;
(void)req;
(void)buf;
@@ -251,9 +262,11 @@ static int usb_standard_get_interface(struct usb_setup_data *req,
return 1;
}
-static int usb_standard_device_get_status(struct usb_setup_data *req,
+static int usb_standard_device_get_status(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
+ (void)usbd_dev;
(void)req;
/* bit 0: self powered */
@@ -266,9 +279,11 @@ static int usb_standard_device_get_status(struct usb_setup_data *req,
return 1;
}
-static int usb_standard_interface_get_status(struct usb_setup_data *req,
+static int usb_standard_interface_get_status(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
+ (void)usbd_dev;
(void)req;
/* not defined */
@@ -280,45 +295,50 @@ static int usb_standard_interface_get_status(struct usb_setup_data *req,
return 1;
}
-static int usb_standard_endpoint_get_status(struct usb_setup_data *req,
+static int usb_standard_endpoint_get_status(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
(void)req;
if (*len > 2)
*len = 2;
- (*buf)[0] = usbd_ep_stall_get(req->wIndex) ? 1 : 0;
+ (*buf)[0] = usbd_ep_stall_get(usbd_dev, req->wIndex) ? 1 : 0;
(*buf)[1] = 0;
return 1;
}
-static int usb_standard_endpoint_stall(struct usb_setup_data *req,
+static int usb_standard_endpoint_stall(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
(void)buf;
(void)len;
- usbd_ep_stall_set(req->wIndex, 1);
+ usbd_ep_stall_set(usbd_dev, req->wIndex, 1);
return 1;
}
-static int usb_standard_endpoint_unstall(struct usb_setup_data *req,
+static int usb_standard_endpoint_unstall(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
(void)buf;
(void)len;
- usbd_ep_stall_set(req->wIndex, 0);
+ usbd_ep_stall_set(usbd_dev, req->wIndex, 0);
return 1;
}
-int _usbd_standard_request_device(struct usb_setup_data *req, u8 **buf,
+int _usbd_standard_request_device(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf,
u16 *len)
{
- int (*command)(struct usb_setup_data *req, u8 **buf, u16 *len) = NULL;
+ int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req, u8
+ **buf, u16 *len) = NULL;
switch (req->bRequest) {
case USB_REQ_CLEAR_FEATURE:
@@ -361,13 +381,15 @@ int _usbd_standard_request_device(struct usb_setup_data *req, u8 **buf,
if (!command)
return 0;
- return command(req, buf, len);
+ return command(usbd_dev, req, buf, len);
}
-int _usbd_standard_request_interface(struct usb_setup_data *req, u8 **buf,
+int _usbd_standard_request_interface(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf,
u16 *len)
{
- int (*command)(struct usb_setup_data *req, u8 **buf, u16 *len) = NULL;
+ int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req,
+ u8 **buf, u16 *len) = NULL;
switch (req->bRequest) {
case USB_REQ_CLEAR_FEATURE:
@@ -388,13 +410,15 @@ int _usbd_standard_request_interface(struct usb_setup_data *req, u8 **buf,
if (!command)
return 0;
- return command(req, buf, len);
+ return command(usbd_dev, req, buf, len);
}
-int _usbd_standard_request_endpoint(struct usb_setup_data *req, u8 **buf,
+int _usbd_standard_request_endpoint(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf,
u16 *len)
{
- int (*command) (struct usb_setup_data *req, u8 **buf, u16 *len) = NULL;
+ int (*command) (usbd_device *usbd_dev, struct usb_setup_data *req,
+ u8 **buf, u16 *len) = NULL;
switch (req->bRequest) {
case USB_REQ_CLEAR_FEATURE:
@@ -420,10 +444,11 @@ int _usbd_standard_request_endpoint(struct usb_setup_data *req, u8 **buf,
if (!command)
return 0;
- return command(req, buf, len);
+ return command(usbd_dev, req, buf, len);
}
-int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len)
+int _usbd_standard_request(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf, u16 *len)
{
/* FIXME: Have class/vendor requests as well. */
if ((req->bmRequestType & USB_REQ_TYPE_TYPE) != USB_REQ_TYPE_STANDARD)
@@ -431,11 +456,12 @@ int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len)
switch (req->bmRequestType & USB_REQ_TYPE_RECIPIENT) {
case USB_REQ_TYPE_DEVICE:
- return _usbd_standard_request_device(req, buf, len);
+ return _usbd_standard_request_device(usbd_dev, req, buf, len);
case USB_REQ_TYPE_INTERFACE:
- return _usbd_standard_request_interface(req, buf, len);
+ return _usbd_standard_request_interface(usbd_dev, req,
+ buf, len);
case USB_REQ_TYPE_ENDPOINT:
- return _usbd_standard_request_endpoint(req, buf, len);
+ return _usbd_standard_request_endpoint(usbd_dev, req, buf, len);
default:
return 0;
}
diff --git a/scripts/irq2nvic_h b/scripts/irq2nvic_h
new file mode 100755
index 0000000..d1a8a40
--- /dev/null
+++ b/scripts/irq2nvic_h
@@ -0,0 +1,176 @@
+#!/usr/bin/env python
+
+# 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/>.
+
+"""Generate an nvic.h header from a small YAML file describing the interrupt
+numbers.
+
+Code generation is chosen here because the resulting C code needs to be very
+repetetive (definition of the IRQ numbers, function prototypes, weak fallback
+definition and vector table definition), all being very repetitive. No portable
+method to achive the same thing with C preprocessor is known to the author.
+(Neither is any non-portable method, for that matter.)"""
+
+import sys
+import os
+import os.path
+import yaml
+
+template_nvic_h = '''\
+/* This file is part of the libopencm3 project.
+ *
+ * It was generated by the irq2nvic_h script.
+ */
+
+#ifndef {includeguard}
+#define {includeguard}
+
+#include <libopencm3/cm3/nvic.h>
+
+/** @defgroup CM3_nvic_defines_{partname_doxygen} User interrupts for {partname_humanreadable}
+ @ingroup CM3_nvic_defines
+
+ @{{*/
+
+{irqdefinitions}
+
+#define NVIC_IRQ_COUNT {irqcount}
+
+/**@}}*/
+
+#define WEAK __attribute__ ((weak))
+
+/** @defgroup CM3_nvic_isrprototypes_{partname_doxygen} User interrupt service routines (ISR) prototypes for {partname_humanreadable}
+ @ingroup CM3_nvic_isrprototypes
+
+ @{{*/
+
+BEGIN_DECLS
+
+{isrprototypes}
+
+END_DECLS
+
+/**@}}*/
+
+#endif /* {includeguard} */
+'''
+
+template_vector_nvic_c = '''\
+/* This file is part of the libopencm3 project.
+ *
+ * It was generated by the irq2nvic_h script.
+ *
+ * This part needs to get included in the compilation unit where
+ * blocking_handler gets defined due to the way #pragma works.
+ */
+
+
+/** @defgroup CM3_nvic_isrpragmas_{partname_doxygen} User interrupt service routines (ISR) defaults for {partname_humanreadable}
+ @ingroup CM3_nvic_isrpragmas
+
+ @{{*/
+
+{isrpragmas}
+
+/**@}}*/
+
+/* Initialization template for the interrupt vector table. This definition is
+ * used by the startup code generator (vector.c) to set the initial values for
+ * the interrupt handling routines to the chip family specific _isr weak
+ * symbols. */
+
+#define IRQ_HANDLERS \\
+ {vectortableinitialization}
+'''
+
+template_cmsis_h = '''\
+/* This file is part of the libopencm3 project.
+ *
+ * It was generated by the irq2nvic_h script.
+ *
+ * These definitions bend every interrupt handler that is defined CMSIS style
+ * to the weak symbol exported by libopenmc3.
+ */
+
+{cmsisbends}
+'''
+
+def convert(infile, outfile_nvic, outfile_vectornvic, outfile_cmsis):
+ data = yaml.load(infile)
+
+ irq2name = list(enumerate(data['irqs']) if isinstance(data['irqs'], list) else data['irqs'].items())
+ irqnames = [v for (k,v) in irq2name]
+
+ if isinstance(data['irqs'], list):
+ data['irqcount'] = len(irq2name)
+ else:
+ data['irqcount'] = max(data['irqs'].keys()) + 1
+
+ data['irqdefinitions'] = "\n".join('#define NVIC_%s_IRQ %d'%(v.upper(),k) for (k,v) in irq2name)
+ data['isrprototypes'] = "\n".join('void WEAK %s_isr(void);'%name.lower() for name in irqnames)
+ data['isrpragmas'] = "\n".join('#pragma weak %s_isr = blocking_handler'%name.lower() for name in irqnames)
+ data['vectortableinitialization'] = ', \\\n '.join('[NVIC_%s_IRQ] = %s_isr'%(name.upper(), name.lower()) for name in irqnames)
+ data['cmsisbends'] = "\n".join("#define %s_IRQHandler %s_isr"%(name.upper(), name.lower()) for name in irqnames)
+
+ outfile_nvic.write(template_nvic_h.format(**data))
+ outfile_vectornvic.write(template_vector_nvic_c.format(**data))
+ outfile_cmsis.write(template_cmsis_h.format(**data))
+
+def makeparentdir(filename):
+ try:
+ os.makedirs(os.path.dirname(filename))
+ except OSError:
+ # where is my 'mkdir -p'?
+ pass
+
+def needs_update(infiles, outfiles):
+ timestamp = lambda filename: os.stat(filename).st_mtime
+ return any(not os.path.exists(o) for o in outfiles) or max(map(timestamp, infiles)) > min(map(timestamp, outfiles))
+
+def main():
+ if sys.argv[1] == '--remove':
+ remove = True
+ del sys.argv[1]
+ else:
+ remove = False
+ infile = sys.argv[1]
+ if not infile.startswith('./include/libopencm3/') or not infile.endswith('/irq.yaml'):
+ raise ValueError("Arguent must match ./include/libopencm3/**/irq.yaml")
+ nvic_h = infile.replace('irq.yaml', 'nvic.h')
+ vector_nvic_c = infile.replace('./include/libopencm3/', './lib/').replace('irq.yaml', 'vector_nvic.c')
+ cmsis = infile.replace('irq.yaml', 'irqhandlers.h').replace('/libopencm3/', '/libopencmsis/')
+
+ if remove:
+ if os.path.exists(nvic_h):
+ os.unlink(nvic_h)
+ if os.path.exists(vector_nvic_c):
+ os.unlink(vector_nvic_c)
+ sys.exit(0)
+
+ if not needs_update([__file__, infile], [nvic_h, vector_nvic_c]):
+ sys.exit(0)
+
+ makeparentdir(nvic_h)
+ makeparentdir(vector_nvic_c)
+ makeparentdir(cmsis)
+
+ convert(open(infile), open(nvic_h, 'w'), open(vector_nvic_c, 'w'), open(cmsis, 'w'))
+
+if __name__ == "__main__":
+ main()