diff --git a/.gitignore b/.gitignore index f0c86ce4..63b7b481 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ *.swp \#* .\#* +*~ +*.map +*.log +doxygen/ diff --git a/Doxyfile b/Doxyfile index beb5dda3..0cad2c40 100644 --- a/Doxyfile +++ b/Doxyfile @@ -610,7 +610,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = examples include lib +INPUT = include lib # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -640,7 +640,7 @@ RECURSIVE = YES # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -654,7 +654,7 @@ EXCLUDE_SYMLINKS = NO # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = *.d +EXCLUDE_PATTERNS = */*.d # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -1079,12 +1079,12 @@ ENUM_VALUES_PER_LINE = 4 # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. -GENERATE_TREEVIEW = NO +GENERATE_TREEVIEW = YES # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. -USE_INLINE_TREES = NO +USE_INLINE_TREES = YES # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree diff --git a/DoxygenLayout.xml b/DoxygenLayout.xml new file mode 100644 index 00000000..1a3be6ff --- /dev/null +++ b/DoxygenLayout.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Makefile b/Makefile index 931e2471..c59e5aa4 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,8 @@ LIBDIR = $(DESTDIR)/$(PREFIX)/lib SHAREDIR = $(DESTDIR)/$(PREFIX)/share/libopencm3/scripts INSTALL = install -TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lpc17xx lm3s efm32/tinygecko +SRCLIBDIR = $(shell pwd)/lib +TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lpc17xx lpc43xx lm3s efm32/tinygecko # Be silent per default, but 'make V=1' will show all compiler calls. ifneq ($(V),1) @@ -42,7 +43,7 @@ lib: $(Q)for i in $(addprefix $@/,$(TARGETS)); do \ if [ -d $$i ]; then \ printf " BUILD $$i\n"; \ - $(MAKE) -C $$i || exit $?; \ + $(MAKE) -C $$i SRCLIBDIR=$(SRCLIBDIR) || exit $?; \ fi; \ done @@ -61,9 +62,9 @@ install: lib $(Q)$(INSTALL) -d $(SHAREDIR) $(Q)cp -r include/libopencm3/* $(INCDIR)/libopencm3 @printf " INSTALL libs\n" - $(Q)$(INSTALL) -m 0644 lib/*/*/*.a $(LIBDIR) + $(Q)$(INSTALL) -m 0644 lib/*.a $(LIBDIR) @printf " INSTALL ldscripts\n" - $(Q)$(INSTALL) -m 0644 lib/*/*/*.ld $(LIBDIR) + $(Q)$(INSTALL) -m 0644 lib/*.ld $(LIBDIR) @printf " INSTALL scripts\n" $(Q)$(INSTALL) -m 0644 scripts/* $(SHAREDIR) @@ -75,7 +76,7 @@ clean: $(addsuffix /*/*,$(addprefix examples/,$(TARGETS))); do \ if [ -d $$i ]; then \ printf " CLEAN $$i\n"; \ - $(MAKE) -C $$i clean || exit $?; \ + $(MAKE) -C $$i clean SRCLIBDIR=$(SRCLIBDIR) || exit $?; \ fi; \ done @printf " CLEAN doxygen\n" diff --git a/examples/lm3s/Makefile.include b/examples/lm3s/Makefile.include index b850d576..0e18bd62 100644 --- a/examples/lm3s/Makefile.include +++ b/examples/lm3s/Makefile.include @@ -24,13 +24,18 @@ CC = $(PREFIX)-gcc LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump -# Uncomment this line if you want to use the installed (not local) library. -# TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -TOOLCHAIN_DIR = ../../../.. +ifeq ($(wildcard ../../../../lib/libopencm3_lm3s.a),) +TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +else +ifeq ($(V),1) +$(info We seem to be building the example in the source directory. Using local library!) +endif +TOOLCHAIN_DIR := ../../../.. +endif CFLAGS += -O0 -g3 -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ -mcpu=cortex-m3 -mthumb -MD LDSCRIPT ?= $(BINARY).ld -LDFLAGS += -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/lm3s \ +LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections OBJS += $(BINARY).o @@ -75,7 +80,7 @@ flash: $(BINARY).flash @#printf " OBJDUMP $(*).list\n" $(Q)$(OBJDUMP) -S $(*).elf > $(*).list -%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/lm3s/libopencm3_lm3s.a +%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_lm3s.a @#printf " LD $(subst $(shell pwd)/,,$(@))\n" $(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJS) -lopencm3_lm3s diff --git a/examples/lpc13xx/Makefile.include b/examples/lpc13xx/Makefile.include index 1db02e99..cc668f89 100644 --- a/examples/lpc13xx/Makefile.include +++ b/examples/lpc13xx/Makefile.include @@ -24,13 +24,18 @@ CC = $(PREFIX)-gcc LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump -# Uncomment this line if you want to use the installed (not local) library. -# TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -TOOLCHAIN_DIR = ../../../.. +ifeq ($(wildcard ../../../../lib/libopencm3_lpc13xx.a),) +TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +else +ifeq ($(V),1) +$(info We seem to be building the example in the source directory. Using local library!) +endif +TOOLCHAIN_DIR := ../../../.. +endif CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ -mcpu=cortex-m3 -mthumb -MD LDSCRIPT ?= $(BINARY).ld -LDFLAGS += -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/lpc13xx \ +LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections OBJS += $(BINARY).o @@ -75,7 +80,7 @@ flash: $(BINARY).flash @#printf " OBJDUMP $(*).list\n" $(Q)$(OBJDUMP) -S $(*).elf > $(*).list -%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/lpc13xx/libopencm3_lpc13xx.a +%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_lpc13xx.a @#printf " LD $(subst $(shell pwd)/,,$(@))\n" $(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJS) -lopencm3_lpc13xx diff --git a/examples/lpc17xx/Makefile.include b/examples/lpc17xx/Makefile.include index 8d6efe7d..66688d32 100644 --- a/examples/lpc17xx/Makefile.include +++ b/examples/lpc17xx/Makefile.include @@ -24,13 +24,18 @@ CC = $(PREFIX)-gcc LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump -# Uncomment this line if you want to use the installed (not local) library. -# TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -TOOLCHAIN_DIR = ../../../.. +ifeq ($(wildcard ../../../../lib/libopencm3_lpc17xx.a),) +TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +else +ifeq ($(V),1) +$(info We seem to be building the example in the source directory. Using local library!) +endif +TOOLCHAIN_DIR := ../../../.. +endif CFLAGS += -O0 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ -mcpu=cortex-m3 -mthumb -MD LDSCRIPT ?= $(BINARY).ld -LDFLAGS += -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/lpc17xx \ +LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections OBJS += $(BINARY).o @@ -75,7 +80,7 @@ flash: $(BINARY).flash @#printf " OBJDUMP $(*).list\n" $(Q)$(OBJDUMP) -S $(*).elf > $(*).list -%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/lpc17xx/libopencm3_lpc17xx.a +%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_lpc17xx.a @#printf " LD $(subst $(shell pwd)/,,$(@))\n" $(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJS) -lopencm3_lpc17xx diff --git a/examples/lpc43xx/Makefile.include b/examples/lpc43xx/Makefile.include new file mode 100644 index 00000000..4b1a092f --- /dev/null +++ b/examples/lpc43xx/Makefile.include @@ -0,0 +1,132 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2010 Piotr Esden-Tempski +## Copyright (C) 2012 Michael Ossmann +## Copyright (C) 2012 Benjamin Vernoux +## +## 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 . +## + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +LD = $(PREFIX)-gcc +OBJCOPY = $(PREFIX)-objcopy +OBJDUMP = $(PREFIX)-objdump +GDB = $(PREFIX)-gdb +ifeq ($(wildcard ../../../../lib/libopencm3_lpc43xx.a),) +TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +else +ifeq ($(V),1) +$(info We seem to be building the example in the source directory. Using local library!) +endif +TOOLCHAIN_DIR := ../../../.. +endif +CFLAGS += -O2 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ + -mcpu=cortex-m4 -mthumb -MD \ + -mfloat-abi=hard -mfpu=fpv4-sp-d16 +LDSCRIPT ?= $(BINARY).ld +LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \ + -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections -Xlinker -Map=$(BINARY).map +OBJS += $(BINARY).o + +OOCD ?= openocd +OOCD_INTERFACE ?= flossjtag +OOCD_BOARD ?= olimex_stm32_h103 + +# 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_lpc43xx.a + @#printf " LD $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJS) -lopencm3_lpc43xx + +%.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 + $(Q)rm -f *.map + +# FIXME: Replace STM32 stuff with proper LPC43XX OpenOCD support later. +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 "stm32x 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 "stm32x mass_erase 0" \ + -c "flash write_image $(*).hex" \ + -c "reset" \ + -c "shutdown" $(NULL) +endif + +.PHONY: images clean + +-include $(OBJS:.o=.d) diff --git a/examples/lpc43xx/diolan-lpc-4350-db1/README b/examples/lpc43xx/diolan-lpc-4350-db1/README new file mode 100644 index 00000000..bff2388f --- /dev/null +++ b/examples/lpc43xx/diolan-lpc-4350-db1/README @@ -0,0 +1,3 @@ +These example programs are written for the Diolan LPC-4350-DB1: + +http://www.diolan.com/lpc4350-features.html diff --git a/examples/lpc43xx/diolan-lpc-4350-db1/diolan-lpc-4350-db1.ld b/examples/lpc43xx/diolan-lpc-4350-db1/diolan-lpc-4350-db1.ld new file mode 100644 index 00000000..92c25aff --- /dev/null +++ b/examples/lpc43xx/diolan-lpc-4350-db1/diolan-lpc-4350-db1.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * 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 . + */ + +/* Linker script for HackRF Jellybean (LPC4330, 1M SPI flash, 64K SRAM). */ + +/* Define memory regions. */ +MEMORY +{ + /* rom is really the shadow region that points to SPI flash or elsewhere */ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M + ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K + /* there are some additional RAM regions */ +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lpc43xx.ld diff --git a/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/Makefile b/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/Makefile new file mode 100644 index 00000000..bf0ca91e --- /dev/null +++ b/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2010 Uwe Hermann +## +## 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 . +## + +BINARY = miniblink + +LDSCRIPT = ../diolan-lpc-4350-db1.ld + +include ../../Makefile.include diff --git a/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/README b/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/README new file mode 100644 index 00000000..009b9a99 --- /dev/null +++ b/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/README @@ -0,0 +1,11 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is the smallest-possible example program using libopencm3. + +It's intended for the Diolan LPC-4350-DB1: + +http://www.diolan.com/lpc4350-features.html + +It should blink D2 on the board. diff --git a/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/miniblink.c b/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/miniblink.c new file mode 100644 index 00000000..ce732894 --- /dev/null +++ b/examples/lpc43xx/diolan-lpc-4350-db1/miniblink/miniblink.c @@ -0,0 +1,46 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#include + +void gpio_setup(void) +{ + GPIO0_DIR |= (1 << 5); /* Configure GPIO0[5] (P6_6) as output. */ +} + +int main(void) +{ + int i; + + gpio_setup(); + + /* Blink D2 on the board. */ + while (1) { + + gpio_set(GPIO0, GPIOPIN5); /* LED on */ + for (i = 0; i < 800000; i++) /* Wait a bit. */ + __asm__("nop"); + gpio_clear(GPIO0, GPIOPIN5); /* LED off */ + for (i = 0; i < 800000; i++) /* Wait a bit. */ + __asm__("nop"); + } + + return 0; +} diff --git a/examples/lpc43xx/hackrf-jellybean/README b/examples/lpc43xx/hackrf-jellybean/README new file mode 100644 index 00000000..07aaeee9 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/README @@ -0,0 +1,4 @@ +These example programs are written for the Jellybean development board from the +HackRF project: + +https://github.com/mossmann/hackrf diff --git a/examples/lpc43xx/hackrf-jellybean/i2c/Makefile b/examples/lpc43xx/hackrf-jellybean/i2c/Makefile new file mode 100644 index 00000000..b18f1225 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/i2c/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2010 Uwe Hermann +## +## 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 . +## + +BINARY = i2cdemo + +LDSCRIPT = ../jellybean-lpc4330.ld + +include ../../Makefile.include diff --git a/examples/lpc43xx/hackrf-jellybean/i2c/README b/examples/lpc43xx/hackrf-jellybean/i2c/README new file mode 100644 index 00000000..86763fe1 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/i2c/README @@ -0,0 +1,15 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This program exercises the I2C peripheral on Jellybean's LPC43xx. You can +scope SCL on P6 pin 3 and SDA on P6 pin 5. If Lemondrop is connected, LED1 +will illuminate if I2C communication to the Si5351C on Lemondrop is successful. + +Required Lemondrop -> Jellybean connections: + +SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 +SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 +VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 +1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 +GND: Lemondrop P5 -> Jellybean P13 diff --git a/examples/lpc43xx/hackrf-jellybean/i2c/i2cdemo.c b/examples/lpc43xx/hackrf-jellybean/i2c/i2cdemo.c new file mode 100644 index 00000000..102365bd --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/i2c/i2cdemo.c @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#include +#include + +#include "../jellybean_conf.h" + +void gpio_setup(void) +{ + /* Configure SCU Pin Mux as GPIO */ + scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); + + /* Configure all GPIO as Input (safe state) */ + GPIO0_DIR = 0; + GPIO1_DIR = 0; + GPIO2_DIR = 0; + GPIO3_DIR = 0; + GPIO4_DIR = 0; + GPIO5_DIR = 0; + GPIO6_DIR = 0; + GPIO7_DIR = 0; + + /* Configure GPIO as Output */ + GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ + GPIO3_DIR |= PIN_EN1V8; /* GPIO3[6] on P6_10 as output. */ +} + +#define SI5351C_I2C_ADDR (0x60 << 1) + +/* write to single register */ +void si5351c_write_reg(uint8_t reg, uint8_t val) +{ + i2c0_tx_start(); + i2c0_tx_byte(SI5351C_I2C_ADDR | I2C_WRITE); + i2c0_tx_byte(reg); + i2c0_tx_byte(val); + i2c0_stop(); +} + +/* read single register */ +uint8_t si5351c_read_reg(uint8_t reg) +{ + uint8_t val; + + /* set register address with write */ + i2c0_tx_start(); + i2c0_tx_byte(SI5351C_I2C_ADDR | I2C_WRITE); + i2c0_tx_byte(reg); + + /* read the value */ + i2c0_tx_start(); + i2c0_tx_byte(SI5351C_I2C_ADDR | I2C_READ); + val = i2c0_rx_byte(); + i2c0_stop(); + + return val; +} + +int main(void) +{ + int i; + + gpio_setup(); + i2c0_init(); + + gpio_set(PORT_EN1V8, PIN_EN1V8); /* 1V8 on */ + + while (1) { + if (si5351c_read_reg(0) == 0x10) + gpio_set(GPIO2, GPIOPIN1); /* LED on */ + else + gpio_clear(GPIO2, GPIOPIN1); /* LED off */ + + for (i = 0; i < 1000; i++) /* Wait a bit. */ + __asm__("nop"); + } + + return 0; +} diff --git a/examples/lpc43xx/hackrf-jellybean/jellybean-lpc4330.ld b/examples/lpc43xx/hackrf-jellybean/jellybean-lpc4330.ld new file mode 100644 index 00000000..29e57004 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/jellybean-lpc4330.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * 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 . + */ + +/* Linker script for HackRF Jellybean (LPC4330, 1M SPI flash, 264K SRAM). */ + +/* Define memory regions. */ +MEMORY +{ + /* rom is really the shadow region that points to SPI flash or elsewhere */ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M + ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K + /* there are some additional RAM regions */ +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lpc43xx.ld diff --git a/examples/lpc43xx/hackrf-jellybean/jellybean-lpc4330_rom_to_ram.ld b/examples/lpc43xx/hackrf-jellybean/jellybean-lpc4330_rom_to_ram.ld new file mode 100644 index 00000000..fb3d8f6d --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/jellybean-lpc4330_rom_to_ram.ld @@ -0,0 +1,36 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +/* Linker script for HackRF Jellybean (LPC4330, 1M SPI flash, 264K SRAM). */ + +/* Define memory regions. */ +MEMORY +{ + /* Physical address in Flash used to copy Code from Flash to RAM */ + rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M + /* rom is really the shadow region that points to SPI flash or elsewhere */ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M + ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K + /* there are some additional RAM regions for data */ + ram_data (rw) : ORIGIN = 0x10080000, LENGTH = 72K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lpc43xx_rom_to_ram.ld diff --git a/examples/lpc43xx/hackrf-jellybean/jellybean_conf.h b/examples/lpc43xx/hackrf-jellybean/jellybean_conf.h new file mode 100644 index 00000000..dc791b34 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/jellybean_conf.h @@ -0,0 +1,85 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +#ifndef __JELLYBEAN_CONF_H +#define __JELLYBEAN_CONF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/* + * JellyBean SCU PinMux + */ + +/* GPIO Output PinMux */ +#define SCU_PINMUX_LED1 (P4_1) /* GPIO2[1] on P4_1 */ +#define SCU_PINMUX_LED2 (P4_2) /* GPIO2[2] on P4_2 */ +#define SCU_PINMUX_LED3 (P6_12) /* GPIO2[8] on P6_12 */ + +#define SCU_PINMUX_EN1V8 (P6_10) /* GPIO3[6] on P6_10 */ + +/* GPIO Input PinMux */ +#define SCU_PINMUX_BOOT0 (P1_1) /* GPIO0[8] on P1_1 */ +#define SCU_PINMUX_BOOT1 (P1_2) /* GPIO0[9] on P1_2 */ +#define SCU_PINMUX_BOOT2 (P2_8) /* GPIO5[7] on P2_8 */ +#define SCU_PINMUX_BOOT3 (P2_9) /* GPIO1[10] on P2_9 */ + +/* SSP1 Peripheral PinMux */ +#define SCU_SSP1_MISO (P1_3) /* P1_3 */ +#define SCU_SSP1_MOSI (P1_4) /* P1_4 */ +#define SCU_SSP1_SCK (P1_19) /* P1_19 */ +#define SCU_SSP1_SSEL (P1_20) /* P1_20 */ + +/* TODO add other Pins */ + +/* + * JellyBean GPIO Pin + */ +/* GPIO Output */ +#define PIN_LED1 (BIT1) /* GPIO2[1] on P4_1 */ +#define PIN_LED2 (BIT2) /* GPIO2[2] on P4_2 */ +#define PIN_LED3 (BIT8) /* GPIO2[8] on P6_12 */ +#define PORT_LED1_3 (GPIO2) /* PORT for LED1, 2 & 3 */ + +#define PIN_EN1V8 (BIT6) /* GPIO3[6] on P6_10 */ +#define PORT_EN1V8 (GPIO3) + +/* GPIO Input */ +#define PIN_BOOT0 (BIT8) /* GPIO0[8] on P1_1 */ +#define PIN_BOOT1 (BIT9) /* GPIO0[9] on P1_2 */ +#define PIN_BOOT2 (BIT7) /* GPIO5[7] on P2_8 */ +#define PIN_BOOT3 (BIT10) /* GPIO1[10] on P2_9 */ + +/* Read GPIO Pin */ +#define BOOT0_STATE ( (GPIO0_PIN & PIN_BOOT0)==PIN_BOOT0 ) +#define BOOT1_STATE ( (GPIO0_PIN & PIN_BOOT1)==PIN_BOOT1 ) +#define BOOT2_STATE ( (GPIO5_PIN & PIN_BOOT2)==PIN_BOOT2 ) +#define BOOT3_STATE ( (GPIO1_PIN & PIN_BOOT3)==PIN_BOOT3 ) + +/* TODO add other Pins */ + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/examples/lpc43xx/hackrf-jellybean/miniblink/Makefile b/examples/lpc43xx/hackrf-jellybean/miniblink/Makefile new file mode 100644 index 00000000..32da7ff4 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/miniblink/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2010 Uwe Hermann +## +## 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 . +## + +BINARY = miniblink + +LDSCRIPT = ../jellybean-lpc4330.ld + +include ../../Makefile.include diff --git a/examples/lpc43xx/hackrf-jellybean/miniblink/README b/examples/lpc43xx/hackrf-jellybean/miniblink/README new file mode 100644 index 00000000..556ed922 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/miniblink/README @@ -0,0 +1,11 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is the smallest-possible example program using libopencm3. + +It's intended for the Jellybean development board from the HackRF project: + +https://github.com/mossmann/hackrf + +It should blink LED1 on the board. diff --git a/examples/lpc43xx/hackrf-jellybean/miniblink/miniblink.c b/examples/lpc43xx/hackrf-jellybean/miniblink/miniblink.c new file mode 100644 index 00000000..3b3919b5 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/miniblink/miniblink.c @@ -0,0 +1,82 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2010 Uwe Hermann +* Copyright (C) 2012 Michael Ossmann +* +* 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 . +*/ + +#include +#include + +#include "../jellybean_conf.h" + +void gpio_setup(void) +{ + /* Configure SCU Pin Mux as GPIO */ + scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); + + /* Configure all GPIO as Input (safe state) */ + GPIO0_DIR = 0; + GPIO1_DIR = 0; + GPIO2_DIR = 0; + GPIO3_DIR = 0; + GPIO4_DIR = 0; + GPIO5_DIR = 0; + GPIO6_DIR = 0; + GPIO7_DIR = 0; + + /* Configure GPIO as Output */ + GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ + GPIO3_DIR |= PIN_EN1V8; /* GPIO3[6] on P6_10 as output. */ +} + +u32 boot0, boot1, boot2, boot3; + +int main(void) +{ + int i; + gpio_setup(); + + /* Set 1V8 */ + gpio_set(PORT_EN1V8, PIN_EN1V8); + + /* Blink LED1/2/3 on the board and Read BOOT0/1/2/3 pins. */ + while (1) + { + boot0 = BOOT0_STATE; + boot1 = BOOT1_STATE; + boot2 = BOOT2_STATE; + boot3 = BOOT3_STATE; + + gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LEDs on */ + for (i = 0; i < 2000000; i++) /* Wait a bit. */ + __asm__("nop"); + gpio_clear(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LED off */ + for (i = 0; i < 2000000; i++) /* Wait a bit. */ + __asm__("nop"); + } + + return 0; +} diff --git a/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/Makefile b/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/Makefile new file mode 100644 index 00000000..56cb540e --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2010 Uwe Hermann +## +## 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 . +## + +BINARY = miniblink + +LDSCRIPT = ../jellybean-lpc4330_rom_to_ram.ld + +include ../../Makefile.include diff --git a/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/README b/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/README new file mode 100644 index 00000000..02960fa0 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/README @@ -0,0 +1,12 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is the smallest-possible example program using libopencm3. + +It's intended for the Jellybean development board from the HackRF project: + +https://github.com/mossmann/hackrf + +It should blink LED1 on the board. +This example copy the Code from ROM to RAM and execute code from RAM. diff --git a/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/miniblink.c b/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/miniblink.c new file mode 100644 index 00000000..3b3919b5 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/miniblink_rom_to_ram/miniblink.c @@ -0,0 +1,82 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2010 Uwe Hermann +* Copyright (C) 2012 Michael Ossmann +* +* 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 . +*/ + +#include +#include + +#include "../jellybean_conf.h" + +void gpio_setup(void) +{ + /* Configure SCU Pin Mux as GPIO */ + scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); + + /* Configure all GPIO as Input (safe state) */ + GPIO0_DIR = 0; + GPIO1_DIR = 0; + GPIO2_DIR = 0; + GPIO3_DIR = 0; + GPIO4_DIR = 0; + GPIO5_DIR = 0; + GPIO6_DIR = 0; + GPIO7_DIR = 0; + + /* Configure GPIO as Output */ + GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ + GPIO3_DIR |= PIN_EN1V8; /* GPIO3[6] on P6_10 as output. */ +} + +u32 boot0, boot1, boot2, boot3; + +int main(void) +{ + int i; + gpio_setup(); + + /* Set 1V8 */ + gpio_set(PORT_EN1V8, PIN_EN1V8); + + /* Blink LED1/2/3 on the board and Read BOOT0/1/2/3 pins. */ + while (1) + { + boot0 = BOOT0_STATE; + boot1 = BOOT1_STATE; + boot2 = BOOT2_STATE; + boot3 = BOOT3_STATE; + + gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LEDs on */ + for (i = 0; i < 2000000; i++) /* Wait a bit. */ + __asm__("nop"); + gpio_clear(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LED off */ + for (i = 0; i < 2000000; i++) /* Wait a bit. */ + __asm__("nop"); + } + + return 0; +} diff --git a/examples/lpc43xx/hackrf-jellybean/ssp/Makefile b/examples/lpc43xx/hackrf-jellybean/ssp/Makefile new file mode 100644 index 00000000..8a3b1cc0 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/ssp/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2010 Uwe Hermann +## +## 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 . +## + +BINARY = sspdemo + +LDSCRIPT = ../jellybean-lpc4330.ld + +include ../../Makefile.include diff --git a/examples/lpc43xx/hackrf-jellybean/ssp/README b/examples/lpc43xx/hackrf-jellybean/ssp/README new file mode 100644 index 00000000..5354a53b --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/ssp/README @@ -0,0 +1,48 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This program exercises the SSP1 peripheral on Jellybean's LPC43xx. + + Jellybean (connector) + P9 SPI + |-----------------| + | Pin2 Pin4 Pin6 | +||------| | +|| Pin1 |Pin3 Pin5 | +||------|----------| +|-------| + +SSP1_MISO: Jellybean P9 SPI Pin6 +SSP1_MOSI: Jellybean P9 SPI Pin4 +SSP1_SCK: Jellybean P9 SPI Pin2 +SSP1_SSEL: Jellybean P9 SPI Pin3 +GND: Can be connected to P12 SD Pin1 + +PCLK clock source is PLL1 288MHz (from IRC 96MHz boot from SPIFI) +Freq = PCLK / (CPSDVSR * [SCR+1]). + +By default (CPSDVSR=0 => Means MAX Divisor) +SSP1->CR0->SCR = 0x00 => CLK Freq 1.126MHz +SSP1->CR0->SCR = 0x01 => MOSI Freq 566.9KHz +... + +Test Oscilloscpe: +SCR=0, CPSDVSR=32 => CLK 9.025MHz +SCR=1, CPSDVSR=2 => CLK 73MHz +SCR=2, CPSDVSR=2 => CLK 49MHz +SCR=4, CPSDVSR=2 => CLK 29MHz +SCR=8, CPSDVSR=2 => CLK 16MHz +SCR=16, CPSDVSR=2 => CLK 8.5MHz +SCR=32, CPSDVSR=2 => CLK 4.386MHz +SCR=64, CPSDVSR=2 => CLK 2.227MHz +SCR=1, CPSDVSR=64 => CLK 2.262MHz + +Theory: +SCR=0, CPSDVSR=32 => 288MHz / (32*(0+1) = 9MHz +SCR=1, CPSDVSR=2 => 288MHz / (2*(1+1) = 72MHz +SCR=4, CPSDVSR=2 => 288MHz / (2*(4+1) = 28.8MHz +SCR=32, CPSDVSR=2 => 288MHz / (2*(32+1) = 4.364MHz +SCR=64, CPSDVSR=2 => 288MHz / (2*(64+1)) = 2.2154MHz +SCR=128, CPSDVSR=2 => 288MHz / (2*(128+1)) = 1.116MHz +SCR=1, CPSDVSR=64 => 288MHz / (64*(1+1)) = 2.25MHz diff --git a/examples/lpc43xx/hackrf-jellybean/ssp/sspdemo.c b/examples/lpc43xx/hackrf-jellybean/ssp/sspdemo.c new file mode 100644 index 00000000..cdb3702c --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/ssp/sspdemo.c @@ -0,0 +1,102 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +#include +#include +#include +#include + +#include "../jellybean_conf.h" + +void gpio_setup(void) +{ + /* Configure all GPIO as Input (safe state) */ + GPIO0_DIR = 0; + GPIO1_DIR = 0; + GPIO2_DIR = 0; + GPIO3_DIR = 0; + GPIO4_DIR = 0; + GPIO5_DIR = 0; + GPIO6_DIR = 0; + GPIO7_DIR = 0; + + /* Configure SCU Pin Mux as GPIO */ + scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); + + /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ + scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); + scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); + + /* Configure GPIO as Output */ + GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ + GPIO3_DIR |= PIN_EN1V8; /* GPIO3[6] on P6_10 as output. */ +} + +int main(void) +{ + int i; + u8 ssp_val; + u8 serial_clock_rate; + u8 clock_prescale_rate; + + gpio_setup(); + + /* Freq About 1.12MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=288MHz */ + clock_prescale_rate = 2; + serial_clock_rate = 128; + + ssp_init(SSP1_NUM, + SSP_DATA_8BITS, + SSP_FRAME_SPI, + SSP_CPOL_0_CPHA_0, + serial_clock_rate, + clock_prescale_rate, + SSP_MODE_NORMAL, + SSP_MASTER, + SSP_SLAVE_OUT_ENABLE); + + ssp_val = 0x0; + + while (1) { + + ssp_write(SSP1_NUM, (u16)ssp_val); + + gpio_set(GPIO2, GPIOPIN1); /* LED on */ + + for (i = 0; i < 1000; i++) /* Wait a bit. */ + __asm__("nop"); + + gpio_clear(GPIO2, GPIOPIN1); /* LED off */ + + ssp_val++; + } + + return 0; +} diff --git a/examples/lpc43xx/hackrf-jellybean/systick/Makefile b/examples/lpc43xx/hackrf-jellybean/systick/Makefile new file mode 100644 index 00000000..93b471e1 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/systick/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2012 Benjamin Vernoux +## +## 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 . +## + +BINARY = systickdemo + +LDSCRIPT = ../jellybean-lpc4330.ld + +include ../../Makefile.include diff --git a/examples/lpc43xx/hackrf-jellybean/systick/README b/examples/lpc43xx/hackrf-jellybean/systick/README new file mode 100644 index 00000000..8c32cdc5 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/systick/README @@ -0,0 +1,8 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This program exercises the SysTick Interrupt of ARM CortexM4 on Jellybean's LPC43xx. +It also enable Cycle Counter to be used for accurate delay independant from Clock Frequency. +The Demo Use Cycle Counter and SysTick Interrupt to compute number of cycles executed per second. +The result is LED1/2 & 3 Blink with an accurate 1s Period (using SysTick) (Checked visualy and with Oscilloscope). diff --git a/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c b/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c new file mode 100644 index 00000000..66c8e068 --- /dev/null +++ b/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c @@ -0,0 +1,184 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include "../jellybean_conf.h" + +/* Global counter incremented by SysTick Interrupt each millisecond */ +volatile u32 g_ulSysTickCount; +u32 g_NbCyclePerSecond; + +void gpio_setup(void) +{ + /* Configure all GPIO as Input (safe state) */ + GPIO0_DIR = 0; + GPIO1_DIR = 0; + GPIO2_DIR = 0; + GPIO3_DIR = 0; + GPIO4_DIR = 0; + GPIO5_DIR = 0; + GPIO6_DIR = 0; + GPIO7_DIR = 0; + + /* Configure SCU Pin Mux as GPIO */ + scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); + + /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ + scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); + scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); + + /* Configure GPIO as Output */ + GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ + GPIO3_DIR |= PIN_EN1V8; /* GPIO3[6] on P6_10 as output. */ +} + +void systick_setup(void) +{ + u32 systick_reload_val; + g_ulSysTickCount = 0; + + /* Disable IRQ globally */ + asm volatile ("cpsid i"); + + /* Set processor Clock as Source Clock */ + systick_set_clocksource(STK_CTRL_CLKSOURCE); + + /* Get SysTick calibration value to obtain by default 1 tick = 10ms */ + systick_reload_val = systick_get_calib(); + /* + * Calibration seems wrong on LPC43xx(TBC) for default Freq it assume System Clock is 12MHz but it is 12*8=96MHz + * Fix the Calibration value bu multiplication by 8 + */ + systick_reload_val = (systick_reload_val*8); + + /* To obtain 1ms per tick just divide by 10 the 10ms base tick and set the reload */ + systick_reload_val = systick_reload_val/10; + systick_set_reload(systick_reload_val); + + systick_interrupt_enable(); + + /* Start counting. */ + systick_counter_enable(); + + /* Set SysTick Priority to maximum */ + nvic_set_priority(NVIC_SYSTICK_IRQ, 0xFF); + + /* Enable IRQ globally */ + asm volatile ("cpsie i"); +} + +void scs_dwt_cycle_counter_enabled(void) +{ + SCS_DEMCR |= SCS_DEMCR_TRCENA; + SCS_DWT_CTRL |= SCS_DWT_CTRL_CYCCNTENA; +} + +u32 sys_tick_get_time_ms(void) +{ + return g_ulSysTickCount; +} + +u32 sys_tick_delta_time_ms(u32 start, u32 end) +{ + #define MAX_T_U32 ((2^32)-1) + u32 diff; + + if(end > start) + { + diff=end-start; + }else + { + diff=MAX_T_U32-(start-end)+1; + } + + return diff; +} + +void sys_tick_wait_time_ms(u32 wait_ms) +{ + u32 start, end; + u32 tickms; + + start = sys_tick_get_time_ms(); + + do + { + end = sys_tick_get_time_ms(); + tickms = sys_tick_delta_time_ms(start, end); + }while(tickms < wait_ms); +} + +/* Called each 1ms/1000Hz by interrupt + 1) Count the number of cycle per second. + 2) Increment g_ulSysTickCount counter. +*/ +void sys_tick_handler(void) +{ + if(g_ulSysTickCount==0) + { + /* Clear Cycle Counter*/ + SCS_DWT_CYCCNT = 0; + }else if(g_ulSysTickCount==1000) + { + /* Capture number of cycle elapsed during 1 second */ + g_NbCyclePerSecond = SCS_DWT_CYCCNT; + } + + g_ulSysTickCount++; +} + +int main(void) +{ + systick_setup(); + + gpio_setup(); + + /* SCS & Cycle Counter enabled (used to count number of cycles executed per second see g_NbCyclePerSecond */ + scs_dwt_cycle_counter_enabled(); + + while (1) + { + gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LEDs on */ + + sys_tick_wait_time_ms(500); + + gpio_clear(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LED off */ + + sys_tick_wait_time_ms(500); + } + + return 0; +} diff --git a/examples/stm32/f1/Makefile.include b/examples/stm32/f1/Makefile.include index 92ad689d..b315fac1 100644 --- a/examples/stm32/f1/Makefile.include +++ b/examples/stm32/f1/Makefile.include @@ -25,16 +25,22 @@ LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb -# Uncomment this line if you want to use the installed (not local) library. -#TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -TOOLCHAIN_DIR = ../../../../.. +ifeq ($(wildcard ../../../../../lib/libopencm3_stm32f1.a),) +TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +else +ifeq ($(V),1) +$(info We seem to be building the example in the source directory. Using local library!) +endif +TOOLCHAIN_DIR := ../../../../.. +endif +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 -msoft-float CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ - -fno-common -mcpu=cortex-m3 -mthumb -msoft-float -MD -DSTM32F1 + -fno-common $(ARCH_FLAGS) -MD -DSTM32F1 LDSCRIPT ?= $(BINARY).ld LDFLAGS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group \ - -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/stm32/f1 \ + -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \ - -mthumb -march=armv7 -mfix-cortex-m3-ldrd -msoft-float + $(ARCH_FLAGS) -mfix-cortex-m3-ldrd OBJS += $(BINARY).o OOCD ?= openocd @@ -80,7 +86,7 @@ flash: $(BINARY).flash @#printf " OBJDUMP $(*).list\n" $(Q)$(OBJDUMP) -S $(*).elf > $(*).list -%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/stm32/f1/libopencm3_stm32f1.a +%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f1.a @#printf " LD $(subst $(shell pwd)/,,$(@))\n" $(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32f1 $(LDFLAGS) diff --git a/examples/stm32/f1/lisa-m-2/adc_regular/Makefile b/examples/stm32/f1/lisa-m-2/adc_regular/Makefile new file mode 100644 index 00000000..20355ceb --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_regular/Makefile @@ -0,0 +1,27 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +BINARY = adc +# 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/adc_regular/README b/examples/stm32/f1/lisa-m-2/adc_regular/README new file mode 100644 index 00000000..3b583ffa --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_regular/README @@ -0,0 +1,9 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is a simple polling example that sends the value read out from the +temperature sensor ADC channel of the STM32 to the USART2. + +The terminal settings for the receiving device/PC are 115200 8n1. + diff --git a/examples/stm32/f1/lisa-m-2/adc_regular/adc.c b/examples/stm32/f1/lisa-m-2/adc_regular/adc.c new file mode 100644 index 00000000..91d029f0 --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_regular/adc.c @@ -0,0 +1,162 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Piotr Esden-Tempski + * + * 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 . + */ + +#include +#include +#include +#include +#include + +void usart_setup(void) +{ + /* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + + /* Setup GPIO pin GPIO_USART1_TX/GPIO9 on GPIO port A for transmit. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); + + /* Setup UART parameters. */ + usart_set_baudrate(USART2, 115200); + usart_set_databits(USART2, 8); + usart_set_stopbits(USART2, USART_STOPBITS_1); + usart_set_mode(USART2, USART_MODE_TX_RX); + 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) +{ + /* Enable GPIO clocks. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + + /* Setup the LEDs. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); +} + +void adc_setup(void) +{ + int i; + + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + + /* Make sure the ADC doesn't run during config. */ + adc_off(ADC1); + + /* We configure everything for one single conversion. */ + adc_disable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + adc_enable_discontinous_mode_regular(ADC1); + adc_disable_external_trigger_regular(ADC1); + adc_set_right_aligned(ADC1); + /* We want to read the temperature sensor, so we have to enable it. */ + adc_enable_temperature_sensor(ADC1); + adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + + adc_on(ADC1); + + /* Wait for ADC starting up. */ + for (i = 0; i < 800000; i++) /* Wait a bit. */ + __asm__("nop"); + + adc_reset_calibration(ADC1); + adc_calibration(ADC1); +} + +void my_usart_print_int(u32 usart, int value) +{ + s8 i; + u8 nr_digits = 0; + char buffer[25]; + + if (value < 0) { + usart_send_blocking(usart, '-'); + value = value * -1; + } + + while (value > 0) { + buffer[nr_digits++] = "0123456789"[value % 10]; + value /= 10; + } + + for (i = nr_digits; i >= 0; i--) { + usart_send_blocking(usart, buffer[i]); + } + + usart_send_blocking(usart, '\r'); +} + +int main(void) +{ + u8 channel_array[16]; + u16 temperature = 0; + + rcc_clock_setup_in_hse_12mhz_out_72mhz(); + gpio_setup(); + usart_setup(); + adc_setup(); + + gpio_set(GPIOA, GPIO8); /* LED1 on */ + gpio_set(GPIOC, GPIO15); /* LED2 off */ + + /* Send a message on USART1. */ + usart_send_blocking(USART2, 's'); + usart_send_blocking(USART2, 't'); + usart_send_blocking(USART2, 'm'); + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + + /* Select the channel we want to convert. 16=temperature_sensor. */ + channel_array[0] = 16; + adc_set_regular_sequence(ADC1, 1, channel_array); + + /* Continously convert and poll the temperature ADC. */ + while (1) { + /* + * If the ADC_CR2_ON bit is already set -> setting it another time + * starts the conversion. + */ + adc_on(ADC1); + + /* Wait for end of conversion. */ + while (!(ADC_SR(ADC1) & ADC_SR_EOC)); + + temperature = ADC_DR(ADC1); + + /* + * That's actually not the real temperature - you have to compute it + * as described in the datasheet. + */ + my_usart_print_int(USART2, temperature); + + gpio_toggle(GPIOA, GPIO8); /* LED2 on */ + + } + + return 0; +} diff --git a/examples/stm32/f2/Makefile.include b/examples/stm32/f2/Makefile.include index f68da433..3e338af5 100644 --- a/examples/stm32/f2/Makefile.include +++ b/examples/stm32/f2/Makefile.include @@ -26,9 +26,14 @@ LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb -# Uncomment this line if you want to use the installed (not local) library. -#TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -TOOLCHAIN_DIR = ../../../../.. +ifeq ($(wildcard ../../../../../lib/libopencm3_stm32f2.a),) +TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +else +ifeq ($(V),1) +$(info We seem to be building the example in the source directory. Using local library!) +endif +TOOLCHAIN_DIR := ../../../../.. +endif CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ -fno-common -mcpu=cortex-m3 -mthumb -msoft-float -MD -DSTM32F2 LDSCRIPT ?= $(BINARY).ld @@ -81,7 +86,7 @@ flash: $(BINARY).flash @#printf " OBJDUMP $(*).list\n" $(Q)$(OBJDUMP) -S $(*).elf > $(*).list -%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/stm32/f2/libopencm3_stm32f2.a +%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f2.a @#printf " LD $(subst $(shell pwd)/,,$(@))\n" $(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32f2 $(LDFLAGS) diff --git a/examples/stm32/f4/Makefile.include b/examples/stm32/f4/Makefile.include index 42e7162d..b735aa6e 100644 --- a/examples/stm32/f4/Makefile.include +++ b/examples/stm32/f4/Makefile.include @@ -26,9 +26,15 @@ LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb -# Uncomment this line if you want to use the installed (not local) library. -#TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -TOOLCHAIN_DIR = ../../../../.. +FLASH = $(shell which st-flash) +ifeq ($(wildcard ../../../../../lib/libopencm3_stm32f4.a),) +TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +else +ifeq ($(V),1) +$(info We seem to be building the example in the source directory. Using local library!) +endif +TOOLCHAIN_DIR := ../../../../.. +endif CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ -fno-common -mcpu=cortex-m4 -mthumb -msoft-float -MD -DSTM32F4 LDSCRIPT ?= $(BINARY).ld @@ -81,7 +87,7 @@ flash: $(BINARY).flash @#printf " OBJDUMP $(*).list\n" $(Q)$(OBJDUMP) -S $(*).elf > $(*).list -%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/stm32/f4/libopencm3_stm32f4.a +%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f4.a @#printf " LD $(subst $(shell pwd)/,,$(@))\n" $(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32f4 $(LDFLAGS) @@ -98,6 +104,11 @@ clean: $(Q)rm -f *.srec $(Q)rm -f *.list +%.stlink-flash: %.bin + @printf " FLASH $<\n" + $(Q)$(FLASH) write $(*).bin 0x8000000 + + ifeq ($(BMP_PORT),) ifeq ($(OOCD_SERIAL),) %.flash: %.hex diff --git a/include/libopencm3/cm3/common.h b/include/libopencm3/cm3/common.h index dc3e433b..7ef18fea 100644 --- a/include/libopencm3/cm3/common.h +++ b/include/libopencm3/cm3/common.h @@ -32,26 +32,54 @@ typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; +/* This must be placed around external function declaration for C++ + * support. */ +#ifdef __cplusplus +# define BEGIN_DECLS extern "C" { +# define END_DECLS } +#else +# define BEGIN_DECLS +# define END_DECLS +#endif + /* Generic memory-mapped I/O accessor functions */ #define MMIO8(addr) (*(volatile u8 *)(addr)) #define MMIO16(addr) (*(volatile u16 *)(addr)) #define MMIO32(addr) (*(volatile u32 *)(addr)) #define MMIO64(addr) (*(volatile u64 *)(addr)) -/* Main page for the doxygen-generated documentation: */ - -/** - * @mainpage libopencm3 Developer Documentation - * - * The libopencm3 project (previously known as libopenstm32) aims to create - * a free/libre/open-source (GPL v3, or later) firmware library for various - * ARM Cortex-M3 microcontrollers, including ST STM32, Toshiba TX03, - * Atmel SAM3U, NXP LPC1000 and others. - * - * @par "" - * - * See the libopencm3 wiki for - * more information. - */ +/* Generic bit definition */ +#define BIT0 (1<<0) +#define BIT1 (1<<1) +#define BIT2 (1<<2) +#define BIT3 (1<<3) +#define BIT4 (1<<4) +#define BIT5 (1<<5) +#define BIT6 (1<<6) +#define BIT7 (1<<7) +#define BIT8 (1<<8) +#define BIT9 (1<<9) +#define BIT10 (1<<10) +#define BIT11 (1<<11) +#define BIT12 (1<<12) +#define BIT13 (1<<13) +#define BIT14 (1<<14) +#define BIT15 (1<<15) +#define BIT16 (1<<16) +#define BIT17 (1<<17) +#define BIT18 (1<<18) +#define BIT19 (1<<19) +#define BIT20 (1<<20) +#define BIT21 (1<<21) +#define BIT22 (1<<22) +#define BIT23 (1<<23) +#define BIT24 (1<<24) +#define BIT25 (1<<25) +#define BIT26 (1<<26) +#define BIT27 (1<<27) +#define BIT28 (1<<28) +#define BIT29 (1<<29) +#define BIT30 (1<<30) +#define BIT31 (1<<31) #endif diff --git a/include/libopencm3/cm3/docmain.h b/include/libopencm3/cm3/docmain.h new file mode 100644 index 00000000..9407ceb6 --- /dev/null +++ b/include/libopencm3/cm3/docmain.h @@ -0,0 +1,70 @@ +/** + * @mainpage libopencm3 Developer Documentation + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +@date 18 August 2012 + + * The libopencm3 project (previously known as libopenstm32) aims to create + * a free/libre/open-source (GPL v3, or later) firmware library for various + * ARM Cortex-M3 microcontrollers, including ST STM32, Toshiba TX03, + * Atmel SAM3U, NXP LPC1000 and others. + * + * @par "" + * + * See the libopencm3 wiki for + * more information. + +LGPL License Terms @ref lgpl_license + +*/ + +/** @page lgpl_license libopencm3 License + +libopencm3 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. + +libopencm3 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 +program. If not, see . + +*/ + +/** @defgroup LM3S LM3S +Libraries for Texas instruments LM3S series. +*/ + +/** @defgroup LPC13xx LPC13xx +Libraries for NXP Semiconductor LPC13xx series. +*/ + +/** @defgroup LPC17xx LPC17xx +Libraries for NXP Semiconductor LPC17xx series. +*/ + +/** @defgroup STM32F STM32F +Libraries for ST Microelectronics STM32F series. +*/ + +/** @defgroup STM32F1xx STM32F1xx +@ingroup STM32F +Libraries for ST Microelectronics STM32F1xx series. +*/ + +/** @defgroup STM32F2xx STM32F2xx +@ingroup STM32F +Libraries for ST Microelectronics STM32F2xx series. +*/ + +/** @defgroup STM32F4xx STM32F4xx +@ingroup STM32F +Libraries for ST Microelectronics STM32F4xx series. +*/ + diff --git a/include/libopencm3/cm3/scs.h b/include/libopencm3/cm3/scs.h index 033ec730..fff4a1b8 100644 --- a/include/libopencm3/cm3/scs.h +++ b/include/libopencm3/cm3/scs.h @@ -2,6 +2,7 @@ * This file is part of the libopencm3 project. * * Copyright (C) 2011 Gareth McMullin + * Copyright (C) 2012 Benjamin Vernoux * * 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 @@ -20,9 +21,85 @@ #ifndef LIBOPENCM3_CM3_SCS_H #define LIBOPENCM3_CM3_SCS_H +/* + * All the definition hereafter are generic for CortexMx ARMv7-M + * See ARM document "ARMv7-M Architecture Reference Manual" for more details. + * See also ARM document "ARM Compiler toolchain Developing Software for ARM Processors" for details on System Timer/SysTick. + */ + +/* + * The System Control Space (SCS) is a memory-mapped 4KB address space that provides 32-bit registers for + * configuration, status reporting and control. The SCS registers divide into the following groups: + * - system control and identification + * - the CPUID processor identification space + * - system configuration and status + * - fault reporting + * - a system timer, SysTick + * - a Nested Vectored Interrupt Controller (NVIC) + * - a Protected Memory System Architecture (PMSA) + * - system debug. + */ + +/* System Handler Priority 8 bits Registers, SHPR1/2/3 */ +/* Note: 12 8bit Registers */ +#define SCS_SHPR(ipr_id) MMIO8(SCS_BASE + 0xD18 + ipr_id) + +/* + * Debug Halting Control and Status Register (DHCSR). + * + * Purpose Controls halting debug. + * Usage constraints: The effect of modifying the C_STEP or C_MASKINTS bit when the system + * is running with halting debug enabled is UNPREDICTABLE. + * Halting debug is enabled when C_DEBUGEN is set to 1. The system is running when S_HALT is set to 0. + * - When C_DEBUGEN is set to 0, the processor ignores the values of all other bits in this register. + * - For more information about the use of DHCSR see Debug stepping on + * page C1-824. + * Configurations Always implemented. + */ +/* SCS_DHCSR register */ #define SCS_DHCSR MMIO32(SCS_BASE + 0xDF0) +/* + * Debug Core Register Selector Register (DCRSR). + * + * Purpose With the DCRDR, the DCRSR provides debug access to the ARM core registers, + * special-purpose registers, and Floating-point extension registers. A write to DCRSR + * specifies the register to transfer, whether the transfer is a read or a write, and starts + * the transfer. + * Usage constraints: Only accessible in Debug state. + * Configurations Always implemented. + * + */ +/* SCS_DCRS register */ #define SCS_DCRSR MMIO32(SCS_BASE + 0xDF4) +/* + * Debug Core Register Data Register (DCRDR) + * + * Purpose With the DCRSR, see Debug Core Register Selector Register, + * the DCRDR provides debug access to the ARM core registers, + * special-purpose registers, and Floating-point extension registers. The + * DCRDR is the data register for these accesses. + * - Used on its own, the DCRDR provides a message passing resource between + * an external debugger and a debug agent running on the processor. + * Note: + * The architecture does not define any handshaking mechanism for this use of DCRDR. + * Usage constraints: See Use of DCRSR and DCRDR for constraints that apply to + * particular transfers using the DCRSR and DCRDR. + * Configurations Always implemented. + * + */ +/* SCS_DCRDR register */ #define SCS_DCRDR MMIO32(SCS_BASE + 0xDF8) +/* + * Debug Exception and Monitor Control Register (DEMCR). + * + * Purpose Manages vector catch behavior and DebugMonitor handling when debugging. + * Usage constraints: + * - Bits [23:16] provide DebugMonitor exception control. + * - Bits [15:0] provide Debug state, halting debug, control. + * Configurations Always implemented. + * + */ +/* SCS_DEMCR register */ #define SCS_DEMCR MMIO32(SCS_BASE + 0xDFC) /* Debug Halting Control and Status Register (DHCSR) */ @@ -64,4 +141,169 @@ /* Bits 3:1 - Reserved */ #define SCS_DEMCR_VC_CORERESET (1 << 0) +/* + * System Control Space (SCS) => System timer register support in the SCS. + * To configure SysTick, load the interval required between SysTick events to the SysTick Reload + * Value register. The timer interrupt, or COUNTFLAG bit in the SysTick Control and Status + * register, is activated on the transition from 1 to 0, therefore it activates every n+1 clock ticks. + * If you require a period of 100, write 99 to the SysTick Reload Value register. The SysTick Reload + * Value register supports values between 0x1 and 0x00FFFFFF. + * + * If you want to use SysTick to generate an event at a timed interval, for example 1ms, you can + * use the SysTick Calibration Value Register to scale your value for the Reload register. The + * SysTick Calibration Value Register is a read-only register that contains the number of pulses for + * a period of 10ms, in the TENMS field, bits[23:0]. + * + * This register also has a SKEW bit. Bit[30] == 1 indicates that the calibration for 10ms in the + * TENMS section is not exactly 10ms due to clock frequency. Bit[31] == 1 indicates that the + * reference clock is not provided. + */ +/* + * SysTick Control and Status Register (CSR). + * Purpose Controls the system timer and provides status data. + * Usage constraints: There are no usage constraints. + * Configurations Always implemented. +*/ +#define SCS_SYST_CSR MMIO32(SCS_BASE + 0x10) + +/* SysTick Reload Value Register (CVR). + * Purpose Reads or clears the current counter value. + * Usage constraints: + * - Any write to the register clears the register to zero. + * - The counter does not provide read-modify-write protection. + * - Unsupported bits are read as zero + * Configurations Always implemented. + */ +#define CM_SCS_SYST_RVR MMIO32(SCS_BASE + 0x14) + +/* SysTick Current Value Register (RVR). + * Purpose Holds the reload value of the SYST_CVR. + * Usage constraints There are no usage constraints. + * Configurations Always implemented. + */ +#define CM_SCS_SYST_CVR MMIO32(SCS_BASE + 0x18) + +/* + * SysTick Calibration value Register(Read Only) (CALIB) + * Purpose Reads the calibration value and parameters for SysTick. + * Usage constraints: There are no usage constraints. + * Configurations Always implemented. + */ +#define CM_SCS_SYST_CALIB MMIO32(SCS_BASE + 0x1C) + +/* --- SCS_SYST_CSR values ----------------------------------------------- */ +/* Counter is operating. */ +#define SCS_SYST_CSR_ENABLE (BIT0) +/* Count to 0 changes the SysTick exception status to pending. */ +#define SCS_SYST_CSR_TICKINT (BIT1) +/* SysTick uses the processor clock. */ +#define SCS_SYST_CSR_CLKSOURCE (BIT2) +/* + * Indicates whether the counter has counted to 0 since the last read of this register: + * 0 = Timer has not counted to 0 + * 1 = Timer has counted to 0. + */ +#define SCS_SYST_CSR_COUNTFLAG (BIT16) + +/* --- CM_SCS_SYST_RVR values ----------------------------------------------- */ +/* Bit 0 to 23 => RELOAD The value to load into the SYST_CVR when the counter reaches 0. */ +/* Bit 24 to 31 are Reserved */ + +/* --- CM_SCS_SYST_CVR values ----------------------------------------------- */ +/* Bit0 to 31 => Reads or clears the current counter value. */ + +/* --- CM_SCS_SYST_CALIB values ----------------------------------------------- */ +/* + * Bit0 to 23 => TENMS Optionally, holds a reload value to be used for 10ms (100Hz) timing, subject to system clock + * skew errors. If this field is zero, the calibration value is not known. + */ +#define SCS_SYST_SYST_CALIB_TENMS_MASK (BIT24-1) + +/* + * Bit30 => SKEW Indicates whether the 10ms calibration value is exact: + * 0 = 10ms calibration value is exact. + * 1 = 10ms calibration value is inexact, because of the clock frequency + */ +#define SCS_SYST_SYST_CALIB_VALUE_INEXACT (BIT30) +/* + * Bit31 => NOREF Indicates whether the IMPLEMENTATION DEFINED reference clock is implemented: + * 0 = The reference clock is implemented. + * 1 = The reference clock is not implemented. + * When this bit is 1, the CLKSOURCE bit of the SYST_CSR register is forced to 1 and cannot + * be cleared to 0. + */ +#define SCS_SYST_SYST_CALIB_REF_NOT_IMPLEMENTED (BIT31) + +/* + * System Control Space (SCS) => Data Watchpoint and Trace (DWT). + * See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0403c/index.html (ARMv7-M Architecture Reference Manual) + * The DWT is an optional debug unit that provides watchpoints, data tracing, and system profiling + * for the processor. + */ +/* + * DWT Control register + * Purpose Provides configuration and status information for the DWT block, and used to control features of the block + * Usage constraints: There are no usage constraints. + * Configurations Always implemented. + */ +#define SCS_DWT_CTRL MMIO32(DWT_BASE + 0x00) +/* + * DWT_CYCCNT register + * Cycle Count Register (Shows or sets the value of the processor cycle counter, CYCCNT) + * When enabled, CYCCNT increments on each processor clock cycle. On overflow, CYCCNT wraps to zero. + * + * Purpose Shows or sets the value of the processor cycle counter, CYCCNT. + * Usage constraints: The DWT unit suspends CYCCNT counting when the processor is in Debug state. + * Configurations Implemented: only when DWT_CTRL.NOCYCCNT is RAZ, see Control register, DWT_CTRL. + * When DWT_CTRL.NOCYCCNT is RAO no cycle counter is implemented and this register is UNK/SBZP. +*/ +#define SCS_DWT_CYCCNT MMIO32(DWT_BASE + 0x04) + +/* DWT_CPICNT register + * Purpose Counts additional cycles required to execute multi-cycle instructions and instruction fetch stalls. + * Usage constraints: The counter initializes to 0 when software enables its counter overflow event by + * setting the DWT_CTRL.CPIEVTENA bit to 1. + * Configurations Implemented: only when DWT_CTRL.NOPRFCNT is RAZ, see Control register, DWT_CTRL. + * If DWT_CTRL.NOPRFCNT is RAO, indicating that the implementation does not + * include the profiling counters, this register is UNK/SBZP. + */ +#define SCS_DWT_CPICNT MMIO32(DWT_BASE + 0x08) + +/* DWT_EXCCNT register */ +#define SCS_DWT_EXCCNT MMIO32(DWT_BASE + 0x0C) + +/* DWT_EXCCNT register */ +#define SCS_DWT_SLEEPCNT MMIO32(DWT_BASE + 0x10) + +/* DWT_EXCCNT register */ +#define SCS_DWT_LSUCNT MMIO32(DWT_BASE + 0x14) + +/* DWT_EXCCNT register */ +#define SCS_DWT_FOLDCNT MMIO32(DWT_BASE + 0x18) + +/* DWT_PCSR register */ +#define SCS_DWT_PCSR MMIO32(DWT_BASE + 0x18) + +/* --- SCS_DWT_CTRL values ----------------------------------------------- */ +/* + * Enables CYCCNT: + * 0 = Disabled, 1 = Enabled + * This bit is UNK/SBZP if the NOCYCCNT bit is RAO. + */ +#define SCS_DWT_CTRL_CYCCNTENA (BIT0) + +/* TODO bit definition values for other DWT_XXX register */ + +/* Macro to be called at startup to enable SCS & Cycle Counter */ +#define SCS_DWT_CYCLE_COUNTER_ENABLED() ( (SCS_DEMCR |= SCS_DEMCR_TRCENA)\ + (SCS_DWT_CTRL |= SCS_DWT_CTRL_CYCCNTENA) ) + +#define SCS_SYSTICK_DISABLED() (SCS_SYST_CSR=0) + +/* Macro to be called at startup to Enable CortexMx SysTick (but IRQ not enabled) */ +#define SCS_SYSTICK_ENABLED() (SCS_SYST_CSR=(SCS_SYST_CSR_ENABLE | SCS_SYST_CSR_CLKSOURCE)) + +/* Macro to be called at startup to Enable CortexMx SysTick and IRQ */ +#define SCS_SYSTICK_AND_IRQ_ENABLED() (SCS_SYST_CSR=(SCS_SYST_CSR_ENABLE | SCS_SYST_CSR_CLKSOURCE | SCS_SYST_CSR_TICKINT)) + #endif diff --git a/include/libopencm3/lm3s/gpio.h b/include/libopencm3/lm3s/gpio.h index 852609fe..5296b74b 100644 --- a/include/libopencm3/lm3s/gpio.h +++ b/include/libopencm3/lm3s/gpio.h @@ -69,7 +69,11 @@ #define GPIO_CR(port) MMIO32(port + 0x524) #define GPIO_AMSEL(port) MMIO32(port + 0x528) +BEGIN_DECLS + void gpio_set(u32 gpioport, u8 gpios); void gpio_clear(u32 gpioport, u8 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/lpc17xx/gpio.h b/include/libopencm3/lpc17xx/gpio.h index 7b07ac53..15afd87b 100644 --- a/include/libopencm3/lpc17xx/gpio.h +++ b/include/libopencm3/lpc17xx/gpio.h @@ -132,7 +132,11 @@ /* Overall interrupt status */ #define GPIO_IS MMIO32(GPIOINTERRPUT_BASE + 0x80) +BEGIN_DECLS + void gpio_set(u32 gpioport, u32 gpios); void gpio_clear(u32 gpioport, u32 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/lpc43xx/adc.h b/include/libopencm3/lpc43xx/adc.h new file mode 100644 index 00000000..ff51e782 --- /dev/null +++ b/include/libopencm3/lpc43xx/adc.h @@ -0,0 +1,95 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_ADC_H +#define LPC43XX_ADC_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* ADC port base addresses (for convenience) */ +#define ADC0 ADC0_BASE +#define ADC1 ADC1_BASE + + +/* --- ADC registers ------------------------------------------------------- */ + +/* A/D Control Register */ +#define ADC_CR(port) MMIO32(port + 0x000) +#define ADC0_CR ADC_CR(ADC0) +#define ADC1_CR ADC_CR(ADC1) + +/* A/D Global Data Register */ +#define ADC_GDR(port) MMIO32(port + 0x004) +#define ADC0_GDR ADC_GDR(ADC0) +#define ADC1_GDR ADC_GDR(ADC1) + +/* A/D Interrupt Enable Register */ +#define ADC_INTEN(port) MMIO32(port + 0x00C) +#define ADC0_INTEN ADC_INTEN(ADC0) +#define ADC1_INTEN ADC_INTEN(ADC1) + +/* A/D Channel 0 Data Register */ +#define ADC_DR0(port) MMIO32(port + 0x010) +#define ADC0_DR0 ADC_DR0(ADC0) +#define ADC1_DR0 ADC_DR0(ADC1) + +/* A/D Channel 1 Data Register */ +#define ADC_DR1(port) MMIO32(port + 0x014) +#define ADC0_DR1 ADC_DR1(ADC0) +#define ADC1_DR1 ADC_DR1(ADC1) + +/* A/D Channel 2 Data Register */ +#define ADC_DR2(port) MMIO32(port + 0x018) +#define ADC0_DR2 ADC_DR2(ADC0) +#define ADC1_DR2 ADC_DR2(ADC1) + +/* A/D Channel 3 Data Register */ +#define ADC_DR3(port) MMIO32(port + 0x01C) +#define ADC0_DR3 ADC_DR3(ADC0) +#define ADC1_DR3 ADC_DR3(ADC1) + +/* A/D Channel 4 Data Register */ +#define ADC_DR4(port) MMIO32(port + 0x020) +#define ADC0_DR4 ADC_DR4(ADC0) +#define ADC1_DR4 ADC_DR4(ADC1) + +/* A/D Channel 5 Data Register */ +#define ADC_DR5(port) MMIO32(port + 0x024) +#define ADC0_DR5 ADC_DR5(ADC0) +#define ADC1_DR5 ADC_DR5(ADC1) + +/* A/D Channel 6 Data Register */ +#define ADC_DR6(port) MMIO32(port + 0x028) +#define ADC0_DR6 ADC_DR6(ADC0) +#define ADC1_DR6 ADC_DR6(ADC1) + +/* A/D Channel 7 Data Register */ +#define ADC_DR7(port) MMIO32(port + 0x02C) +#define ADC0_DR7 ADC_DR7(ADC0) +#define ADC1_DR7 ADC_DR7(ADC1) + +/* A/D Status Register */ +#define ADC_STAT(port) MMIO32(port + 0x030) +#define ADC0_STAT ADC_STAT(ADC0) +#define ADC1_STAT ADC_STAT(ADC1) + +#endif diff --git a/include/libopencm3/lpc43xx/atimer.h b/include/libopencm3/lpc43xx/atimer.h new file mode 100644 index 00000000..2a7655ff --- /dev/null +++ b/include/libopencm3/lpc43xx/atimer.h @@ -0,0 +1,52 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_ATIMER_H +#define LPC43XX_ATIMER_H + +#include +#include + +/* --- Alarm Timer registers ----------------------------------------------- */ + +/* Downcounter register */ +#define ATIMER_DOWNCOUNTER MMIO32(ATIMER_BASE + 0x000) + +/* Preset value register */ +#define ATIMER_PRESET MMIO32(ATIMER_BASE + 0x004) + +/* Interrupt clear enable register */ +#define ATIMER_CLR_EN MMIO32(ATIMER_BASE + 0xFD8) + +/* Interrupt set enable register */ +#define ATIMER_SET_EN MMIO32(ATIMER_BASE + 0xFDC) + +/* Status register */ +#define ATIMER_STATUS MMIO32(ATIMER_BASE + 0xFE0) + +/* Enable register */ +#define ATIMER_ENABLE MMIO32(ATIMER_BASE + 0xFE4) + +/* Clear register */ +#define ATIMER_CLR_STAT MMIO32(ATIMER_BASE + 0xFE8) + +/* Set register */ +#define ATIMER_SET_STAT MMIO32(ATIMER_BASE + 0xFEC) + +#endif diff --git a/include/libopencm3/lpc43xx/ccu.h b/include/libopencm3/lpc43xx/ccu.h new file mode 100644 index 00000000..068bd3d8 --- /dev/null +++ b/include/libopencm3/lpc43xx/ccu.h @@ -0,0 +1,384 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_CCU_H +#define LPC43XX_CCU_H + +#include +#include + +/* --- CCU1 registers ------------------------------------------------------ */ + +/* CCU1 power mode register */ +#define CCU1_PM MMIO32(CCU1_BASE + 0x000) + +/* CCU1 base clock status register */ +#define CCU1_BASE_STAT MMIO32(CCU1_BASE + 0x004) + +/* CLK_APB3_BUS clock configuration register */ +#define CCU1_CLK_APB3_BUS_CFG MMIO32(CCU1_BASE + 0x100) + +/* CLK_APB3_BUS clock status register */ +#define CCU1_CLK_APB3_BUS_STAT MMIO32(CCU1_BASE + 0x104) + +/* CLK_APB3_I2C1 configuration register */ +#define CCU1_CLK_APB3_I2C1_CFG MMIO32(CCU1_BASE + 0x108) + +/* CLK_APB3_I2C1 status register */ +#define CCU1_CLK_APB3_I2C1_STAT MMIO32(CCU1_BASE + 0x10C) + +/* CLK_APB3_DAC configuration register */ +#define CCU1_CLK_APB3_DAC_CFG MMIO32(CCU1_BASE + 0x110) + +/* CLK_APB3_DAC status register */ +#define CCU1_CLK_APB3_DAC_STAT MMIO32(CCU1_BASE + 0x114) + +/* CLK_APB3_ADC0 configuration register */ +#define CCU1_CLK_APB3_ADC0_CFG MMIO32(CCU1_BASE + 0x118) + +/* CLK_APB3_ADC0 status register */ +#define CCU1_CLK_APB3_ADC0_STAT MMIO32(CCU1_BASE + 0x11C) + +/* CLK_APB3_ADC1 configuration register */ +#define CCU1_CLK_APB3_ADC1_CFG MMIO32(CCU1_BASE + 0x120) + +/* CLK_APB3_ADC1 status register */ +#define CCU1_CLK_APB3_ADC1_STAT MMIO32(CCU1_BASE + 0x124) + +/* CLK_APB3_CAN0 configuration register */ +#define CCU1_CLK_APB3_CAN0_CFG MMIO32(CCU1_BASE + 0x128) + +/* CLK_APB3_CAN0 status register */ +#define CCU1_CLK_APB3_CAN0_STAT MMIO32(CCU1_BASE + 0x12C) + +/* CLK_APB1_BUS configuration register */ +#define CCU1_CLK_APB1_BUS_CFG MMIO32(CCU1_BASE + 0x200) + +/* CLK_APB1_BUS status register */ +#define CCU1_CLK_APB1_BUS_STAT MMIO32(CCU1_BASE + 0x204) + +/* CLK_APB1_MOTOCON configuration register */ +#define CCU1_CLK_APB1_MOTOCONPWM_CFG MMIO32(CCU1_BASE + 0x208) + +/* CLK_APB1_MOTOCON status register */ +#define CCU1_CLK_APB1_MOTOCONPWM_STAT MMIO32(CCU1_BASE + 0x20C) + +/* CLK_APB1_I2C0 configuration register */ +#define CCU1_CLK_APB1_I2C0_CFG MMIO32(CCU1_BASE + 0x210) + +/* CLK_APB1_I2C0 status register */ +#define CCU1_CLK_APB1_I2C0_STAT MMIO32(CCU1_BASE + 0x214) + +/* CLK_APB1_I2S configuration register */ +#define CCU1_CLK_APB1_I2S_CFG MMIO32(CCU1_BASE + 0x218) + +/* CLK_APB1_I2S status register */ +#define CCU1_CLK_APB1_I2S_STAT MMIO32(CCU1_BASE + 0x21C) + +/* CLK_APB3_CAN1 configuration register */ +#define CCU1_CLK_APB1_CAN1_CFG MMIO32(CCU1_BASE + 0x220) + +/* CLK_APB3_CAN1 status register */ +#define CCU1_CLK_APB1_CAN1_STAT MMIO32(CCU1_BASE + 0x224) + +/* CLK_SPIFI configuration register */ +#define CCU1_CLK_SPIFI_CFG MMIO32(CCU1_BASE + 0x300) + +/* CLK_SPIFI status register */ +#define CCU1_CLK_SPIFI_STAT MMIO32(CCU1_BASE + 0x304) + +/* CLK_M4_BUS configuration register */ +#define CCU1_CLK_M4_BUS_CFG MMIO32(CCU1_BASE + 0x400) + +/* CLK_M4_BUS status register */ +#define CCU1_CLK_M4_BUS_STAT MMIO32(CCU1_BASE + 0x404) + +/* CLK_M4_SPIFI configuration register */ +#define CCU1_CLK_M4_SPIFI_CFG MMIO32(CCU1_BASE + 0x408) + +/* CLK_M4_SPIFI status register */ +#define CCU1_CLK_M4_SPIFI_STAT MMIO32(CCU1_BASE + 0x40C) + +/* CLK_M4_GPIO configuration register */ +#define CCU1_CLK_M4_GPIO_CFG MMIO32(CCU1_BASE + 0x410) + +/* CLK_M4_GPIO status register */ +#define CCU1_CLK_M4_GPIO_STAT MMIO32(CCU1_BASE + 0x414) + +/* CLK_M4_LCD configuration register */ +#define CCU1_CLK_M4_LCD_CFG MMIO32(CCU1_BASE + 0x418) + +/* CLK_M4_LCD status register */ +#define CCU1_CLK_M4_LCD_STAT MMIO32(CCU1_BASE + 0x41C) + +/* CLK_M4_ETHERNET configuration register */ +#define CCU1_CLK_M4_ETHERNET_CFG MMIO32(CCU1_BASE + 0x420) + +/* CLK_M4_ETHERNET status register */ +#define CCU1_CLK_M4_ETHERNET_STAT MMIO32(CCU1_BASE + 0x424) + +/* CLK_M4_USB0 configuration register */ +#define CCU1_CLK_M4_USB0_CFG MMIO32(CCU1_BASE + 0x428) + +/* CLK_M4_USB0 status register */ +#define CCU1_CLK_M4_USB0_STAT MMIO32(CCU1_BASE + 0x42C) + +/* CLK_M4_EMC configuration register */ +#define CCU1_CLK_M4_EMC_CFG MMIO32(CCU1_BASE + 0x430) + +/* CLK_M4_EMC status register */ +#define CCU1_CLK_M4_EMC_STAT MMIO32(CCU1_BASE + 0x434) + +/* CLK_M4_SDIO configuration register */ +#define CCU1_CLK_M4_SDIO_CFG MMIO32(CCU1_BASE + 0x438) + +/* CLK_M4_SDIO status register */ +#define CCU1_CLK_M4_SDIO_STAT MMIO32(CCU1_BASE + 0x43C) + +/* CLK_M4_DMA configuration register */ +#define CCU1_CLK_M4_DMA_CFG MMIO32(CCU1_BASE + 0x440) + +/* CLK_M4_DMA status register */ +#define CCU1_CLK_M4_DMA_STAT MMIO32(CCU1_BASE + 0x444) + +/* CLK_M4_M4CORE configuration register */ +#define CCU1_CLK_M4_M4CORE_CFG MMIO32(CCU1_BASE + 0x448) + +/* CLK_M4_M4CORE status register */ +#define CCU1_CLK_M4_M4CORE_STAT MMIO32(CCU1_BASE + 0x44C) + +/* CLK_M4_SCT configuration register */ +#define CCU1_CLK_M4_SCT_CFG MMIO32(CCU1_BASE + 0x468) + +/* CLK_M4_SCT status register */ +#define CCU1_CLK_M4_SCT_STAT MMIO32(CCU1_BASE + 0x46C) + +/* CLK_M4_USB1 configuration register */ +#define CCU1_CLK_M4_USB1_CFG MMIO32(CCU1_BASE + 0x470) + +/* CLK_M4_USB1 status register */ +#define CCU1_CLK_M4_USB1_STAT MMIO32(CCU1_BASE + 0x474) + +/* CLK_M4_EMCDIV configuration register */ +#define CCU1_CLK_M4_EMCDIV_CFG MMIO32(CCU1_BASE + 0x478) + +/* CLK_M4_EMCDIV status register */ +#define CCU1_CLK_M4_EMCDIV_STAT MMIO32(CCU1_BASE + 0x47C) + +/* CLK_M4_M0_CFG configuration register */ +#define CCU1_CLK_M4_M0APP_CFG MMIO32(CCU1_BASE + 0x490) + +/* CLK_M4_M0_STAT status register */ +#define CCU1_CLK_M4_M0APP_STAT MMIO32(CCU1_BASE + 0x494) + +/* CLK_M4_VADC_CFG configuration register */ +#define CCU1_CLK_M4_VADC_CFG MMIO32(CCU1_BASE + 0x498) + +/* CLK_M4_VADC_STAT configuration register */ +#define CCU1_CLK_M4_VADC_STAT MMIO32(CCU1_BASE + 0x49C) + +/* CLK_M4_WWDT configuration register */ +#define CCU1_CLK_M4_WWDT_CFG MMIO32(CCU1_BASE + 0x500) + +/* CLK_M4_WWDT status register */ +#define CCU1_CLK_M4_WWDT_STAT MMIO32(CCU1_BASE + 0x504) + +/* CLK_M4_UART0 configuration register */ +#define CCU1_CLK_M4_USART0_CFG MMIO32(CCU1_BASE + 0x508) + +/* CLK_M4_UART0 status register */ +#define CCU1_CLK_M4_USART0_STAT MMIO32(CCU1_BASE + 0x50C) + +/* CLK_M4_UART1 configuration register */ +#define CCU1_CLK_M4_UART1_CFG MMIO32(CCU1_BASE + 0x510) + +/* CLK_M4_UART1 status register */ +#define CCU1_CLK_M4_UART1_STAT MMIO32(CCU1_BASE + 0x514) + +/* CLK_M4_SSP0 configuration register */ +#define CCU1_CLK_M4_SSP0_CFG MMIO32(CCU1_BASE + 0x518) + +/* CLK_M4_SSP0 status register */ +#define CCU1_CLK_M4_SSP0_STAT MMIO32(CCU1_BASE + 0x51C) + +/* CLK_M4_TIMER0 configuration register */ +#define CCU1_CLK_M4_TIMER0_CFG MMIO32(CCU1_BASE + 0x520) + +/* CLK_M4_TIMER0 status register */ +#define CCU1_CLK_M4_TIMER0_STAT MMIO32(CCU1_BASE + 0x524) + +/* CLK_M4_TIMER1 configuration register */ +#define CCU1_CLK_M4_TIMER1_CFG MMIO32(CCU1_BASE + 0x528) + +/* CLK_M4_TIMER1 status register */ +#define CCU1_CLK_M4_TIMER1_STAT MMIO32(CCU1_BASE + 0x52C) + +/* CLK_M4_SCU configuration register */ +#define CCU1_CLK_M4_SCU_CFG MMIO32(CCU1_BASE + 0x530) + +/* CLK_M4_SCU status register */ +#define CCU1_CLK_M4_SCU_STAT MMIO32(CCU1_BASE + 0x534) + +/* CLK_M4_CREG configuration register */ +#define CCU1_CLK_M4_CREG_CFG MMIO32(CCU1_BASE + 0x538) + +/* CLK_M4_CREG status register */ +#define CCU1_CLK_M4_CREG_STAT MMIO32(CCU1_BASE + 0x53C) + +/* CLK_M4_RITIMER configuration register */ +#define CCU1_CLK_M4_RITIMER_CFG MMIO32(CCU1_BASE + 0x600) + +/* CLK_M4_RITIMER status register */ +#define CCU1_CLK_M4_RITIMER_STAT MMIO32(CCU1_BASE + 0x604) + +/* CLK_M4_UART2 configuration register */ +#define CCU1_CLK_M4_USART2_CFG MMIO32(CCU1_BASE + 0x608) + +/* CLK_M4_UART2 status register */ +#define CCU1_CLK_M4_USART2_STAT MMIO32(CCU1_BASE + 0x60C) + +/* CLK_M4_UART3 configuration register */ +#define CCU1_CLK_M4_USART3_CFG MMIO32(CCU1_BASE + 0x610) + +/* CLK_M4_UART3 status register */ +#define CCU1_CLK_M4_USART3_STAT MMIO32(CCU1_BASE + 0x614) + +/* CLK_M4_TIMER2 configuration register */ +#define CCU1_CLK_M4_TIMER2_CFG MMIO32(CCU1_BASE + 0x618) + +/* CLK_M4_TIMER2 status register */ +#define CCU1_CLK_M4_TIMER2_STAT MMIO32(CCU1_BASE + 0x61C) + +/* CLK_M4_TIMER3 configuration register */ +#define CCU1_CLK_M4_TIMER3_CFG MMIO32(CCU1_BASE + 0x620) + +/* CLK_M4_TIMER3 status register */ +#define CCU1_CLK_M4_TIMER3_STAT MMIO32(CCU1_BASE + 0x624) + +/* CLK_M4_SSP1 configuration register */ +#define CCU1_CLK_M4_SSP1_CFG MMIO32(CCU1_BASE + 0x628) + +/* CLK_M4_SSP1 status register */ +#define CCU1_CLK_M4_SSP1_STAT MMIO32(CCU1_BASE + 0x62C) + +/* CLK_M4_QEI configuration register */ +#define CCU1_CLK_M4_QEI_CFG MMIO32(CCU1_BASE + 0x630) + +/* CLK_M4_QEI status register */ +#define CCU1_CLK_M4_QEI_STAT MMIO32(CCU1_BASE + 0x634) + +/* CLK_PERIPH_BUS configuration register */ +#define CCU1_CLK_PERIPH_BUS_CFG MMIO32(CCU1_BASE + 0x700) + +/* CLK_PERIPH_BUS status register */ +#define CCU1_CLK_PERIPH_BUS_STAT MMIO32(CCU1_BASE + 0x704) + +/* CLK_PERIPH_CORE configuration register */ +#define CCU1_CLK_PERIPH_CORE_CFG MMIO32(CCU1_BASE + 0x710) + +/* CLK_PERIPH_CORE status register */ +#define CCU1_CLK_PERIPH_CORE_STAT MMIO32(CCU1_BASE + 0x714) + +/* CLK_PERIPH_SGPIO configuration register */ +#define CCU1_CLK_PERIPH_SGPIO_CFG MMIO32(CCU1_BASE + 0x718) + +/* CLK_PERIPH_SGPIO status register */ +#define CCU1_CLK_PERIPH_SGPIO_STAT MMIO32(CCU1_BASE + 0x71C) + +/* CLK_USB0 configuration register */ +#define CCU1_CLK_USB0_CFG MMIO32(CCU1_BASE + 0x800) + +/* CLK_USB0 status register */ +#define CCU1_CLK_USB0_STAT MMIO32(CCU1_BASE + 0x804) + +/* CLK_USB1 configuration register */ +#define CCU1_CLK_USB1_CFG MMIO32(CCU1_BASE + 0x900) + +/* CLK_USB1 status register */ +#define CCU1_CLK_USB1_STAT MMIO32(CCU1_BASE + 0x904) + +/* CLK_SPI configuration register */ +#define CCU1_CLK_SPI_CFG MMIO32(CCU1_BASE + 0xA00) + +/* CLK_SPI status register */ +#define CCU1_CLK_SPI_STAT MMIO32(CCU1_BASE + 0xA04) + +/* CLK_VADC configuration register */ +#define CCU1_CLK_VADC_CFG MMIO32(CCU1_BASE + 0xB00) + +/* CLK_VADC status register */ +#define CCU1_CLK_VADC_STAT MMIO32(CCU1_BASE + 0xB04) + +/* --- CCU2 registers ------------------------------------------------------ */ + +/* CCU2 power mode register */ +#define CCU2_PM MMIO32(CCU2_BASE + 0x000) + +/* CCU2 base clocks status register */ +#define CCU2_BASE_STAT MMIO32(CCU2_BASE + 0x004) + +/* CLK_APLL configuration register */ +#define CCU2_CLK_APLL_CFG MMIO32(CCU2_BASE + 0x100) + +/* CLK_APLL status register */ +#define CCU2_CLK_APLL_STAT MMIO32(CCU2_BASE + 0x104) + +/* CLK_APB2_UART3 configuration register */ +#define CCU2_CLK_APB2_USART3_CFG MMIO32(CCU2_BASE + 0x200) + +/* CLK_APB2_UART3 status register */ +#define CCU2_CLK_APB2_USART3_STAT MMIO32(CCU2_BASE + 0x204) + +/* CLK_APB2_UART2 configuration register */ +#define CCU2_CLK_APB2_USART2_CFG MMIO32(CCU2_BASE + 0x300) + +/* CLK_APB2_UART2 status register */ +#define CCU2_CLK_APB2_USART2_STAT MMIO32(CCU2_BASE + 0x304) + +/* CLK_APB0_UART1 configuration register */ +#define CCU2_CLK_APB0_UART1_CFG MMIO32(CCU2_BASE + 0x400) + +/* CLK_APB0_UART1 status register */ +#define CCU2_CLK_APB0_UART1_STAT MMIO32(CCU2_BASE + 0x404) + +/* CLK_APB0_UART0 configuration register */ +#define CCU2_CLK_APB0_USART0_CFG MMIO32(CCU2_BASE + 0x500) + +/* CLK_APB0_UART0 status register */ +#define CCU2_CLK_APB0_USART0_STAT MMIO32(CCU2_BASE + 0x504) + +/* CLK_APB2_SSP1 configuration register */ +#define CCU2_CLK_APB2_SSP1_CFG MMIO32(CCU2_BASE + 0x600) + +/* CLK_APB2_SSP1 status register */ +#define CCU2_CLK_APB2_SSP1_STAT MMIO32(CCU2_BASE + 0x604) + +/* CLK_APB0_SSP0 configuration register */ +#define CCU2_CLK_APB0_SSP0_CFG MMIO32(CCU2_BASE + 0x700) + +/* CLK_APB0_SSP0 status register */ +#define CCU2_CLK_APB0_SSP0_STAT MMIO32(CCU2_BASE + 0x704) + +/* CLK_SDIO configuration register (for SD/MMC) */ +#define CCU2_CLK_SDIO_CFG MMIO32(CCU2_BASE + 0x800) + +/* CLK_SDIO status register (for SD/MMC) */ +#define CCU2_CLK_SDIO_STAT MMIO32(CCU2_BASE + 0x804) + +#endif diff --git a/include/libopencm3/lpc43xx/cgu.h b/include/libopencm3/lpc43xx/cgu.h new file mode 100644 index 00000000..c0ce8271 --- /dev/null +++ b/include/libopencm3/lpc43xx/cgu.h @@ -0,0 +1,239 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_CGU_H +#define CGU_LPC43XX_CGU_H + +#include +#include + +/* --- CGU registers ------------------------------------------------------- */ + +/* Frequency monitor register */ +#define CGU_FREQ_MON MMIO32(CGU_BASE + 0x014) + +/* Crystal oscillator control register */ +#define CGU_XTAL_OSC_CTRL MMIO32(CGU_BASE + 0x018) + +/* PLL0USB status register */ +#define CGU_PLL0USB_STAT MMIO32(CGU_BASE + 0x01C) + +/* PLL0USB control register */ +#define CGU_PLL0USB_CTRL MMIO32(CGU_BASE + 0x020) + +/* PLL0USB M-divider register */ +#define CGU_PLL0USB_MDIV MMIO32(CGU_BASE + 0x024) + +/* PLL0USB N/P-divider register */ +#define CGU_PLL0USB_NP_DIV MMIO32(CGU_BASE + 0x028) + +/* PLL0AUDIO status register */ +#define CGU_PLL0AUDIO_STAT MMIO32(CGU_BASE + 0x02C) + +/* PLL0AUDIO control register */ +#define CGU_PLL0AUDIO_CTRL MMIO32(CGU_BASE + 0x030) + +/* PLL0AUDIO M-divider register */ +#define CGU_PLL0AUDIO_MDIV MMIO32(CGU_BASE + 0x034) + +/* PLL0AUDIO N/P-divider register */ +#define CGU_PLL0AUDIO_NP_DIV MMIO32(CGU_BASE + 0x038) + +/* PLL0AUDIO fractional divider register */ +#define CGU_PLLAUDIO_FRAC MMIO32(CGU_BASE + 0x03C) + +/* PLL1 status register */ +#define CGU_PLL1_STAT MMIO32(CGU_BASE + 0x040) + +/* PLL1 control register */ +#define CGU_PLL1_CTRL MMIO32(CGU_BASE + 0x044) + +/* Integer divider A control register */ +#define CGU_IDIVA_CTRL MMIO32(CGU_BASE + 0x048) + +/* Integer divider B control register */ +#define CGU_IDIVB_CTRL MMIO32(CGU_BASE + 0x04C) + +/* Integer divider C control register */ +#define CGU_IDIVC_CTRL MMIO32(CGU_BASE + 0x050) + +/* Integer divider D control register */ +#define CGU_IDIVD_CTRL MMIO32(CGU_BASE + 0x054) + +/* Integer divider E control register */ +#define CGU_IDIVE_CTRL MMIO32(CGU_BASE + 0x058) + +/* Output stage 0 control register */ +#define CGU_BASE_SAFE_CLK MMIO32(CGU_BASE + 0x05C) + +/* Output stage 1 control register for base clock */ +#define CGU_BASE_USB0_CLK MMIO32(CGU_BASE + 0x060) + +/* Output stage 2 control register for base clock */ +#define CGU_BASE_PERIPH_CLK MMIO32(CGU_BASE + 0x064) + +/* Output stage 3 control register for base clock */ +#define CGU_BASE_USB1_CLK MMIO32(CGU_BASE + 0x068) + +/* Output stage 4 control register for base clock */ +#define CGU_BASE_M4_CLK MMIO32(CGU_BASE + 0x06C) + +/* Output stage 5 control register for base clock */ +#define CGU_BASE_SPIFI_CLK MMIO32(CGU_BASE + 0x070) + +/* Output stage 6 control register for base clock */ +#define CGU_BASE_SPI_CLK MMIO32(CGU_BASE + 0x074) + +/* Output stage 7 control register for base clock */ +#define CGU_BASE_PHY_RX_CLK MMIO32(CGU_BASE + 0x078) + +/* Output stage 8 control register for base clock */ +#define CGU_BASE_PHY_TX_CLK MMIO32(CGU_BASE + 0x07C) + +/* Output stage 9 control register for base clock */ +#define CGU_BASE_APB1_CLK MMIO32(CGU_BASE + 0x080) + +/* Output stage 10 control register for base clock */ +#define CGU_BASE_APB3_CLK MMIO32(CGU_BASE + 0x084) + +/* Output stage 11 control register for base clock */ +#define CGU_BASE_LCD_CLK MMIO32(CGU_BASE + 0x088) + +/* Output stage 12 control register for base clock */ +#define CGU_BASE_VADC_CLK MMIO32(CGU_BASE + 0x08C) + +/* Output stage 13 control register for base clock */ +#define CGU_BASE_SDIO_CLK MMIO32(CGU_BASE + 0x090) + +/* Output stage 14 control register for base clock */ +#define CGU_BASE_SSP0_CLK MMIO32(CGU_BASE + 0x094) + +/* Output stage 15 control register for base clock */ +#define CGU_BASE_SSP1_CLK MMIO32(CGU_BASE + 0x098) + +/* Output stage 16 control register for base clock */ +#define CGU_BASE_UART0_CLK MMIO32(CGU_BASE + 0x09C) + +/* Output stage 17 control register for base clock */ +#define CGU_BASE_UART1_CLK MMIO32(CGU_BASE + 0x0A0) + +/* Output stage 18 control register for base clock */ +#define CGU_BASE_UART2_CLK MMIO32(CGU_BASE + 0x0A4) + +/* Output stage 19 control register for base clock */ +#define CGU_BASE_UART3_CLK MMIO32(CGU_BASE + 0x0A8) + +/* Output stage 20 control register for base clock */ +#define CGU_BASE_OUT_CLK MMIO32(CGU_BASE + 0x0AC) + +/* Reserved output stage */ +#define CGU_OUTCLK_21_CTRL MMIO32(CGU_BASE + 0x0B0) + +/* Reserved output stage */ +#define CGU_OUTCLK_22_CTRL MMIO32(CGU_BASE + 0x0B4) + +/* Reserved output stage */ +#define CGU_OUTCLK_23_CTRL MMIO32(CGU_BASE + 0x0B8) + +/* Reserved output stage */ +#define CGU_OUTCLK_24_CTRL MMIO32(CGU_BASE + 0x0BC) + +/* Output stage 25 control register for base clock */ +#define CGU_BASE_APLL_CLK MMIO32(CGU_BASE + 0x0C0) + +/* Output stage 26 control CLK register for base clock */ +#define CGU_BASE_CGU_OUT0_CLK MMIO32(CGU_BASE + 0x0C4) + +/* Output stage 27 control CLK register for base clock */ +#define CGU_BASE_CGU_OUT1_CLK MMIO32(CGU_BASE + 0x0C8) + +/* --- CGU_XTAL_OSC_CTRL values -------------------------------------------- */ + +#define CGU_XTAL_OSC_CTRL_ENABLE (1 << 0) /* enable or power down xtal osc */ +#define CGU_XTAL_OSC_CTRL_BYPASS (1 << 1) /* external clock input (not xtal) */ +#define CGU_XTAL_OSC_CTRL_HF (1 << 2) /* high frequency mode (>15 MHz) */ + +/* --- CGU_PLL1_STAT values ------------------------------------------------ */ + +#define CGU_PLL1_STAT_LOCK (1 << 0) + +/* --- CGU_PLL1_CTRL values ------------------------------------------------ */ + +#define CGU_PLL1_CTRL_PD (1 << 0) /* power down */ +#define CGU_PLL1_CTRL_BYPASS (1 << 1) /* PLL input to post-dividers */ +#define CGU_PLL1_CTRL_FBSEL (1 << 6) /* use clkout as feedback input */ +#define CGU_PLL1_CTRL_DIRECT (1 << 7) /* enable direct CCO output */ +#define CGU_PLL1_CTRL_PSEL_SHIFT 8 /* division ratio P (2 bits) */ +#define CGU_PLL1_CTRL_AUTOBLOCK (1 << 11) /* block clock automatically */ +#define CGU_PLL1_CTRL_NSEL_SHIFT 12 /* division ratio N (2 bits) */ +#define CGU_PLL1_CTRL_MSEL_SHIFT 16 /* division ratio M (8 bits) */ +#define CGU_PLL1_CTRL_CLK_SEL_SHIFT 24 /* clock source (5 bits) */ + +/* --- CGU_PLL0USB_STAT values --------------------------------------------- */ + +#define CGU_PLL0USB_STAT_LOCK (1 << 0) /* PLL0 lock indicator */ +#define CGU_PLL0USB_STAT_FR (1 << 1) /* PLL0 free running indicator */ + +/* --- CGU_PLL0USB_CTRL values --------------------------------------------- */ + +#define CGU_PLL0USB_CTRL_PD (1 << 0) /* power down */ +#define CGU_PLL0USB_CTRL_BYPASS (1 << 1) /* input to post-dividers */ +#define CGU_PLL0USB_CTRL_DIRECTI (1 << 2) /* direct input */ +#define CGU_PLL0USB_CTRL_DIRECTO (1 << 3) /* direct output */ +#define CGU_PLL0USB_CTRL_CLKEN (1 << 4) /* clock enable */ +#define CGU_PLL0USB_CTRL_FRM (1 << 6) /* free running mode */ +#define CGU_PLL0USB_CTRL_AUTOBLOCK (1 << 11) /* block clock automatically */ +#define CGU_PLL0USB_CTRL_CLK_SEL_SHIFT 24 /* clock source (5 bits) */ + +/* --- CGU_PLL0USB_MDIV values --------------------------------------------- */ + +#define CGU_PLL0USB_MDIV_MDEC_SHIFT 0 /* Decoded M-divider value (17 bits) */ +#define CGU_PLL0USB_SELP_MDEC_SHIFT 17 /* Bandwidth select P value (5 bits) */ +#define CGU_PLL0USB_SELI_MDEC_SHIFT 22 /* Bandwidth select I value (6 bits) */ +#define CGU_PLL0USB_SELR_MDEC_SHIFT 28 /* Bandwidth select R value (4 bits) */ + +/* --- CGU_PLL0USB_NP_DIV values ------------------------------------------- */ + +#define CGU_PLL0USB_NP_DIV_PDEC_SHIFT 0 /* Decoded P-divider value (7 bits) */ +#define CGU_PLL0USB_NP_DIV_NDEC_SHIFT 12 /* Decoded N-divider value (8 bits) */ + +/* --- CGU_BASE_x_CLK values ----------------------------------------------- */ + +#define CGU_BASE_CLK_PD (1 << 0) /* output stage power-down */ +#define CGU_BASE_CLK_AUTOBLOCK (1 << 11) /* block clock automatically */ +#define CGU_BASE_CLK_SEL_SHIFT 24 /* clock source selection (5 bits) */ + +/* --- CGU_BASE_x_CLK clock sources --------------------------------------- */ + +#define CGU_SRC_32K 0x00 +#define CGU_SRC_IRC 0x01 +#define CGU_SRC_ENET_RX 0x02 +#define CGU_SRC_ENET_TX 0x03 +#define CGU_SRC_GP_CLKIN 0x04 +#define CGU_SRC_XTAL 0x06 +#define CGU_SRC_PLL0USB 0x07 +#define CGU_SRC_PLL0AUDIO 0x08 +#define CGU_SRC_PLL1 0x09 +#define CGU_SRC_IDIVA 0x0C +#define CGU_SRC_IDIVB 0x0D +#define CGU_SRC_IDIVC 0x0E +#define CGU_SRC_IDIVD 0x0F +#define CGU_SRC_IDIVE 0x10 + +#endif diff --git a/include/libopencm3/lpc43xx/creg.h b/include/libopencm3/lpc43xx/creg.h new file mode 100644 index 00000000..dafc8824 --- /dev/null +++ b/include/libopencm3/lpc43xx/creg.h @@ -0,0 +1,76 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_CREG_H +#define LPC43XX_CREG_H + +#include +#include + +/* --- CREG registers ----------------------------------------------------- */ + +/* + * Chip configuration register 32 kHz oscillator output and BOD control + * register + */ +#define CREG_CREG0 MMIO32(CREG_BASE + 0x004) + +/* ARM Cortex-M4 memory mapping */ +#define CREG_M4MEMMAP MMIO32(CREG_BASE + 0x100) + +/* Chip configuration register 1 */ +#define CREG_CREG1 MMIO32(CREG_BASE + 0x108) + +/* Chip configuration register 2 */ +#define CREG_CREG2 MMIO32(CREG_BASE + 0x10C) + +/* Chip configuration register 3 */ +#define CREG_CREG3 MMIO32(CREG_BASE + 0x110) + +/* Chip configuration register 4 */ +#define CREG_CREG4 MMIO32(CREG_BASE + 0x114) + +/* Chip configuration register 5 */ +#define CREG_CREG5 MMIO32(CREG_BASE + 0x118) + +/* DMA muxing control */ +#define CREG_DMAMUX MMIO32(CREG_BASE + 0x11C) + +/* ETB RAM configuration */ +#define CREG_ETBCFG MMIO32(CREG_BASE + 0x128) + +/* + * Chip configuration register 6. Controls multiple functions: Ethernet + * interface, SCT output, I2S0/1 inputs, EMC clock. + */ +#define CREG_CREG6 MMIO32(CREG_BASE + 0x12C) + +/* Cortex-M4 TXEV event clear */ +#define CREG_M4TXEVENT MMIO32(CREG_BASE + 0x130) + +/* Part ID */ +#define CREG_CHIPID MMIO32(CREG_BASE + 0x200) + +/* Cortex-M0 TXEV event clear */ +#define CREG_M0TXEVENT MMIO32(CREG_BASE + 0x400) + +/* ARM Cortex-M0 memory mapping */ +#define CREG_M0APPMEMMAP MMIO32(CREG_BASE + 0x404) + +#endif diff --git a/include/libopencm3/lpc43xx/eventrouter.h b/include/libopencm3/lpc43xx/eventrouter.h new file mode 100644 index 00000000..d326988b --- /dev/null +++ b/include/libopencm3/lpc43xx/eventrouter.h @@ -0,0 +1,52 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_EVENTROUTER_H +#define LPC43XX_EVENTROUTER_H + +#include +#include + +/* --- Event Router registers ---------------------------------------------- */ + +/* Level configuration register */ +#define EVENTROUTER_HILO MMIO32(EVENTROUTER_BASE + 0x000) + +/* Edge configuration */ +#define EVENTROUTER_EDGE MMIO32(EVENTROUTER_BASE + 0x004) + +/* Clear event enable register */ +#define EVENTROUTER_CLR_EN MMIO32(EVENTROUTER_BASE + 0xFD8) + +/* Set event enable register */ +#define EVENTROUTER_ET_EN MMIO32(EVENTROUTER_BASE + 0xFDC) + +/* Event Status register */ +#define EVENTROUTER_STATUS MMIO32(EVENTROUTER_BASE + 0xFE0) + +/* Event Enable register */ +#define EVENTROUTER_ENABLE MMIO32(EVENTROUTER_BASE + 0xFE4) + +/* Clear event status register */ +#define EVENTROUTER_CLR_STAT MMIO32(EVENTROUTER_BASE + 0xFE8) + +/* Set event status register */ +#define EVENTROUTER_SET_STAT MMIO32(EVENTROUTER_BASE + 0xFEC) + +#endif diff --git a/include/libopencm3/lpc43xx/gima.h b/include/libopencm3/lpc43xx/gima.h new file mode 100644 index 00000000..ee14ecc0 --- /dev/null +++ b/include/libopencm3/lpc43xx/gima.h @@ -0,0 +1,118 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_GIMA_H +#define LPC43XX_GIMA_H + +#include +#include + +/* --- GIMA registers ----------------------------------------------------- */ + +/* Timer 0 CAP0_0 capture input multiplexer (GIMA output 0) */ +#define GIMA_CAP0_0_IN MMIO32(GIMA_BASE + 0x000) + +/* Timer 0 CAP0_1 capture input multiplexer (GIMA output 1) */ +#define GIMA_CAP0_1_IN MMIO32(GIMA_BASE + 0x004) + +/* Timer 0 CAP0_2 capture input multiplexer (GIMA output 2) */ +#define GIMA_CAP0_2_IN MMIO32(GIMA_BASE + 0x008) + +/* Timer 0 CAP0_3 capture input multiplexer (GIMA output 3) */ +#define GIMA_CAP0_3_IN MMIO32(GIMA_BASE + 0x00C) + +/* Timer 1 CAP1_0 capture input multiplexer (GIMA output 4) */ +#define GIMA_CAP1_0_IN MMIO32(GIMA_BASE + 0x010) + +/* Timer 1 CAP1_1 capture input multiplexer (GIMA output 5) */ +#define GIMA_CAP1_1_IN MMIO32(GIMA_BASE + 0x014) + +/* Timer 1 CAP1_2 capture input multiplexer (GIMA output 6) */ +#define GIMA_CAP1_2_IN MMIO32(GIMA_BASE + 0x018) + +/* Timer 1 CAP1_3 capture input multiplexer (GIMA output 7) */ +#define GIMA_CAP1_3_IN MMIO32(GIMA_BASE + 0x01C) + +/* Timer 2 CAP2_0 capture input multiplexer (GIMA output 8) */ +#define GIMA_CAP2_0_IN MMIO32(GIMA_BASE + 0x020) + +/* Timer 2 CAP2_1 capture input multiplexer (GIMA output 9) */ +#define GIMA_CAP2_1_IN MMIO32(GIMA_BASE + 0x024) + +/* Timer 2 CAP2_2 capture input multiplexer (GIMA output 10) */ +#define GIMA_CAP2_2_IN MMIO32(GIMA_BASE + 0x028) + +/* Timer 2 CAP2_3 capture input multiplexer (GIMA output 11) */ +#define GIMA_CAP2_3_IN MMIO32(GIMA_BASE + 0x02C) + +/* Timer 3 CAP3_0 capture input multiplexer (GIMA output 12) */ +#define GIMA_CAP3_0_IN MMIO32(GIMA_BASE + 0x030) + +/* Timer 3 CAP3_1 capture input multiplexer (GIMA output 13) */ +#define GIMA_CAP3_1_IN MMIO32(GIMA_BASE + 0x034) + +/* Timer 3 CAP3_2 capture input multiplexer (GIMA output 14) */ +#define GIMA_CAP3_2_IN MMIO32(GIMA_BASE + 0x038) + +/* Timer 3 CAP3_3 capture input multiplexer (GIMA output 15) */ +#define GIMA_CAP3_3_IN MMIO32(GIMA_BASE + 0x03C) + +/* SCT CTIN_0 capture input multiplexer (GIMA output 16) */ +#define GIMA_CTIN_0_IN MMIO32(GIMA_BASE + 0x040) + +/* SCT CTIN_1 capture input multiplexer (GIMA output 17) */ +#define GIMA_CTIN_1_IN MMIO32(GIMA_BASE + 0x044) + +/* SCT CTIN_2 capture input multiplexer (GIMA output 18) */ +#define GIMA_CTIN_2_IN MMIO32(GIMA_BASE + 0x048) + +/* SCT CTIN_3 capture input multiplexer (GIMA output 19) */ +#define GIMA_CTIN_3_IN MMIO32(GIMA_BASE + 0x04C) + +/* SCT CTIN_4 capture input multiplexer (GIMA output 20) */ +#define GIMA_CTIN_4_IN MMIO32(GIMA_BASE + 0x050) + +/* SCT CTIN_5 capture input multiplexer (GIMA output 21) */ +#define GIMA_CTIN_5_IN MMIO32(GIMA_BASE + 0x054) + +/* SCT CTIN_6 capture input multiplexer (GIMA output 22) */ +#define GIMA_CTIN_6_IN MMIO32(GIMA_BASE + 0x058) + +/* SCT CTIN_7 capture input multiplexer (GIMA output 23) */ +#define GIMA_CTIN_7_IN MMIO32(GIMA_BASE + 0x05C) + +/* VADC trigger input multiplexer (GIMA output 24) */ +#define GIMA_VADC_TRIGGER_IN MMIO32(GIMA_BASE + 0x060) + +/* Event router input 13 multiplexer (GIMA output 25) */ +#define GIMA_EVENTROUTER_13_IN MMIO32(GIMA_BASE + 0x064) + +/* Event router input 14 multiplexer (GIMA output 26) */ +#define GIMA_EVENTROUTER_14_IN MMIO32(GIMA_BASE + 0x068) + +/* Event router input 16 multiplexer (GIMA output 27) */ +#define GIMA_EVENTROUTER_16_IN MMIO32(GIMA_BASE + 0x06C) + +/* ADC start0 input multiplexer (GIMA output 28) */ +#define GIMA_ADCSTART0_IN MMIO32(GIMA_BASE + 0x070) + +/* ADC start1 input multiplexer (GIMA output 29) */ +#define GIMA_ADCSTART1_IN MMIO32(GIMA_BASE + 0x074) + +#endif diff --git a/include/libopencm3/lpc43xx/gpdma.h b/include/libopencm3/lpc43xx/gpdma.h new file mode 100644 index 00000000..064ccd77 --- /dev/null +++ b/include/libopencm3/lpc43xx/gpdma.h @@ -0,0 +1,143 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_GPDMA_H +#define LPC43XX_GPDMA_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPDMA channel base addresses */ +#define GPDMA_CHANNEL0 (GPDMA_PORT_BASE + 0x100) +#define GPDMA_CHANNEL1 (GPDMA_PORT_BASE + 0x120) +#define GPDMA_CHANNEL2 (GPDMA_PORT_BASE + 0x140) +#define GPDMA_CHANNEL3 (GPDMA_PORT_BASE + 0x160) +#define GPDMA_CHANNEL4 (GPDMA_PORT_BASE + 0x180) +#define GPDMA_CHANNEL5 (GPDMA_PORT_BASE + 0x1A0) +#define GPDMA_CHANNEL6 (GPDMA_PORT_BASE + 0x1C0) +#define GPDMA_CHANNEL7 (GPDMA_PORT_BASE + 0x1E0) + + +/* --- GPDMA registers ----------------------------------------------------- */ + +/* General registers */ + +/* DMA Interrupt Status Register */ +#define GPDMA_NTSTAT MMIO32(GPDMA_BASE + 0x000) + +/* DMA Interrupt Terminal Count Request Status Register */ +#define GPDMA_INTTCSTAT MMIO32(GPDMA_BASE + 0x004) + +/* DMA Interrupt Terminal Count Request Clear Register */ +#define GPDMA_INTTCCLEAR MMIO32(GPDMA_BASE + 0x008) + +/* DMA Interrupt Error Status Register */ +#define GPDMA_INTERRSTAT MMIO32(GPDMA_BASE + 0x00C) + +/* DMA Interrupt Error Clear Register */ +#define GPDMA_INTERRCLR MMIO32(GPDMA_BASE + 0x010) + +/* DMA Raw Interrupt Terminal Count Status Register */ +#define GPDMA_RAWINTTCSTAT MMIO32(GPDMA_BASE + 0x014) + +/* DMA Raw Error Interrupt Status Register */ +#define GPDMA_RAWINTERRSTAT MMIO32(GPDMA_BASE + 0x018) + +/* DMA Enabled Channel Register */ +#define GPDMA_ENBLDCHNS MMIO32(GPDMA_BASE + 0x01C) + +/* DMA Software Burst Request Register */ +#define GPDMA_SOFTBREQ MMIO32(GPDMA_BASE + 0x020) + +/* DMA Software Single Request Register */ +#define GPDMA_SOFTSREQ MMIO32(GPDMA_BASE + 0x024) + +/* DMA Software Last Burst Request Register */ +#define GPDMA_SOFTLBREQ MMIO32(GPDMA_BASE + 0x028) + +/* DMA Software Last Single Request Register */ +#define GPDMA_SOFTLSREQ MMIO32(GPDMA_BASE + 0x02C) + +/* DMA Configuration Register */ +#define GPDMA_CONFIG MMIO32(GPDMA_BASE + 0x030) + +/* DMA Synchronization Register */ +#define GPDMA_SYNC MMIO32(GPDMA_BASE + 0x034) + + +/* Channel registers */ + +/* Source Address Register */ +#define GPDMA_SRCADDR(channel) MMIO32(channel + 0x000) +#define GPDMA_C0SRCADDR GPDMA_SRCADDR(GPDMA_CHANNEL0) +#define GPDMA_C1SRCADDR GPDMA_SRCADDR(GPDMA_CHANNEL1) +#define GPDMA_C2SRCADDR GPDMA_SRCADDR(GPDMA_CHANNEL2) +#define GPDMA_C3SRCADDR GPDMA_SRCADDR(GPDMA_CHANNEL3) +#define GPDMA_C4SRCADDR GPDMA_SRCADDR(GPDMA_CHANNEL4) +#define GPDMA_C5SRCADDR GPDMA_SRCADDR(GPDMA_CHANNEL5) +#define GPDMA_C6SRCADDR GPDMA_SRCADDR(GPDMA_CHANNEL6) +#define GPDMA_C7SRCADDR GPDMA_SRCADDR(GPDMA_CHANNEL7) + +/* Destination Address Register */ +#define GPDMA_DESTADDR(channel) MMIO32(channel + 0x004) +#define GPDMA_C0DESTADDR GPDMA_DESTADDR(GPDMA_CHANNEL0) +#define GPDMA_C1DESTADDR GPDMA_DESTADDR(GPDMA_CHANNEL1) +#define GPDMA_C2DESTADDR GPDMA_DESTADDR(GPDMA_CHANNEL2) +#define GPDMA_C3DESTADDR GPDMA_DESTADDR(GPDMA_CHANNEL3) +#define GPDMA_C4DESTADDR GPDMA_DESTADDR(GPDMA_CHANNEL4) +#define GPDMA_C5DESTADDR GPDMA_DESTADDR(GPDMA_CHANNEL5) +#define GPDMA_C6DESTADDR GPDMA_DESTADDR(GPDMA_CHANNEL6) +#define GPDMA_C7DESTADDR GPDMA_DESTADDR(GPDMA_CHANNEL7) + +/* Linked List Item Register */ +#define GPDMA_LLI(channel) MMIO32(channel + 0x008) +#define GPDMA_C0LLI GPDMA_LLI(GPDMA_CHANNEL0) +#define GPDMA_C1LLI GPDMA_LLI(GPDMA_CHANNEL1) +#define GPDMA_C2LLI GPDMA_LLI(GPDMA_CHANNEL2) +#define GPDMA_C3LLI GPDMA_LLI(GPDMA_CHANNEL3) +#define GPDMA_C4LLI GPDMA_LLI(GPDMA_CHANNEL4) +#define GPDMA_C5LLI GPDMA_LLI(GPDMA_CHANNEL5) +#define GPDMA_C6LLI GPDMA_LLI(GPDMA_CHANNEL6) +#define GPDMA_C7LLI GPDMA_LLI(GPDMA_CHANNEL7) + +/* Control Register */ +#define GPDMA_CONTROL(channel) MMIO32(channel + 0x00C) +#define GPDMA_C0CONTROL GPDMA_CONTROL(GPDMA_CHANNEL0) +#define GPDMA_C1CONTROL GPDMA_CONTROL(GPDMA_CHANNEL1) +#define GPDMA_C2CONTROL GPDMA_CONTROL(GPDMA_CHANNEL2) +#define GPDMA_C3CONTROL GPDMA_CONTROL(GPDMA_CHANNEL3) +#define GPDMA_C4CONTROL GPDMA_CONTROL(GPDMA_CHANNEL4) +#define GPDMA_C5CONTROL GPDMA_CONTROL(GPDMA_CHANNEL5) +#define GPDMA_C6CONTROL GPDMA_CONTROL(GPDMA_CHANNEL6) +#define GPDMA_C7CONTROL GPDMA_CONTROL(GPDMA_CHANNEL7) + +/* Configuration Register */ +#define GPDMA_CONFIG(channel) MMIO32(channel + 0x010) +#define GPDMA_C0CONFIG GPDMA_CONFIG(GPDMA_CHANNEL0) +#define GPDMA_C1CONFIG GPDMA_CONFIG(GPDMA_CHANNEL1) +#define GPDMA_C2CONFIG GPDMA_CONFIG(GPDMA_CHANNEL2) +#define GPDMA_C3CONFIG GPDMA_CONFIG(GPDMA_CHANNEL3) +#define GPDMA_C4CONFIG GPDMA_CONFIG(GPDMA_CHANNEL4) +#define GPDMA_C5CONFIG GPDMA_CONFIG(GPDMA_CHANNEL5) +#define GPDMA_C6CONFIG GPDMA_CONFIG(GPDMA_CHANNEL6) +#define GPDMA_C7CONFIG GPDMA_CONFIG(GPDMA_CHANNEL7) + +#endif diff --git a/include/libopencm3/lpc43xx/gpio.h b/include/libopencm3/lpc43xx/gpio.h new file mode 100644 index 00000000..daa21fd3 --- /dev/null +++ b/include/libopencm3/lpc43xx/gpio.h @@ -0,0 +1,164 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_GPIO_H +#define LPC43XX_GPIO_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPIO port base addresses (for convenience) */ +#define GPIO0 (GPIO_PORT_BASE + 0x2000) +#define GPIO1 (GPIO_PORT_BASE + 0x2004) +#define GPIO2 (GPIO_PORT_BASE + 0x2008) +#define GPIO3 (GPIO_PORT_BASE + 0x200C) +#define GPIO4 (GPIO_PORT_BASE + 0x2010) +#define GPIO5 (GPIO_PORT_BASE + 0x2014) +#define GPIO6 (GPIO_PORT_BASE + 0x2018) +#define GPIO7 (GPIO_PORT_BASE + 0x201C) + +/* GPIO number definitions (for convenience) */ +#define GPIOPIN0 (1 << 0) +#define GPIOPIN1 (1 << 1) +#define GPIOPIN2 (1 << 2) +#define GPIOPIN3 (1 << 3) +#define GPIOPIN4 (1 << 4) +#define GPIOPIN5 (1 << 5) +#define GPIOPIN6 (1 << 6) +#define GPIOPIN7 (1 << 7) +#define GPIOPIN8 (1 << 8) +#define GPIOPIN9 (1 << 9) +#define GPIOPIN10 (1 << 10) +#define GPIOPIN11 (1 << 11) +#define GPIOPIN12 (1 << 12) +#define GPIOPIN13 (1 << 13) +#define GPIOPIN14 (1 << 14) +#define GPIOPIN15 (1 << 15) +#define GPIOPIN16 (1 << 16) +#define GPIOPIN17 (1 << 17) +#define GPIOPIN18 (1 << 18) +#define GPIOPIN19 (1 << 19) +#define GPIOPIN20 (1 << 20) +#define GPIOPIN21 (1 << 21) +#define GPIOPIN22 (1 << 22) +#define GPIOPIN23 (1 << 23) +#define GPIOPIN24 (1 << 24) +#define GPIOPIN25 (1 << 25) +#define GPIOPIN26 (1 << 26) +#define GPIOPIN27 (1 << 27) +#define GPIOPIN28 (1 << 28) +#define GPIOPIN29 (1 << 29) +#define GPIOPIN30 (1 << 30) +#define GPIOPIN31 (1 << 31) + +/* --- GPIO registers ------------------------------------------------------ */ + +//TODO byte/word access registers + +/* GPIO data direction register (GPIOn_DIR) */ +#define GPIO_DIR(port) MMIO32(port + 0x00) +#define GPIO0_DIR GPIO_DIR(GPIO0) +#define GPIO1_DIR GPIO_DIR(GPIO1) +#define GPIO2_DIR GPIO_DIR(GPIO2) +#define GPIO3_DIR GPIO_DIR(GPIO3) +#define GPIO4_DIR GPIO_DIR(GPIO4) +#define GPIO5_DIR GPIO_DIR(GPIO5) +#define GPIO6_DIR GPIO_DIR(GPIO6) +#define GPIO7_DIR GPIO_DIR(GPIO7) + +/* GPIO fast mask register (GPIOn_MASK) */ +#define GPIO_MASK(port) MMIO32(port + 0x80) +#define GPIO0_MASK GPIO_MASK(GPIO0) +#define GPIO1_MASK GPIO_MASK(GPIO1) +#define GPIO2_MASK GPIO_MASK(GPIO2) +#define GPIO3_MASK GPIO_MASK(GPIO3) +#define GPIO4_MASK GPIO_MASK(GPIO4) +#define GPIO5_MASK GPIO_MASK(GPIO5) +#define GPIO6_MASK GPIO_MASK(GPIO6) +#define GPIO7_MASK GPIO_MASK(GPIO7) + +/* GPIO port pin value register (GPIOn_PIN) */ +#define GPIO_PIN(port) MMIO32(port + 0x100) +#define GPIO0_PIN GPIO_PIN(GPIO0) +#define GPIO1_PIN GPIO_PIN(GPIO1) +#define GPIO2_PIN GPIO_PIN(GPIO2) +#define GPIO3_PIN GPIO_PIN(GPIO3) +#define GPIO4_PIN GPIO_PIN(GPIO4) +#define GPIO5_PIN GPIO_PIN(GPIO5) +#define GPIO6_PIN GPIO_PIN(GPIO6) +#define GPIO7_PIN GPIO_PIN(GPIO7) + +/* GPIO port masked pin value register (GPIOn_MPIN) */ +#define GPIO_MPIN(port) MMIO32(port + 0x180) +#define GPIO0_MPIN GPIO_MPIN(GPIO0) +#define GPIO1_MPIN GPIO_MPIN(GPIO1) +#define GPIO2_MPIN GPIO_MPIN(GPIO2) +#define GPIO3_MPIN GPIO_MPIN(GPIO3) +#define GPIO4_MPIN GPIO_MPIN(GPIO4) +#define GPIO5_MPIN GPIO_MPIN(GPIO5) +#define GPIO6_MPIN GPIO_MPIN(GPIO6) +#define GPIO7_MPIN GPIO_MPIN(GPIO7) + +/* GPIO port output set register (GPIOn_SET) */ +#define GPIO_SET(port) MMIO32(port + 0x200) +#define GPIO0_SET GPIO_SET(GPIO0) +#define GPIO1_SET GPIO_SET(GPIO1) +#define GPIO2_SET GPIO_SET(GPIO2) +#define GPIO3_SET GPIO_SET(GPIO3) +#define GPIO4_SET GPIO_SET(GPIO4) +#define GPIO5_SET GPIO_SET(GPIO5) +#define GPIO6_SET GPIO_SET(GPIO6) +#define GPIO7_SET GPIO_SET(GPIO7) + +/* GPIO port output clear register (GPIOn_CLR) */ +#define GPIO_CLR(port) MMIO32(port + 0x280) +#define GPIO0_CLR GPIO_CLR(GPIO0) +#define GPIO1_CLR GPIO_CLR(GPIO1) +#define GPIO2_CLR GPIO_CLR(GPIO2) +#define GPIO3_CLR GPIO_CLR(GPIO3) +#define GPIO4_CLR GPIO_CLR(GPIO4) +#define GPIO5_CLR GPIO_CLR(GPIO5) +#define GPIO6_CLR GPIO_CLR(GPIO6) +#define GPIO7_CLR GPIO_CLR(GPIO7) + +/* GPIO port toggle register (GPIOn_NOT) */ +#define GPIO_NOT(port) MMIO32(port + 0x300) +#define GPIO0_NOT GPIO_NOT(GPIO0) +#define GPIO1_NOT GPIO_NOT(GPIO1) +#define GPIO2_NOT GPIO_NOT(GPIO2) +#define GPIO3_NOT GPIO_NOT(GPIO3) +#define GPIO4_NOT GPIO_NOT(GPIO4) +#define GPIO5_NOT GPIO_NOT(GPIO5) +#define GPIO6_NOT GPIO_NOT(GPIO6) +#define GPIO7_NOT GPIO_NOT(GPIO7) + +//TODO interrupts + +BEGIN_DECLS + +void gpio_set(u32 gpioport, u32 gpios); +void gpio_clear(u32 gpioport, u32 gpios); +void gpio_toggle(u32 gpioport, u32 gpios); + +END_DECLS + +#endif diff --git a/include/libopencm3/lpc43xx/i2c.h b/include/libopencm3/lpc43xx/i2c.h new file mode 100644 index 00000000..29e797e5 --- /dev/null +++ b/include/libopencm3/lpc43xx/i2c.h @@ -0,0 +1,146 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_I2C_H +#define LPC43XX_I2C_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* I2C port base addresses (for convenience) */ +#define I2C0 I2C0_BASE +#define I2C1 I2C1_BASE + +/* --- I2C registers ------------------------------------------------------- */ + +/* I2C Control Set Register */ +#define I2C_CONSET(port) MMIO32(port + 0x000) +#define I2C0_CONSET I2C_CONSET(I2C0) +#define I2C1_CONSET I2C_CONSET(I2C1) + +/* I2C Status Register */ +#define I2C_STAT(port) MMIO32(port + 0x004) +#define I2C0_STAT I2C_STAT(I2C0) +#define I2C1_STAT I2C_STAT(I2C1) + +/* I2C Data Register */ +#define I2C_DAT(port) MMIO32(port + 0x008) +#define I2C0_DAT I2C_DAT(I2C0) +#define I2C1_DAT I2C_DAT(I2C1) + +/* I2C Slave Address Register 0 */ +#define I2C_ADR0(port) MMIO32(port + 0x00C) +#define I2C0_ADR0 I2C_ADR0(I2C0) +#define I2C1_ADR0 I2C_ADR0(I2C1) + +/* SCH Duty Cycle Register High Half Word */ +#define I2C_SCLH(port) MMIO32(port + 0x010) +#define I2C0_SCLH I2C_SCLH(I2C0) +#define I2C1_SCLH I2C_SCLH(I2C1) + +/* SCL Duty Cycle Register Low Half Word */ +#define I2C_SCLL(port) MMIO32(port + 0x014) +#define I2C0_SCLL I2C_SCLL(I2C0) +#define I2C1_SCLL I2C_SCLL(I2C1) + +/* I2C Control Clear Register */ +#define I2C_CONCLR(port) MMIO32(port + 0x018) +#define I2C0_CONCLR I2C_CONCLR(I2C0) +#define I2C1_CONCLR I2C_CONCLR(I2C1) + +/* Monitor mode control register */ +#define I2C_MMCTRL(port) MMIO32(port + 0x01C) +#define I2C0_MMCTRL I2C_MMCTRL(I2C0) +#define I2C1_MMCTRL I2C_MMCTRL(I2C1) + +/* I2C Slave Address Register 1 */ +#define I2C_ADR1(port) MMIO32(port + 0x020) +#define I2C0_ADR1 I2C_ADR1(I2C0) +#define I2C1_ADR1 I2C_ADR1(I2C1) + +/* I2C Slave Address Register 2 */ +#define I2C_ADR2(port) MMIO32(port + 0x024) +#define I2C0_ADR2 I2C_ADR2(I2C0) +#define I2C1_ADR2 I2C_ADR2(I2C1) + +/* I2C Slave Address Register 3 */ +#define I2C_ADR3(port) MMIO32(port + 0x028) +#define I2C0_ADR3 I2C_ADR3(I2C0) +#define I2C1_ADR3 I2C_ADR3(I2C1) + +/* Data buffer register */ +#define I2C_DATA_BUFFER(port) MMIO32(port + 0x02C) +#define I2C0_DATA_BUFFER I2C_DATA_BUFFER(I2C0) +#define I2C1_DATA_BUFFER I2C_DATA_BUFFER(I2C1) + +/* I2C Slave address mask register 0 */ +#define I2C_MASK0(port) MMIO32(port + 0x030) +#define I2C0_MASK0 I2C_MASK0(I2C0) +#define I2C1_MASK0 I2C_MASK0(I2C1) + +/* I2C Slave address mask register 1 */ +#define I2C_MASK1(port) MMIO32(port + 0x034) +#define I2C0_MASK1 I2C_MASK1(I2C0) +#define I2C1_MASK1 I2C_MASK1(I2C1) + +/* I2C Slave address mask register 2 */ +#define I2C_MASK2(port) MMIO32(port + 0x038) +#define I2C0_MASK2 I2C_MASK2(I2C0) +#define I2C1_MASK2 I2C_MASK2(I2C1) + +/* I2C Slave address mask register 3 */ +#define I2C_MASK3(port) MMIO32(port + 0x03C) +#define I2C0_MASK3 I2C_MASK3(I2C0) +#define I2C1_MASK3 I2C_MASK3(I2C1) + +/* --- I2Cx_CONCLR values -------------------------------------------------- */ + +#define I2C_CONCLR_AAC (1 << 2) /* Assert acknowledge Clear */ +#define I2C_CONCLR_SIC (1 << 3) /* I2C interrupt Clear */ +#define I2C_CONCLR_STAC (1 << 5) /* START flag Clear */ +#define I2C_CONCLR_I2ENC (1 << 6) /* I2C interface Disable bit */ + +/* --- I2Cx_CONSET values -------------------------------------------------- */ + +#define I2C_CONSET_AA (1 << 2) /* Assert acknowledge flag */ +#define I2C_CONSET_SI (1 << 3) /* I2C interrupt flag */ +#define I2C_CONSET_STO (1 << 4) /* STOP flag */ +#define I2C_CONSET_STA (1 << 5) /* START flag */ +#define I2C_CONSET_I2EN (1 << 6) /* I2C interface enable */ + +/* --- I2C const definitions ----------------------------------------------- */ + +#define I2C_WRITE 0 +#define I2C_READ 1 + +/* --- I2C function prototypes --------------------------------------------- */ + +BEGIN_DECLS + +void i2c0_init(void); +void i2c0_tx_start(void); +void i2c0_tx_byte(u8 byte); +u8 i2c0_rx_byte(void); +void i2c0_stop(void); + +END_DECLS + +#endif diff --git a/include/libopencm3/lpc43xx/i2s.h b/include/libopencm3/lpc43xx/i2s.h new file mode 100644 index 00000000..8c9c5dba --- /dev/null +++ b/include/libopencm3/lpc43xx/i2s.h @@ -0,0 +1,105 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_I2S_H +#define LPC43XX_I2S_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* I2S port base addresses (for convenience) */ +#define I2S0 I2S0_BASE +#define I2S1 I2S1_BASE + + +/* --- I2S registers ------------------------------------------------------- */ + +/* I2S Digital Audio Output Register */ +#define I2S_DAO(port) MMIO32(port + 0x000) +#define I2S0_DAO I2S_DAO(I2S0) +#define I2S1_DAO I2S_DAO(I2S1) + +/* I2S Digital Audio Input Register */ +#define I2S_DAI(port) MMIO32(port + 0x004) +#define I2S0_DAI I2S_DAI(I2S0) +#define I2S1_DAI I2S_DAI(I2S1) + +/* I2S Transmit FIFO */ +#define I2S_TXFIFO(port) MMIO32(port + 0x008) +#define I2S0_TXFIFO I2S_TXFIFO(I2S0) +#define I2S1_TXFIFO I2S_TXFIFO(I2S1) + +/* I2S Receive FIFO */ +#define I2S_RXFIFO(port) MMIO32(port + 0x00C) +#define I2S0_RXFIFO I2S_RXFIFO(I2S0) +#define I2S1_RXFIFO I2S_RXFIFO(I2S1) + +/* I2S Status Feedback Register */ +#define I2S_STATE(port) MMIO32(port + 0x010) +#define I2S0_STATE I2S_STATE(I2S0) +#define I2S1_STATE I2S_STATE(I2S1) + +/* I2S DMA Configuration Register 1 */ +#define I2S_DMA1(port) MMIO32(port + 0x014) +#define I2S0_DMA1 I2S_DMA1(I2S0) +#define I2S1_DMA1 I2S_DMA1(I2S1) + +/* I2S DMA Configuration Register 2 */ +#define I2S_DMA2(port) MMIO32(port + 0x018) +#define I2S0_DMA2 I2S_DMA2(I2S0) +#define I2S1_DMA2 I2S_DMA2(I2S1) + +/* I2S Interrupt Request Control Register */ +#define I2S_IRQ(port) MMIO32(port + 0x01C) +#define I2S0_IRQ I2S_IRQ(I2S0) +#define I2S1_IRQ I2S_IRQ(I2S1) + +/* I2S Transmit MCLK divider */ +#define I2S_TXRATE(port) MMIO32(port + 0x020) +#define I2S0_TXRATE I2S_TXRATE(I2S0) +#define I2S1_TXRATE I2S_TXRATE(I2S1) + +/* I2S Receive MCLK divider */ +#define I2S_RXRATE(port) MMIO32(port + 0x024) +#define I2S0_RXRATE I2S_RXRATE(I2S0) +#define I2S1_RXRATE I2S_RXRATE(I2S1) + +/* I2S Transmit bit rate divider */ +#define I2S_TXBITRATE(port) MMIO32(port + 0x028) +#define I2S0_TXBITRATE I2S_TXBITRATE(I2S0) +#define I2S1_TXBITRATE I2S_TXBITRATE(I2S1) + +/* I2S Receive bit rate divider */ +#define I2S_RXBITRATE(port) MMIO32(port + 0x02C) +#define I2S0_RXBITRATE I2S_RXBITRATE(I2S0) +#define I2S1_RXBITRATE I2S_RXBITRATE(I2S1) + +/* I2S Transmit mode control */ +#define I2S_TXMODE(port) MMIO32(port + 0x030) +#define I2S0_TXMODE I2S_TXMODE(I2S0) +#define I2S1_TXMODE I2S_TXMODE(I2S1) + +/* I2S Receive mode control */ +#define I2S_RXMODE(port) MMIO32(port + 0x034) +#define I2S0_RXMODE I2S_RXMODE(I2S0) +#define I2S1_RXMODE I2S_RXMODE(I2S1) + +#endif diff --git a/include/libopencm3/lpc43xx/memorymap.h b/include/libopencm3/lpc43xx/memorymap.h new file mode 100644 index 00000000..9ea38fb5 --- /dev/null +++ b/include/libopencm3/lpc43xx/memorymap.h @@ -0,0 +1,138 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_MEMORYMAP_H +#define LPC43XX_MEMORYMAP_H + +#include + +/* --- LPC43XX specific peripheral definitions ----------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE_AHB 0x40000000 +#define PERIPH_BASE_APB0 0x40080000 +#define PERIPH_BASE_APB1 0x400A0000 +#define PERIPH_BASE_APB2 0x400C0000 +#define PERIPH_BASE_APB3 0x400E0000 + +/* Register boundary addresses */ + +/* AHB (0x4000 0000 - 0x4001 2000) */ +#define SCT_BASE (PERIPH_BASE_AHB + 0x00000) +/* PERIPH_BASE_AHB + 0x01000 (0x4000 1000 - 0x4000 1FFF): Reserved */ +#define DMA_BASE (PERIPH_BASE_AHB + 0x02000) +#define SPIFI_BASE (PERIPH_BASE_AHB + 0x03000) +#define SDIO_BASE (PERIPH_BASE_AHB + 0x04000) +#define EMC_BASE (PERIPH_BASE_AHB + 0x05000) +#define USB0_BASE (PERIPH_BASE_AHB + 0x06000) +#define USB1_BASE (PERIPH_BASE_AHB + 0x07000) +#define LCD_BASE (PERIPH_BASE_AHB + 0x08000) +/* PERIPH_BASE_AHB + 0x09000 (0x4000 9000 - 0x4000 FFFF): Reserved */ +#define ETHERNET_BASE (PERIPH_BASE_AHB + 0x10000) + +/* 0x4001 2000 - 0x4003 FFFF Reserved */ + +/* RTC domain peripherals */ +#define ATIMER_BASE 0x40040000 +#define BACKUP_REG_BASE 0x40041000 +#define PMC_BASE 0x40042000 +#define CREG_BASE 0x40043000 +#define EVENTROUTER_BASE 0x40044000 +#define OTP_BASE 0x40045000 +#define RTC_BASE 0x40046000 +/* 0x4004 7000 - 0x4004 FFFF Reserved */ + +/* clocking/reset control peripherals */ +#define CGU_BASE 0x40050000 +#define CCU1_BASE 0x40051000 +#define CCU2_BASE 0x40052000 +#define RGU_BASE 0x40053000 +/* 0x4005 4000 - 0x4005 FFFF Reserved */ + +/* 0x4006 0000 - 0x4007 FFFF Reserved */ + +/* APB0 ( 0x4008 0000 - 0x4008 FFFF) */ +#define WWDT_BASE (PERIPH_BASE_APB0 + 0x00000) +#define USART0_BASE (PERIPH_BASE_APB0 + 0x01000) +#define UART1_BASE (PERIPH_BASE_APB0 + 0x02000) +#define SSP0_BASE (PERIPH_BASE_APB0 + 0x03000) +#define TIMER0_BASE (PERIPH_BASE_APB0 + 0x04000) +#define TIMER1_BASE (PERIPH_BASE_APB0 + 0x05000) +#define SCU_BASE (PERIPH_BASE_APB0 + 0x06000) +#define GPIO_PIN_INTERRUPT_BASE (PERIPH_BASE_APB0 + 0x07000) +#define GPIO_GROUP0_INTRRUPT_BASE (PERIPH_BASE_APB0 + 0x08000) +#define GPIO_GROUP1_INTRRUPT_BASE (PERIPH_BASE_APB0 + 0x09000) +/* 0x4008 A000 - 0x4008 FFFF Reserved */ + +/* 0x4009 0000 - 0x4009 FFFF Reserved */ + +/* APB1 (0x400A 0000 - 0x400A FFFF) */ +#define MCPWM_BASE (PERIPH_BASE_APB1 + 0x00000) +#define I2C0_BASE (PERIPH_BASE_APB1 + 0x01000) +#define I2S0_BASE (PERIPH_BASE_APB1 + 0x02000) +#define I2S1_BASE (PERIPH_BASE_APB1 + 0x03000) +#define C_CCAN1_BASE (PERIPH_BASE_APB1 + 0x04000) +/* 0x400A 5000 - 0x400A FFFF Reserved */ + +/* 0x400B 0000 - 0x400B FFFF Reserved */ + +/* APB2 (0x400C 0000 - 0x400C FFFF) */ +#define RITIMER_BASE (PERIPH_BASE_APB2 + 0x00000) +#define USART2_BASE (PERIPH_BASE_APB2 + 0x01000) +#define USART3_BASE (PERIPH_BASE_APB2 + 0x02000) +#define TIMER2_BASE (PERIPH_BASE_APB2 + 0x03000) +#define TIMER3_BASE (PERIPH_BASE_APB2 + 0x04000) +#define SSP1_BASE (PERIPH_BASE_APB2 + 0x05000) +#define QEI_BASE (PERIPH_BASE_APB2 + 0x06000) +#define GIMA_BASE (PERIPH_BASE_APB2 + 0x07000) +/* 0x400C 8000 - 0x400C FFFF Reserved */ + +/* 0x400D 0000 - 0x400D FFFF Reserved */ + +/* APB3 (0x400E 0000 - 0x400E FFFF) */ +#define I2C1_BASE (PERIPH_BASE_APB3 + 0x00000) +#define DAC_BASE (PERIPH_BASE_APB3 + 0x01000) +#define C_CAN0_BASE (PERIPH_BASE_APB3 + 0x02000) +#define ADC0_BASE (PERIPH_BASE_APB3 + 0x03000) +#define ADC1_BASE (PERIPH_BASE_APB3 + 0x04000) +/* 0x400E 5000 - 0x400E FFFF Reserved */ + +/* 0x400F 0000 - 0x400F 0FFF Reserved */ + +#define AES_BASE 0x400F1000 + +/* 0x400F 2000 - 0x400F 3FFF Reserved */ + +#define GPIO_PORT_BASE 0x400F4000 + +/* 0x400F 8000 - 0x400F FFFF Reserved */ + +#define SPI_PORT_BASE 0x40100000 +#define SGPIO_PORT_BASE 0x40101000 + +/* 0x4010 2000 - 0x41FF FFFF Reserved */ + +/* 0x4200 0000 - 0x43FF FFFF peripheral bit band alias region */ + +/* 0x4400 0000 - 0x5FFF FFFF Reserved */ + +/* 0x6000 0000 - 0xFFFF FFFF external memories and ARM private bus */ + +#endif diff --git a/include/libopencm3/lpc43xx/nvic.h b/include/libopencm3/lpc43xx/nvic.h new file mode 100644 index 00000000..cdbf0702 --- /dev/null +++ b/include/libopencm3/lpc43xx/nvic.h @@ -0,0 +1,151 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +#ifndef LPC43XX_NVIC_H +#define LPC43XX_NVIC_H + +#include +#include +#include + +/* --- 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/rgu.h b/include/libopencm3/lpc43xx/rgu.h new file mode 100644 index 00000000..777158bb --- /dev/null +++ b/include/libopencm3/lpc43xx/rgu.h @@ -0,0 +1,244 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_RGU_H +#define LPC43XX_RGU_H + +#include +#include + +/* --- RGU registers ------------------------------------------------------- */ + +/* Reset control register 0 */ +#define RESET_CTRL0 MMIO32(RGU_BASE + 0x100) + +/* Reset control register 1 */ +#define RESET_CTRL1 MMIO32(RGU_BASE + 0x104) + +/* Reset status register 0 */ +#define RESET_STATUS0 MMIO32(RGU_BASE + 0x110) + +/* Reset status register 1 */ +#define RESET_STATUS1 MMIO32(RGU_BASE + 0x114) + +/* Reset status register 2 */ +#define RESET_STATUS2 MMIO32(RGU_BASE + 0x118) + +/* Reset status register 3 */ +#define RESET_STATUS3 MMIO32(RGU_BASE + 0x11C) + +/* Reset active status register 0 */ +#define RESET_ACTIVE_STATUS0 MMIO32(RGU_BASE + 0x150) + +/* Reset active status register 1 */ +#define RESET_ACTIVE_STATUS1 MMIO32(RGU_BASE + 0x154) + +/* Reset external status register 0 for CORE_RST */ +#define RESET_EXT_STAT0 MMIO32(RGU_BASE + 0x400) + +/* Reset external status register 1 for PERIPH_RST */ +#define RESET_EXT_STAT1 MMIO32(RGU_BASE + 0x404) + +/* Reset external status register 2 for MASTER_RST */ +#define RESET_EXT_STAT2 MMIO32(RGU_BASE + 0x408) + +/* Reserved */ +#define RESET_EXT_STAT3 MMIO32(RGU_BASE + 0x40C) + +/* Reset external status register 4 for WWDT_RST */ +#define RESET_EXT_STAT4 MMIO32(RGU_BASE + 0x410) + +/* Reset external status register 5 for CREG_RST */ +#define RESET_EXT_STAT5 MMIO32(RGU_BASE + 0x414) + +/* Reserved */ +#define RESET_EXT_STAT6 MMIO32(RGU_BASE + 0x418) + +/* Reserved */ +#define RESET_EXT_STAT7 MMIO32(RGU_BASE + 0x41C) + +/* Reset external status register 8 for BUS_RST */ +#define RESET_EXT_STAT8 MMIO32(RGU_BASE + 0x420) + +/* Reset external status register 9 for SCU_RST */ +#define RESET_EXT_STAT9 MMIO32(RGU_BASE + 0x424) + +/* Reserved */ +#define RESET_EXT_STAT10 MMIO32(RGU_BASE + 0x428) + +/* Reserved */ +#define RESET_EXT_STAT11 MMIO32(RGU_BASE + 0x42C) + +/* Reserved */ +#define RESET_EXT_STAT12 MMIO32(RGU_BASE + 0x430) + +/* Reset external status register 13 for M4_RST */ +#define RESET_EXT_STAT13 MMIO32(RGU_BASE + 0x434) + +/* Reserved */ +#define RESET_EXT_STAT14 MMIO32(RGU_BASE + 0x438) + +/* Reserved */ +#define RESET_EXT_STAT15 MMIO32(RGU_BASE + 0x43C) + +/* Reset external status register 16 for LCD_RST */ +#define RESET_EXT_STAT16 MMIO32(RGU_BASE + 0x440) + +/* Reset external status register 17 for USB0_RST */ +#define RESET_EXT_STAT17 MMIO32(RGU_BASE + 0x444) + +/* Reset external status register 18 for USB1_RST */ +#define RESET_EXT_STAT18 MMIO32(RGU_BASE + 0x448) + +/* Reset external status register 19 for DMA_RST */ +#define RESET_EXT_STAT19 MMIO32(RGU_BASE + 0x44C) + +/* Reset external status register 20 for SDIO_RST */ +#define RESET_EXT_STAT20 MMIO32(RGU_BASE + 0x450) + +/* Reset external status register 21 for EMC_RST */ +#define RESET_EXT_STAT21 MMIO32(RGU_BASE + 0x454) + +/* Reset external status register 22 for ETHERNET_RST */ +#define RESET_EXT_STAT22 MMIO32(RGU_BASE + 0x458) + +/* Reserved */ +#define RESET_EXT_STAT23 MMIO32(RGU_BASE + 0x45C) + +/* Reserved */ +#define RESET_EXT_STAT24 MMIO32(RGU_BASE + 0x460) + +/* Reserved */ +#define RESET_EXT_STAT25 MMIO32(RGU_BASE + 0x464) + +/* Reserved */ +#define RESET_EXT_STAT26 MMIO32(RGU_BASE + 0x468) + +/* Reserved */ +#define RESET_EXT_STAT27 MMIO32(RGU_BASE + 0x46C) + +/* Reset external status register 28 for GPIO_RST */ +#define RESET_EXT_STAT28 MMIO32(RGU_BASE + 0x470) + +/* Reserved */ +#define RESET_EXT_STAT29 MMIO32(RGU_BASE + 0x474) + +/* Reserved */ +#define RESET_EXT_STAT30 MMIO32(RGU_BASE + 0x478) + +/* Reserved */ +#define RESET_EXT_STAT31 MMIO32(RGU_BASE + 0x47C) + +/* Reset external status register 32 for TIMER0_RST */ +#define RESET_EXT_STAT32 MMIO32(RGU_BASE + 0x480) + +/* Reset external status register 33 for TIMER1_RST */ +#define RESET_EXT_STAT33 MMIO32(RGU_BASE + 0x484) + +/* Reset external status register 34 for TIMER2_RST */ +#define RESET_EXT_STAT34 MMIO32(RGU_BASE + 0x488) + +/* Reset external status register 35 for TIMER3_RST */ +#define RESET_EXT_STAT35 MMIO32(RGU_BASE + 0x48C) + +/* Reset external status register 36 for RITIMER_RST */ +#define RESET_EXT_STAT36 MMIO32(RGU_BASE + 0x490) + +/* Reset external status register 37 for SCT_RST */ +#define RESET_EXT_STAT37 MMIO32(RGU_BASE + 0x494) + +/* Reset external status register 38 for MOTOCONPWM_RST */ +#define RESET_EXT_STAT38 MMIO32(RGU_BASE + 0x498) + +/* Reset external status register 39 for QEI_RST */ +#define RESET_EXT_STAT39 MMIO32(RGU_BASE + 0x49C) + +/* Reset external status register 40 for ADC0_RST */ +#define RESET_EXT_STAT40 MMIO32(RGU_BASE + 0x4A0) + +/* Reset external status register 41 for ADC1_RST */ +#define RESET_EXT_STAT41 MMIO32(RGU_BASE + 0x4A4) + +/* Reset external status register 42 for DAC_RST */ +#define RESET_EXT_STAT42 MMIO32(RGU_BASE + 0x4A8) + +/* Reserved */ +#define RESET_EXT_STAT43 MMIO32(RGU_BASE + 0x4AC) + +/* Reset external status register 44 for UART0_RST */ +#define RESET_EXT_STAT44 MMIO32(RGU_BASE + 0x4B0) + +/* Reset external status register 45 for UART1_RST */ +#define RESET_EXT_STAT45 MMIO32(RGU_BASE + 0x4B4) + +/* Reset external status register 46 for UART2_RST */ +#define RESET_EXT_STAT46 MMIO32(RGU_BASE + 0x4B8) + +/* Reset external status register 47 for UART3_RST */ +#define RESET_EXT_STAT47 MMIO32(RGU_BASE + 0x4BC) + +/* Reset external status register 48 for I2C0_RST */ +#define RESET_EXT_STAT48 MMIO32(RGU_BASE + 0x4C0) + +/* Reset external status register 49 for I2C1_RST */ +#define RESET_EXT_STAT49 MMIO32(RGU_BASE + 0x4C4) + +/* Reset external status register 50 for SSP0_RST */ +#define RESET_EXT_STAT50 MMIO32(RGU_BASE + 0x4C8) + +/* Reset external status register 51 for SSP1_RST */ +#define RESET_EXT_STAT51 MMIO32(RGU_BASE + 0x4CC) + +/* Reset external status register 52 for I2S_RST */ +#define RESET_EXT_STAT52 MMIO32(RGU_BASE + 0x4D0) + +/* Reset external status register 53 for SPIFI_RST */ +#define RESET_EXT_STAT53 MMIO32(RGU_BASE + 0x4D4) + +/* Reset external status register 54 for CAN1_RST */ +#define RESET_EXT_STAT54 MMIO32(RGU_BASE + 0x4D8) + +/* Reset external status register 55 for CAN0_RST */ +#define RESET_EXT_STAT55 MMIO32(RGU_BASE + 0x4DC) + +/* Reset external status register 56 for M0APP_RST */ +#define RESET_EXT_STAT56 MMIO32(RGU_BASE + 0x4E0) + +/* Reset external status register 57 for SGPIO_RST */ +#define RESET_EXT_STAT57 MMIO32(RGU_BASE + 0x4E4) + +/* Reset external status register 58 for SPI_RST */ +#define RESET_EXT_STAT58 MMIO32(RGU_BASE + 0x4E8) + +/* Reserved */ +#define RESET_EXT_STAT59 MMIO32(RGU_BASE + 0x4EC) + +/* Reserved */ +#define RESET_EXT_STAT60 MMIO32(RGU_BASE + 0x4F0) + +/* Reserved */ +#define RESET_EXT_STAT61 MMIO32(RGU_BASE + 0x4F4) + +/* Reserved */ +#define RESET_EXT_STAT62 MMIO32(RGU_BASE + 0x4F8) + +/* Reserved */ +#define RESET_EXT_STAT63 MMIO32(RGU_BASE + 0x4FC) + +#endif diff --git a/include/libopencm3/lpc43xx/ritimer.h b/include/libopencm3/lpc43xx/ritimer.h new file mode 100644 index 00000000..d231a41c --- /dev/null +++ b/include/libopencm3/lpc43xx/ritimer.h @@ -0,0 +1,40 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_RITIMER_H +#define LPC43XX_RITIMER_H + +#include +#include + +/* --- Repetitive Interrupt Timer registers -------------------------------- */ + +/* Compare register */ +#define RITIMER_COMPVAL MMIO32(RITIMER_BASE + 0x000) + +/* Mask register */ +#define RITIMER_MASK MMIO32(RITIMER_BASE + 0x004) + +/* Control register */ +#define RITIMER_CTRL MMIO32(RITIMER_BASE + 0x008) + +/* 32-bit counter */ +#define RITIMER_COUNTER MMIO32(RITIMER_BASE + 0x00C) + +#endif diff --git a/include/libopencm3/lpc43xx/scu.h b/include/libopencm3/lpc43xx/scu.h new file mode 100644 index 00000000..c1b9fc24 --- /dev/null +++ b/include/libopencm3/lpc43xx/scu.h @@ -0,0 +1,734 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Michael Ossmann +* Copyright (C) 2012 Benjamin Vernoux +* +* 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 . +*/ + +#ifndef LPC43XX_SCU_H +#define LPC43XX_SCU_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* Pin group base addresses */ +#define PIN_GROUP0 (SCU_BASE + 0x000) +#define PIN_GROUP1 (SCU_BASE + 0x080) +#define PIN_GROUP2 (SCU_BASE + 0x100) +#define PIN_GROUP3 (SCU_BASE + 0x180) +#define PIN_GROUP4 (SCU_BASE + 0x200) +#define PIN_GROUP5 (SCU_BASE + 0x280) +#define PIN_GROUP6 (SCU_BASE + 0x300) +#define PIN_GROUP7 (SCU_BASE + 0x380) +#define PIN_GROUP8 (SCU_BASE + 0x400) +#define PIN_GROUP9 (SCU_BASE + 0x480) +#define PIN_GROUPA (SCU_BASE + 0x500) +#define PIN_GROUPB (SCU_BASE + 0x580) +#define PIN_GROUPC (SCU_BASE + 0x600) +#define PIN_GROUPD (SCU_BASE + 0x680) +#define PIN_GROUPE (SCU_BASE + 0x700) +#define PIN_GROUPF (SCU_BASE + 0x780) + +#define PIN0 0x000 +#define PIN1 0x004 +#define PIN2 0x008 +#define PIN3 0x00C +#define PIN4 0x010 +#define PIN5 0x014 +#define PIN6 0x018 +#define PIN7 0x01C +#define PIN8 0x020 +#define PIN9 0x024 +#define PIN10 0x028 +#define PIN11 0x02C +#define PIN12 0x030 +#define PIN13 0x034 +#define PIN14 0x038 +#define PIN15 0x03C +#define PIN16 0x040 +#define PIN17 0x044 +#define PIN18 0x048 +#define PIN19 0x04C +#define PIN20 0x050 + + +/* --- SCU registers ------------------------------------------------------- */ + +/* Pin configuration registers */ + +#define SCU_SFS(group, pin) MMIO32(group + pin) + +/* Pins P0_n */ +#define SCU_SFSP0_0 SCU_SFS(PIN_GROUP0, PIN0) +#define SCU_SFSP0_1 SCU_SFS(PIN_GROUP0, PIN1) + +/* Pins P1_n */ +#define SCU_SFSP1_0 SCU_SFS(PIN_GROUP1, PIN0) +#define SCU_SFSP1_1 SCU_SFS(PIN_GROUP1, PIN1) +#define SCU_SFSP1_2 SCU_SFS(PIN_GROUP1, PIN2) +#define SCU_SFSP1_3 SCU_SFS(PIN_GROUP1, PIN3) +#define SCU_SFSP1_4 SCU_SFS(PIN_GROUP1, PIN4) +#define SCU_SFSP1_5 SCU_SFS(PIN_GROUP1, PIN5) +#define SCU_SFSP1_6 SCU_SFS(PIN_GROUP1, PIN6) +#define SCU_SFSP1_7 SCU_SFS(PIN_GROUP1, PIN7) +#define SCU_SFSP1_8 SCU_SFS(PIN_GROUP1, PIN8) +#define SCU_SFSP1_9 SCU_SFS(PIN_GROUP1, PIN9) +#define SCU_SFSP1_10 SCU_SFS(PIN_GROUP1, PIN10) +#define SCU_SFSP1_11 SCU_SFS(PIN_GROUP1, PIN11) +#define SCU_SFSP1_12 SCU_SFS(PIN_GROUP1, PIN12) +#define SCU_SFSP1_13 SCU_SFS(PIN_GROUP1, PIN13) +#define SCU_SFSP1_14 SCU_SFS(PIN_GROUP1, PIN14) +#define SCU_SFSP1_15 SCU_SFS(PIN_GROUP1, PIN15) +#define SCU_SFSP1_16 SCU_SFS(PIN_GROUP1, PIN16) +#define SCU_SFSP1_17 SCU_SFS(PIN_GROUP1, PIN17) +#define SCU_SFSP1_18 SCU_SFS(PIN_GROUP1, PIN18) +#define SCU_SFSP1_19 SCU_SFS(PIN_GROUP1, PIN19) +#define SCU_SFSP1_20 SCU_SFS(PIN_GROUP1, PIN20) + +/* Pins P2_n */ +#define SCU_SFSP2_0 SCU_SFS(PIN_GROUP2, PIN0) +#define SCU_SFSP2_1 SCU_SFS(PIN_GROUP2, PIN1) +#define SCU_SFSP2_2 SCU_SFS(PIN_GROUP2, PIN2) +#define SCU_SFSP2_3 SCU_SFS(PIN_GROUP2, PIN3) +#define SCU_SFSP2_4 SCU_SFS(PIN_GROUP2, PIN4) +#define SCU_SFSP2_5 SCU_SFS(PIN_GROUP2, PIN5) +#define SCU_SFSP2_6 SCU_SFS(PIN_GROUP2, PIN6) +#define SCU_SFSP2_7 SCU_SFS(PIN_GROUP2, PIN7) +#define SCU_SFSP2_8 SCU_SFS(PIN_GROUP2, PIN8) +#define SCU_SFSP2_9 SCU_SFS(PIN_GROUP2, PIN9) +#define SCU_SFSP2_10 SCU_SFS(PIN_GROUP2, PIN10) +#define SCU_SFSP2_11 SCU_SFS(PIN_GROUP2, PIN11) +#define SCU_SFSP2_12 SCU_SFS(PIN_GROUP2, PIN12) +#define SCU_SFSP2_13 SCU_SFS(PIN_GROUP2, PIN13) + +/* Pins P3_n */ +#define SCU_SFSP3_0 SCU_SFS(PIN_GROUP3, PIN0) +#define SCU_SFSP3_1 SCU_SFS(PIN_GROUP3, PIN1) +#define SCU_SFSP3_2 SCU_SFS(PIN_GROUP3, PIN2) +#define SCU_SFSP3_3 SCU_SFS(PIN_GROUP3, PIN3) +#define SCU_SFSP3_4 SCU_SFS(PIN_GROUP3, PIN4) +#define SCU_SFSP3_5 SCU_SFS(PIN_GROUP3, PIN5) +#define SCU_SFSP3_6 SCU_SFS(PIN_GROUP3, PIN6) +#define SCU_SFSP3_7 SCU_SFS(PIN_GROUP3, PIN7) +#define SCU_SFSP3_8 SCU_SFS(PIN_GROUP3, PIN8) + +/* Pins P4_n */ +#define SCU_SFSP4_0 SCU_SFS(PIN_GROUP4, PIN0) +#define SCU_SFSP4_1 SCU_SFS(PIN_GROUP4, PIN1) +#define SCU_SFSP4_2 SCU_SFS(PIN_GROUP4, PIN2) +#define SCU_SFSP4_3 SCU_SFS(PIN_GROUP4, PIN3) +#define SCU_SFSP4_4 SCU_SFS(PIN_GROUP4, PIN4) +#define SCU_SFSP4_5 SCU_SFS(PIN_GROUP4, PIN5) +#define SCU_SFSP4_6 SCU_SFS(PIN_GROUP4, PIN6) +#define SCU_SFSP4_7 SCU_SFS(PIN_GROUP4, PIN7) +#define SCU_SFSP4_8 SCU_SFS(PIN_GROUP4, PIN8) +#define SCU_SFSP4_9 SCU_SFS(PIN_GROUP4, PIN9) +#define SCU_SFSP4_10 SCU_SFS(PIN_GROUP4, PIN10) + +/* Pins P5_n */ +#define SCU_SFSP5_0 SCU_SFS(PIN_GROUP5, PIN0) +#define SCU_SFSP5_1 SCU_SFS(PIN_GROUP5, PIN1) +#define SCU_SFSP5_2 SCU_SFS(PIN_GROUP5, PIN2) +#define SCU_SFSP5_3 SCU_SFS(PIN_GROUP5, PIN3) +#define SCU_SFSP5_4 SCU_SFS(PIN_GROUP5, PIN4) +#define SCU_SFSP5_5 SCU_SFS(PIN_GROUP5, PIN5) +#define SCU_SFSP5_6 SCU_SFS(PIN_GROUP5, PIN6) +#define SCU_SFSP5_7 SCU_SFS(PIN_GROUP5, PIN7) + +/* Pins P6_n */ +#define SCU_SFSP6_0 SCU_SFS(PIN_GROUP6, PIN0) +#define SCU_SFSP6_1 SCU_SFS(PIN_GROUP6, PIN1) +#define SCU_SFSP6_2 SCU_SFS(PIN_GROUP6, PIN2) +#define SCU_SFSP6_3 SCU_SFS(PIN_GROUP6, PIN3) +#define SCU_SFSP6_4 SCU_SFS(PIN_GROUP6, PIN4) +#define SCU_SFSP6_5 SCU_SFS(PIN_GROUP6, PIN5) +#define SCU_SFSP6_6 SCU_SFS(PIN_GROUP6, PIN6) +#define SCU_SFSP6_7 SCU_SFS(PIN_GROUP6, PIN7) +#define SCU_SFSP6_8 SCU_SFS(PIN_GROUP6, PIN8) +#define SCU_SFSP6_9 SCU_SFS(PIN_GROUP6, PIN9) +#define SCU_SFSP6_10 SCU_SFS(PIN_GROUP6, PIN10) +#define SCU_SFSP6_11 SCU_SFS(PIN_GROUP6, PIN11) +#define SCU_SFSP6_12 SCU_SFS(PIN_GROUP6, PIN12) + +/* Pins P7_n */ +#define SCU_SFSP7_0 SCU_SFS(PIN_GROUP7, PIN0) +#define SCU_SFSP7_1 SCU_SFS(PIN_GROUP7, PIN1) +#define SCU_SFSP7_2 SCU_SFS(PIN_GROUP7, PIN2) +#define SCU_SFSP7_3 SCU_SFS(PIN_GROUP7, PIN3) +#define SCU_SFSP7_4 SCU_SFS(PIN_GROUP7, PIN4) +#define SCU_SFSP7_5 SCU_SFS(PIN_GROUP7, PIN5) +#define SCU_SFSP7_6 SCU_SFS(PIN_GROUP7, PIN6) +#define SCU_SFSP7_7 SCU_SFS(PIN_GROUP7, PIN7) + +/* Pins P8_n */ +#define SCU_SFSP8_0 SCU_SFS(PIN_GROUP8, PIN0) +#define SCU_SFSP8_1 SCU_SFS(PIN_GROUP8, PIN1) +#define SCU_SFSP8_2 SCU_SFS(PIN_GROUP8, PIN2) +#define SCU_SFSP8_3 SCU_SFS(PIN_GROUP8, PIN3) +#define SCU_SFSP8_4 SCU_SFS(PIN_GROUP8, PIN4) +#define SCU_SFSP8_5 SCU_SFS(PIN_GROUP8, PIN5) +#define SCU_SFSP8_6 SCU_SFS(PIN_GROUP8, PIN6) +#define SCU_SFSP8_7 SCU_SFS(PIN_GROUP8, PIN7) +#define SCU_SFSP8_8 SCU_SFS(PIN_GROUP8, PIN8) + +/* Pins P9_n */ +#define SCU_SFSP9_0 SCU_SFS(PIN_GROUP9, PIN0) +#define SCU_SFSP9_1 SCU_SFS(PIN_GROUP9, PIN1) +#define SCU_SFSP9_2 SCU_SFS(PIN_GROUP9, PIN2) +#define SCU_SFSP9_3 SCU_SFS(PIN_GROUP9, PIN3) +#define SCU_SFSP9_4 SCU_SFS(PIN_GROUP9, PIN4) +#define SCU_SFSP9_5 SCU_SFS(PIN_GROUP9, PIN5) +#define SCU_SFSP9_6 SCU_SFS(PIN_GROUP9, PIN6) + +/* Pins PA_n */ +#define SCU_SFSPA_0 SCU_SFS(PIN_GROUPA, PIN0) +#define SCU_SFSPA_1 SCU_SFS(PIN_GROUPA, PIN1) +#define SCU_SFSPA_2 SCU_SFS(PIN_GROUPA, PIN2) +#define SCU_SFSPA_3 SCU_SFS(PIN_GROUPA, PIN3) +#define SCU_SFSPA_4 SCU_SFS(PIN_GROUPA, PIN4) + +/* Pins PB_n */ +#define SCU_SFSPB_0 SCU_SFS(PIN_GROUPB, PIN0) +#define SCU_SFSPB_1 SCU_SFS(PIN_GROUPB, PIN1) +#define SCU_SFSPB_2 SCU_SFS(PIN_GROUPB, PIN2) +#define SCU_SFSPB_3 SCU_SFS(PIN_GROUPB, PIN3) +#define SCU_SFSPB_4 SCU_SFS(PIN_GROUPB, PIN4) +#define SCU_SFSPB_5 SCU_SFS(PIN_GROUPB, PIN5) +#define SCU_SFSPB_6 SCU_SFS(PIN_GROUPB, PIN6) + +/* Pins PC_n */ +#define SCU_SFSPC_0 SCU_SFS(PIN_GROUPC, PIN0) +#define SCU_SFSPC_1 SCU_SFS(PIN_GROUPC, PIN1) +#define SCU_SFSPC_2 SCU_SFS(PIN_GROUPC, PIN2) +#define SCU_SFSPC_3 SCU_SFS(PIN_GROUPC, PIN3) +#define SCU_SFSPC_4 SCU_SFS(PIN_GROUPC, PIN4) +#define SCU_SFSPC_5 SCU_SFS(PIN_GROUPC, PIN5) +#define SCU_SFSPC_6 SCU_SFS(PIN_GROUPC, PIN6) +#define SCU_SFSPC_7 SCU_SFS(PIN_GROUPC, PIN7) +#define SCU_SFSPC_8 SCU_SFS(PIN_GROUPC, PIN8) +#define SCU_SFSPC_9 SCU_SFS(PIN_GROUPC, PIN9) +#define SCU_SFSPC_10 SCU_SFS(PIN_GROUPC, PIN10) +#define SCU_SFSPC_11 SCU_SFS(PIN_GROUPC, PIN11) +#define SCU_SFSPC_12 SCU_SFS(PIN_GROUPC, PIN12) +#define SCU_SFSPC_13 SCU_SFS(PIN_GROUPC, PIN13) +#define SCU_SFSPC_14 SCU_SFS(PIN_GROUPC, PIN14) + +/* Pins PD_n */ +#define SCU_SFSPD_0 SCU_SFS(PIN_GROUPD, PIN0) +#define SCU_SFSPD_1 SCU_SFS(PIN_GROUPD, PIN1) +#define SCU_SFSPD_2 SCU_SFS(PIN_GROUPD, PIN2) +#define SCU_SFSPD_3 SCU_SFS(PIN_GROUPD, PIN3) +#define SCU_SFSPD_4 SCU_SFS(PIN_GROUPD, PIN4) +#define SCU_SFSPD_5 SCU_SFS(PIN_GROUPD, PIN5) +#define SCU_SFSPD_6 SCU_SFS(PIN_GROUPD, PIN6) +#define SCU_SFSPD_7 SCU_SFS(PIN_GROUPD, PIN7) +#define SCU_SFSPD_8 SCU_SFS(PIN_GROUPD, PIN8) +#define SCU_SFSPD_9 SCU_SFS(PIN_GROUPD, PIN9) +#define SCU_SFSPD_10 SCU_SFS(PIN_GROUPD, PIN10) +#define SCU_SFSPD_11 SCU_SFS(PIN_GROUPD, PIN11) +#define SCU_SFSPD_12 SCU_SFS(PIN_GROUPD, PIN12) +#define SCU_SFSPD_13 SCU_SFS(PIN_GROUPD, PIN13) +#define SCU_SFSPD_14 SCU_SFS(PIN_GROUPD, PIN14) +#define SCU_SFSPD_15 SCU_SFS(PIN_GROUPD, PIN15) +#define SCU_SFSPD_16 SCU_SFS(PIN_GROUPD, PIN16) + +/* Pins PE_n */ +#define SCU_SFSPE_0 SCU_SFS(PIN_GROUPE, PIN0) +#define SCU_SFSPE_1 SCU_SFS(PIN_GROUPE, PIN1) +#define SCU_SFSPE_2 SCU_SFS(PIN_GROUPE, PIN2) +#define SCU_SFSPE_3 SCU_SFS(PIN_GROUPE, PIN3) +#define SCU_SFSPE_4 SCU_SFS(PIN_GROUPE, PIN4) +#define SCU_SFSPE_5 SCU_SFS(PIN_GROUPE, PIN5) +#define SCU_SFSPE_6 SCU_SFS(PIN_GROUPE, PIN6) +#define SCU_SFSPE_7 SCU_SFS(PIN_GROUPE, PIN7) +#define SCU_SFSPE_8 SCU_SFS(PIN_GROUPE, PIN8) +#define SCU_SFSPE_9 SCU_SFS(PIN_GROUPE, PIN9) +#define SCU_SFSPE_10 SCU_SFS(PIN_GROUPE, PIN10) +#define SCU_SFSPE_11 SCU_SFS(PIN_GROUPE, PIN11) +#define SCU_SFSPE_12 SCU_SFS(PIN_GROUPE, PIN12) +#define SCU_SFSPE_13 SCU_SFS(PIN_GROUPE, PIN13) +#define SCU_SFSPE_14 SCU_SFS(PIN_GROUPE, PIN14) +#define SCU_SFSPE_15 SCU_SFS(PIN_GROUPE, PIN15) + +/* Pins PF_n */ +#define SCU_SFSPF_0 SCU_SFS(PIN_GROUPF, PIN0) +#define SCU_SFSPF_1 SCU_SFS(PIN_GROUPF, PIN1) +#define SCU_SFSPF_2 SCU_SFS(PIN_GROUPF, PIN2) +#define SCU_SFSPF_3 SCU_SFS(PIN_GROUPF, PIN3) +#define SCU_SFSPF_4 SCU_SFS(PIN_GROUPF, PIN4) +#define SCU_SFSPF_5 SCU_SFS(PIN_GROUPF, PIN5) +#define SCU_SFSPF_6 SCU_SFS(PIN_GROUPF, PIN6) +#define SCU_SFSPF_7 SCU_SFS(PIN_GROUPF, PIN7) +#define SCU_SFSPF_8 SCU_SFS(PIN_GROUPF, PIN8) +#define SCU_SFSPF_9 SCU_SFS(PIN_GROUPF, PIN9) +#define SCU_SFSPF_10 SCU_SFS(PIN_GROUPF, PIN10) +#define SCU_SFSPF_11 SCU_SFS(PIN_GROUPF, PIN11) + +/* CLKn pins */ +#define SCU_SFSCLK0 MMIO32(SCU_BASE + 0xC00) +#define SCU_SFSCLK1 MMIO32(SCU_BASE + 0xC04) +#define SCU_SFSCLK2 MMIO32(SCU_BASE + 0xC08) +#define SCU_SFSCLK3 MMIO32(SCU_BASE + 0xC0C) + +/* USB1 USB1_DP/USB1_DM pins and I2C-bus open-drain pins */ +#define SCU_SFSUSB MMIO32(SCU_BASE + 0xC80) +#define SCU_SFSI2C0 MMIO32(SCU_BASE + 0xC84) + +/* ADC pin select registers */ + +/* ADC0 function select register */ +#define SCU_ENAIO0 MMIO32(SCU_BASE + 0xC88) + +/* ADC1 function select register */ +#define SCU_ENAIO1 MMIO32(SCU_BASE + 0xC8C) + +/* Analog function select register */ +#define SCU_ENAIO2 MMIO32(SCU_BASE + 0xC90) + +/* EMC clock delay register */ +#define SCU_EMCDELAYCLK MMIO32(SCU_BASE + 0xD00) + +/* Pin interrupt select registers */ + +/* Pin interrupt select register for pin interrupts 0 to 3 */ +#define SCU_PINTSEL0 MMIO32(SCU_BASE + 0xE00) + +/* Pin interrupt select register for pin interrupts 4 to 7 */ +#define SCU_PINTSEL1 MMIO32(SCU_BASE + 0xE04) + +/**************************/ +/* SCU I2C0 Configuration */ +/**************************/ +/* +* Select input glitch filter time constant for the SCL pin. +* 0 = 50 ns glitch filter. +* 1 = 3ns glitch filter. +*/ +#define SCU_SCL_EFP (BIT0) + +/* BIT1 Reserved. Always write a 0 to this bit. */ + +/* +* Select I2C mode for the SCL pin. +* 0 = Standard/Fast mode transmit. +* 1 = Fast-mode Plus transmit. +*/ +#define SCU_SCL_EHD (BIT2) + +/* +* Enable the input receiver for the SCL pin. +* Always write a 1 to this bit when using the +* I2C0. +* 0 = Disabled. +* 1 = Enabled. +*/ +#define SCU_SCL_EZI_EN (BIT3) + +/* BIT4-6 Reserved. */ + +/* +* Enable or disable input glitch filter for the +* SCL pin. The filter time constant is +* determined by bit EFP. +* 0 = Enable input filter. +* 1 = Disable input filter. +*/ +#define SCU_SCL_ZIF_DIS (BIT7) + +/* +* Select input glitch filter time constant for the SDA pin. +* 0 = 50 ns glitch filter. +* 1 = 3ns glitch filter. +*/ +#define SCU_SDA_EFP (BIT8) + +/* BIT9 Reserved. Always write a 0 to this bit. */ + +/* +* Select I2C mode for the SDA pin. +* 0 = Standard/Fast mode transmit. +* 1 = Fast-mode Plus transmit. +*/ +#define SCU_SDA_EHD (BIT10) + +/* +* Enable the input receiver for the SDA pin. +* Always write a 1 to this bit when using the +* I2C0. +* 0 = Disabled. +* 1 = Enabled. +*/ +#define SCU_SDA_EZI_EN (BIT11) + +/* BIT 12-14 - Reserved */ + +/* +* Enable or disable input glitch filter for the +* SDA pin. The filter time constant is +* determined by bit SDA_EFP. +* 0 = Enable input filter. +* 1 = Disable input filter. +*/ +#define SCU_SDA_ZIF_DIS (BIT15) + +/* Standard mode for I2C SCL/SDA Standard/Fast mode */ +#define SCU_I2C0_NOMINAL (SCU_SCL_EZI_EN | SCU_SDA_EZI_EN) + +/* Standard mode for I2C SCL/SDA Fast-mode Plus transmit */ +#define SCU_I2C0_FAST (SCU_SCL_EFP | SCU_SCL_EHD | SCU_SCL_EZI_EN | SCU_SCL_ZIF_DIS \ + SCU_SDA_EFP | SCU_SDA_EHD | SCU_SDA_EZI_EN) + +/* +* SCU PIN Normal Drive: +* The pin configuration registers for normal-drive pins control the following pins: +* - P0_0 and P0_1 +* - P1_0 to P1_16 and P1_18 to P1_20 +* - P2_0 to P2_2 and P2_6 to P2_13 +* - P3_0 to P3_2 and P3_4 to P3_8 +* - P4_0 to P4_10 +* - P5_0 to P5_7 +* - P6_0 to P6_12 +* - P7_0 to P7_7 +* - P8_3 to P8_8 +* - P9_0 to P9_6 +* - PA_0 and PA_4 +* - PB_0 to PB_6 +* - PC_0 to PC_14 +* - PE_0 to PE_15 +* - PF_0 to PF_11 +* +* Pin configuration registers for High-Drive pins. +* The pin configuration registers for high-drive pins control the following pins: +* - P1_17 +* - P2_3 to P2_5 +* - P8_0 to P8_2 +* - PA_1 to PA_3 +* +* Pin configuration registers for High-Speed pins. +* This register controls the following pins: +* - P3_3 and pins CLK0 to CLK3. +*/ +typedef enum { + /* Group Port 0 */ + P0_0 = (PIN_GROUP0+PIN0), + P0_1 = (PIN_GROUP0+PIN1), + + /* Group Port 1 */ + P1_0 = (PIN_GROUP1+PIN0), + P1_1 = (PIN_GROUP1+PIN1), + P1_2 = (PIN_GROUP1+PIN2), + P1_3 = (PIN_GROUP1+PIN3), + P1_4 = (PIN_GROUP1+PIN4), + P1_5 = (PIN_GROUP1+PIN5), + P1_6 = (PIN_GROUP1+PIN6), + P1_7 = (PIN_GROUP1+PIN7), + P1_8 = (PIN_GROUP1+PIN8), + P1_9 = (PIN_GROUP1+PIN9), + P1_10 = (PIN_GROUP1+PIN10), + P1_11 = (PIN_GROUP1+PIN11), + P1_12 = (PIN_GROUP1+PIN12), + P1_13 = (PIN_GROUP1+PIN13), + P1_14 = (PIN_GROUP1+PIN14), + P1_15 = (PIN_GROUP1+PIN15), + P1_16 = (PIN_GROUP1+PIN16), + + /* P1_17 is High-Drive pin */ + P1_17 = (PIN_GROUP1+PIN17), + + P1_18 = (PIN_GROUP1+PIN18), + P1_19 = (PIN_GROUP1+PIN19), + P1_20 = (PIN_GROUP1+PIN20), + + /* Group Port 2 */ + P2_0 = (PIN_GROUP2+PIN0), + P2_1 = (PIN_GROUP2+PIN1), + P2_2 = (PIN_GROUP2+PIN2), + + /* P2_3 to P2_5 are High-Drive pins */ + P2_3 = (PIN_GROUP2+PIN3), + P2_4 = (PIN_GROUP2+PIN4), + P2_5 = (PIN_GROUP2+PIN5), + + P2_6 = (PIN_GROUP2+PIN6), + P2_7 = (PIN_GROUP2+PIN7), + P2_8 = (PIN_GROUP2+PIN8), + P2_9 = (PIN_GROUP2+PIN9), + P2_10 = (PIN_GROUP2+PIN10), + P2_11 = (PIN_GROUP2+PIN11), + P2_12 = (PIN_GROUP2+PIN12), + P2_13 = (PIN_GROUP2+PIN13), + + /* Group Port 3 */ + P3_0 = (PIN_GROUP3+PIN0), + P3_1 = (PIN_GROUP3+PIN1), + P3_2 = (PIN_GROUP3+PIN2), + + /* P3_3 is High-Speed pin */ + P3_3 = (PIN_GROUP3+PIN3), + + P3_4 = (PIN_GROUP3+PIN4), + P3_5 = (PIN_GROUP3+PIN5), + P3_6 = (PIN_GROUP3+PIN6), + P3_7 = (PIN_GROUP3+PIN7), + P3_8 = (PIN_GROUP3+PIN8), + + /* Group Port 4 */ + P4_0 = (PIN_GROUP4+PIN0), + P4_1 = (PIN_GROUP4+PIN1), + P4_2 = (PIN_GROUP4+PIN2), + P4_3 = (PIN_GROUP4+PIN3), + P4_4 = (PIN_GROUP4+PIN4), + P4_5 = (PIN_GROUP4+PIN5), + P4_6 = (PIN_GROUP4+PIN6), + P4_7 = (PIN_GROUP4+PIN7), + P4_8 = (PIN_GROUP4+PIN8), + P4_9 = (PIN_GROUP4+PIN9), + P4_10 = (PIN_GROUP4+PIN10), + + /* Group Port 5 */ + P5_0 = (PIN_GROUP5+PIN0), + P5_1 = (PIN_GROUP5+PIN1), + P5_2 = (PIN_GROUP5+PIN2), + P5_3 = (PIN_GROUP5+PIN3), + P5_4 = (PIN_GROUP5+PIN4), + P5_5 = (PIN_GROUP5+PIN5), + P5_6 = (PIN_GROUP5+PIN6), + P5_7 = (PIN_GROUP5+PIN7), + + /* Group Port 6 */ + P6_0 = (PIN_GROUP6+PIN0), + P6_1 = (PIN_GROUP6+PIN1), + P6_2 = (PIN_GROUP6+PIN2), + P6_3 = (PIN_GROUP6+PIN3), + P6_4 = (PIN_GROUP6+PIN4), + P6_5 = (PIN_GROUP6+PIN5), + P6_6 = (PIN_GROUP6+PIN6), + P6_7 = (PIN_GROUP6+PIN7), + P6_8 = (PIN_GROUP6+PIN8), + P6_9 = (PIN_GROUP6+PIN9), + P6_10 = (PIN_GROUP6+PIN10), + P6_11 = (PIN_GROUP6+PIN11), + P6_12 = (PIN_GROUP6+PIN12), + + /* Group Port 7 */ + P7_0 = (PIN_GROUP7+PIN0), + P7_1 = (PIN_GROUP7+PIN1), + P7_2 = (PIN_GROUP7+PIN2), + P7_3 = (PIN_GROUP7+PIN3), + P7_4 = (PIN_GROUP7+PIN4), + P7_5 = (PIN_GROUP7+PIN5), + P7_6 = (PIN_GROUP7+PIN6), + P7_7 = (PIN_GROUP7+PIN7), + + /* Group Port 8 */ + /* P8_0 to P8_2 are High-Drive pins */ + P8_0 = (PIN_GROUP8+PIN0), + P8_1 = (PIN_GROUP8+PIN1), + P8_2 = (PIN_GROUP8+PIN2), + + P8_3 = (PIN_GROUP8+PIN3), + P8_4 = (PIN_GROUP8+PIN4), + P8_5 = (PIN_GROUP8+PIN5), + P8_6 = (PIN_GROUP8+PIN6), + P8_7 = (PIN_GROUP8+PIN7), + P8_8 = (PIN_GROUP8+PIN8), + + /* Group Port 9 */ + P9_0 = (PIN_GROUP9+PIN0), + P9_1 = (PIN_GROUP9+PIN1), + P9_2 = (PIN_GROUP9+PIN2), + P9_3 = (PIN_GROUP9+PIN3), + P9_4 = (PIN_GROUP9+PIN4), + P9_5 = (PIN_GROUP9+PIN5), + P9_6 = (PIN_GROUP9+PIN6), + + /* Group Port A */ + PA_0 = (PIN_GROUPA+PIN0), + /* PA_1 to PA_3 are Normal & High-Drive Pins */ + PA_1 = (PIN_GROUPA+PIN1), + PA_2 = (PIN_GROUPA+PIN2), + PA_3 = (PIN_GROUPA+PIN3), + PA_4 = (PIN_GROUPA+PIN4), + + /* Group Port B */ + PB_0 = (PIN_GROUPB+PIN0), + PB_1 = (PIN_GROUPB+PIN1), + PB_2 = (PIN_GROUPB+PIN2), + PB_3 = (PIN_GROUPB+PIN3), + PB_4 = (PIN_GROUPB+PIN4), + PB_5 = (PIN_GROUPB+PIN5), + PB_6 = (PIN_GROUPB+PIN6), + + /* Group Port C */ + PC_0 = (PIN_GROUPC+PIN0), + PC_1 = (PIN_GROUPC+PIN1), + PC_2 = (PIN_GROUPC+PIN2), + PC_3 = (PIN_GROUPC+PIN3), + PC_4 = (PIN_GROUPC+PIN4), + PC_5 = (PIN_GROUPC+PIN5), + PC_6 = (PIN_GROUPC+PIN6), + PC_7 = (PIN_GROUPC+PIN7), + PC_8 = (PIN_GROUPC+PIN8), + PC_9 = (PIN_GROUPC+PIN9), + PC_10 = (PIN_GROUPC+PIN10), + PC_11 = (PIN_GROUPC+PIN11), + PC_12 = (PIN_GROUPC+PIN12), + PC_13 = (PIN_GROUPC+PIN13), + PC_14 = (PIN_GROUPC+PIN14), + + /* Group Port D (seems not configurable through SCU, not defined in UM10503.pdf Rev.1, keep it here) */ + PD_0 = (PIN_GROUPD+PIN0), + PD_1 = (PIN_GROUPD+PIN1), + PD_2 = (PIN_GROUPD+PIN2), + PD_3 = (PIN_GROUPD+PIN3), + PD_4 = (PIN_GROUPD+PIN4), + PD_5 = (PIN_GROUPD+PIN5), + PD_6 = (PIN_GROUPD+PIN6), + PD_7 = (PIN_GROUPD+PIN7), + PD_8 = (PIN_GROUPD+PIN8), + PD_9 = (PIN_GROUPD+PIN9), + PD_10 = (PIN_GROUPD+PIN10), + PD_11 = (PIN_GROUPD+PIN11), + PD_12 = (PIN_GROUPD+PIN12), + PD_13 = (PIN_GROUPD+PIN13), + PD_14 = (PIN_GROUPD+PIN14), + PD_15 = (PIN_GROUPD+PIN15), + PD_16 = (PIN_GROUPD+PIN16), + + /* Group Port E */ + PE_0 = (PIN_GROUPE+PIN0), + PE_1 = (PIN_GROUPE+PIN1), + PE_2 = (PIN_GROUPE+PIN2), + PE_3 = (PIN_GROUPE+PIN3), + PE_4 = (PIN_GROUPE+PIN4), + PE_5 = (PIN_GROUPE+PIN5), + PE_6 = (PIN_GROUPE+PIN6), + PE_7 = (PIN_GROUPE+PIN7), + PE_8 = (PIN_GROUPE+PIN8), + PE_9 = (PIN_GROUPE+PIN9), + PE_10 = (PIN_GROUPE+PIN10), + PE_11 = (PIN_GROUPE+PIN11), + PE_12 = (PIN_GROUPE+PIN12), + PE_13 = (PIN_GROUPE+PIN13), + PE_14 = (PIN_GROUPE+PIN14), + PE_15 = (PIN_GROUPE+PIN15), + + /* Group Port F */ + PF_0 = (PIN_GROUPF+PIN0), + PF_1 = (PIN_GROUPF+PIN1), + PF_2 = (PIN_GROUPF+PIN2), + PF_3 = (PIN_GROUPF+PIN3), + PF_4 = (PIN_GROUPF+PIN4), + PF_5 = (PIN_GROUPF+PIN5), + PF_6 = (PIN_GROUPF+PIN6), + PF_7 = (PIN_GROUPF+PIN7), + PF_8 = (PIN_GROUPF+PIN8), + PF_9 = (PIN_GROUPF+PIN9), + PF_10 = (PIN_GROUPF+PIN10), + PF_11 = (PIN_GROUPF+PIN11), + + /* Group Clock 0 to 3 High-Speed pins */ + CLK0 = (SCU_BASE + 0xC00), + CLK1 = (SCU_BASE + 0xC04), + CLK2 = (SCU_BASE + 0xC08), + CLK3 = (SCU_BASE + 0xC0C) + +} scu_grp_pin_t; + +/* +* Pin Configuration to be used for scu_pinmux() parameter scu_conf +* For normal-drive pins, high-drive pins, high-speed pins +*/ +/* +* Function BIT0 to 2. +* Common to normal-drive pins, high-drive pins, high-speed pins. +*/ +#define SCU_CONF_FUNCTION0 (0x0) +#define SCU_CONF_FUNCTION1 (0x1) +#define SCU_CONF_FUNCTION2 (0x2) +#define SCU_CONF_FUNCTION3 (0x3) +#define SCU_CONF_FUNCTION4 (0x4) +#define SCU_CONF_FUNCTION5 (0x5) +#define SCU_CONF_FUNCTION6 (0x6) +#define SCU_CONF_FUNCTION7 (0x7) + +/* +* Enable pull-down resistor at pad +* By default=0 Disable pull-down. +* Available to normal-drive pins, high-drive pins, high-speed pins +*/ +#define SCU_CONF_EPD_EN_PULLDOWN (BIT3) + +/* +* Disable pull-up resistor at pad. +* By default=0 the pull-up resistor is enabled at reset. +* Available to normal-drive pins, high-drive pins, high-speed pins +*/ +#define SCU_CONF_EPUN_DIS_PULLUP (BIT4) + +/* +* Select Slew Rate. +* By Default=0 Slow. +* Available to normal-drive pins and high-speed pins, reserved for high-drive pins. +*/ +#define SCU_CONF_EHS_FAST (BIT5) + +/* +* Input buffer enable. +* By Default=0 Disable Input Buffer. +* The input buffer is disabled by default at reset and must be enabled. +* for receiving(in normal/highspeed-drive) or to transfer data from the I/O buffer to the pad(in high-drive pins). +* Available to normal-drive pins, high-drive pins, high-speed pins. +*/ +#define SCU_CONF_EZI_EN_IN_BUFFER (BIT6) + +/* +* Input glitch filter. Disable the input glitch filter for clocking signals higher than 30 MHz. +* Available to normal-drive pins, high-drive pins, high-speed pins. +*/ +#define SCU_CONF_ZIF_DIS_IN_GLITCH_FILT (BIT7) + +/* +* Select drive strength. (default=0 Normal-drive: 4 mA drive strength) (BIT8/9). +* Available to high-drive pins, reserved for others. +*/ +#define SCU_CONF_EHD_NORMAL_DRIVE_8MILLIA (0x100) +#define SCU_CONF_EHD_NORMAL_DRIVE_14MILLIA (0x200) +#define SCU_CONF_EHD_NORMAL_DRIVE_20MILLIA (0x300) + +/* BIT10 to 31 are Reserved */ + +/* Configuration for different I/O pins types */ +#define SCU_EMC_IO (SCU_CONF_EPD_EN_PULLDOWN | SCU_CONF_EHS_FAST | SCU_CONF_EZI_EN_IN_BUFFER | SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_LCD (SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_EZI_EN_IN_BUFFER | SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_CLK_IN (SCU_CONF_EPD_EN_PULLDOWN | SCU_CONF_EHS_FAST | SCU_CONF_EZI_EN_IN_BUFFER | SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_CLK_OUT (SCU_CONF_EPD_EN_PULLDOWN | SCU_CONF_EHS_FAST | SCU_CONF_EZI_EN_IN_BUFFER | SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_GPIO_PUP (SCU_CONF_EZI_EN_IN_BUFFER) +#define SCU_GPIO_PDN (SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EPD_EN_PULLDOWN | SCU_CONF_EZI_EN_IN_BUFFER) +#define SCU_GPIO_NOPULL (SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EZI_EN_IN_BUFFER) +#define SCU_GPIO_FAST (SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_EZI_EN_IN_BUFFER | SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_UART_RX_TX (SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EPD_EN_PULLDOWN | SCU_CONF_EZI_EN_IN_BUFFER) +#define SCU_SSP_IO (SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_EZI_EN_IN_BUFFER | SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) + +BEGIN_DECLS + +void scu_pinmux(scu_grp_pin_t group_pin, u32 scu_conf); + +END_DECLS + +#endif diff --git a/include/libopencm3/lpc43xx/sdio.h b/include/libopencm3/lpc43xx/sdio.h new file mode 100644 index 00000000..3310aa95 --- /dev/null +++ b/include/libopencm3/lpc43xx/sdio.h @@ -0,0 +1,133 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_SDIO_H +#define LPC43XX_SDIO_H + +#include +#include + +/* --- SDIO registers ----------------------------------------------------- */ + +/* Control Register */ +#define SDIO_CTRL MMIO32(SDIO_BASE + 0x000) + +/* Power Enable Register */ +#define SDIO_PWREN MMIO32(SDIO_BASE + 0x004) + +/* Clock Divider Register */ +#define SDIO_CLKDIV MMIO32(SDIO_BASE + 0x008) + +/* SD Clock Source Register */ +#define SDIO_CLKSRC MMIO32(SDIO_BASE + 0x00C) + +/* Clock Enable Register */ +#define SDIO_CLKENA MMIO32(SDIO_BASE + 0x010) + +/* Time-out Register */ +#define SDIO_TMOUT MMIO32(SDIO_BASE + 0x014) + +/* Card Type Register */ +#define SDIO_CTYPE MMIO32(SDIO_BASE + 0x018) + +/* Block Size Register */ +#define SDIO_BLKSIZ MMIO32(SDIO_BASE + 0x01C) + +/* Byte Count Register */ +#define SDIO_BYTCNT MMIO32(SDIO_BASE + 0x020) + +/* Interrupt Mask Register */ +#define SDIO_INTMASK MMIO32(SDIO_BASE + 0x024) + +/* Command Argument Register */ +#define SDIO_CMDARG MMIO32(SDIO_BASE + 0x028) + +/* Command Register */ +#define SDIO_CMD MMIO32(SDIO_BASE + 0x02C) + +/* Response Register 0 */ +#define SDIO_RESP0 MMIO32(SDIO_BASE + 0x030) + +/* Response Register 1 */ +#define SDIO_RESP1 MMIO32(SDIO_BASE + 0x034) + +/* Response Register 2 */ +#define SDIO_RESP2 MMIO32(SDIO_BASE + 0x038) + +/* Response Register 3 */ +#define SDIO_RESP3 MMIO32(SDIO_BASE + 0x03C) + +/* Masked Interrupt Status Register */ +#define SDIO_MINTSTS MMIO32(SDIO_BASE + 0x040) + +/* Raw Interrupt Status Register */ +#define SDIO_RINTSTS MMIO32(SDIO_BASE + 0x044) + +/* Status Register */ +#define SDIO_STATUS MMIO32(SDIO_BASE + 0x048) + +/* FIFO Threshold Watermark Register */ +#define SDIO_FIFOTH MMIO32(SDIO_BASE + 0x04C) + +/* Card Detect Register */ +#define SDIO_CDETECT MMIO32(SDIO_BASE + 0x050) + +/* Write Protect Register */ +#define SDIO_WRTPRT MMIO32(SDIO_BASE + 0x054) + +/* Transferred CIU Card Byte Count Register */ +#define SDIO_TCBCNT MMIO32(SDIO_BASE + 0x05C) + +/* Transferred Host to BIU-FIFO Byte Count Register */ +#define SDIO_TBBCNT MMIO32(SDIO_BASE + 0x060) + +/* Debounce Count Register */ +#define SDIO_DEBNCE MMIO32(SDIO_BASE + 0x064) + +/* UHS-1 Register */ +#define SDIO_UHS_REG MMIO32(SDIO_BASE + 0x074) + +/* Hardware Reset */ +#define SDIO_RST_N MMIO32(SDIO_BASE + 0x078) + +/* Bus Mode Register */ +#define SDIO_BMOD MMIO32(SDIO_BASE + 0x080) + +/* Poll Demand Register */ +#define SDIO_PLDMND MMIO32(SDIO_BASE + 0x084) + +/* Descriptor List Base Address Register */ +#define SDIO_DBADDR MMIO32(SDIO_BASE + 0x088) + +/* Internal DMAC Status Register */ +#define SDIO_IDSTS MMIO32(SDIO_BASE + 0x08C) + +/* Internal DMAC Interrupt Enable Register */ +#define SDIO_IDINTEN MMIO32(SDIO_BASE + 0x090) + +/* Current Host Descriptor Address Register */ +#define SDIO_DSCADDR MMIO32(SDIO_BASE + 0x094) + +/* Current Buffer Descriptor Address Register */ +#define SDIO_BUFADDR MMIO32(SDIO_BASE + 0x098) + +/* Data FIFO read/write */ +#define SDIO_DATA MMIO32(SDIO_BASE + 0x100) + +#endif diff --git a/include/libopencm3/lpc43xx/sgpio.h b/include/libopencm3/lpc43xx/sgpio.h new file mode 100644 index 00000000..226551ee --- /dev/null +++ b/include/libopencm3/lpc43xx/sgpio.h @@ -0,0 +1,298 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Jared Boone + * + * 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 . + */ + +#ifndef LPC43XX_SGPIO_H +#define LPC43XX_SGPIO_H + +#include +#include + +/* --- SGPIO registers ----------------------------------------------------- */ + +/* Pin multiplexer configuration registers (OUT_MUX_CFG0 to 15) */ +#define SGPIO_OUT_MUX_CFG(pin) MMIO32(SGPIO_PORT_BASE + (pin * 0x04)) +#define SGPIO_OUT_MUX_CFG0 MMIO32(SGPIO_PORT_BASE + 0x00) +#define SGPIO_OUT_MUX_CFG1 MMIO32(SGPIO_PORT_BASE + 0x04) +#define SGPIO_OUT_MUX_CFG2 MMIO32(SGPIO_PORT_BASE + 0x08) +#define SGPIO_OUT_MUX_CFG3 MMIO32(SGPIO_PORT_BASE + 0x0C) +#define SGPIO_OUT_MUX_CFG4 MMIO32(SGPIO_PORT_BASE + 0x10) +#define SGPIO_OUT_MUX_CFG5 MMIO32(SGPIO_PORT_BASE + 0x14) +#define SGPIO_OUT_MUX_CFG6 MMIO32(SGPIO_PORT_BASE + 0x18) +#define SGPIO_OUT_MUX_CFG7 MMIO32(SGPIO_PORT_BASE + 0x1C) +#define SGPIO_OUT_MUX_CFG8 MMIO32(SGPIO_PORT_BASE + 0x20) +#define SGPIO_OUT_MUX_CFG9 MMIO32(SGPIO_PORT_BASE + 0x24) +#define SGPIO_OUT_MUX_CFG10 MMIO32(SGPIO_PORT_BASE + 0x28) +#define SGPIO_OUT_MUX_CFG11 MMIO32(SGPIO_PORT_BASE + 0x2C) +#define SGPIO_OUT_MUX_CFG12 MMIO32(SGPIO_PORT_BASE + 0x30) +#define SGPIO_OUT_MUX_CFG13 MMIO32(SGPIO_PORT_BASE + 0x34) +#define SGPIO_OUT_MUX_CFG14 MMIO32(SGPIO_PORT_BASE + 0x38) +#define SGPIO_OUT_MUX_CFG15 MMIO32(SGPIO_PORT_BASE + 0x3C) + +/* SGPIO multiplexer configuration registers (SGPIO_MUX_CFG0 to 15) */ +#define SGPIO_MUX_CFG(slice) MMIO32(SGPIO_PORT_BASE + 0x40 + (slice * 0x04)) +#define SGPIO_MUX_CFG0 MMIO32(SGPIO_PORT_BASE + 0x40) +#define SGPIO_MUX_CFG1 MMIO32(SGPIO_PORT_BASE + 0x44) +#define SGPIO_MUX_CFG2 MMIO32(SGPIO_PORT_BASE + 0x48) +#define SGPIO_MUX_CFG3 MMIO32(SGPIO_PORT_BASE + 0x4C) +#define SGPIO_MUX_CFG4 MMIO32(SGPIO_PORT_BASE + 0x50) +#define SGPIO_MUX_CFG5 MMIO32(SGPIO_PORT_BASE + 0x54) +#define SGPIO_MUX_CFG6 MMIO32(SGPIO_PORT_BASE + 0x58) +#define SGPIO_MUX_CFG7 MMIO32(SGPIO_PORT_BASE + 0x5C) +#define SGPIO_MUX_CFG8 MMIO32(SGPIO_PORT_BASE + 0x60) +#define SGPIO_MUX_CFG9 MMIO32(SGPIO_PORT_BASE + 0x64) +#define SGPIO_MUX_CFG10 MMIO32(SGPIO_PORT_BASE + 0x68) +#define SGPIO_MUX_CFG11 MMIO32(SGPIO_PORT_BASE + 0x6C) +#define SGPIO_MUX_CFG12 MMIO32(SGPIO_PORT_BASE + 0x70) +#define SGPIO_MUX_CFG13 MMIO32(SGPIO_PORT_BASE + 0x74) +#define SGPIO_MUX_CFG14 MMIO32(SGPIO_PORT_BASE + 0x78) +#define SGPIO_MUX_CFG15 MMIO32(SGPIO_PORT_BASE + 0x7C) + +/* Slice multiplexer configuration registers (SLICE_MUX_CFG0 to 15) */ +#define SGPIO_SLICE_MUX_CFG(slice) MMIO32(SGPIO_PORT_BASE + 0x80 + (slice * 0x04)) +#define SGPIO_SLICE_MUX_CFG0 MMIO32(SGPIO_PORT_BASE + 0x80) +#define SGPIO_SLICE_MUX_CFG1 MMIO32(SGPIO_PORT_BASE + 0x84) +#define SGPIO_SLICE_MUX_CFG2 MMIO32(SGPIO_PORT_BASE + 0x88) +#define SGPIO_SLICE_MUX_CFG3 MMIO32(SGPIO_PORT_BASE + 0x8C) +#define SGPIO_SLICE_MUX_CFG4 MMIO32(SGPIO_PORT_BASE + 0x90) +#define SGPIO_SLICE_MUX_CFG5 MMIO32(SGPIO_PORT_BASE + 0x94) +#define SGPIO_SLICE_MUX_CFG6 MMIO32(SGPIO_PORT_BASE + 0x98) +#define SGPIO_SLICE_MUX_CFG7 MMIO32(SGPIO_PORT_BASE + 0x9C) +#define SGPIO_SLICE_MUX_CFG8 MMIO32(SGPIO_PORT_BASE + 0xA0) +#define SGPIO_SLICE_MUX_CFG9 MMIO32(SGPIO_PORT_BASE + 0xA4) +#define SGPIO_SLICE_MUX_CFG10 MMIO32(SGPIO_PORT_BASE + 0xA8) +#define SGPIO_SLICE_MUX_CFG11 MMIO32(SGPIO_PORT_BASE + 0xAC) +#define SGPIO_SLICE_MUX_CFG12 MMIO32(SGPIO_PORT_BASE + 0xB0) +#define SGPIO_SLICE_MUX_CFG13 MMIO32(SGPIO_PORT_BASE + 0xB4) +#define SGPIO_SLICE_MUX_CFG14 MMIO32(SGPIO_PORT_BASE + 0xB8) +#define SGPIO_SLICE_MUX_CFG15 MMIO32(SGPIO_PORT_BASE + 0xBC) + +/* Slice data registers (REG0 to 15) */ +#define SGPIO_REG(slice) MMIO32(SGPIO_PORT_BASE + 0xC0 + (slice * 0x04)) +#define SGPIO_REG0 MMIO32(SGPIO_PORT_BASE + 0xC0) +#define SGPIO_REG1 MMIO32(SGPIO_PORT_BASE + 0xC4) +#define SGPIO_REG2 MMIO32(SGPIO_PORT_BASE + 0xC8) +#define SGPIO_REG3 MMIO32(SGPIO_PORT_BASE + 0xCC) +#define SGPIO_REG4 MMIO32(SGPIO_PORT_BASE + 0xD0) +#define SGPIO_REG5 MMIO32(SGPIO_PORT_BASE + 0xD4) +#define SGPIO_REG6 MMIO32(SGPIO_PORT_BASE + 0xD8) +#define SGPIO_REG7 MMIO32(SGPIO_PORT_BASE + 0xDC) +#define SGPIO_REG8 MMIO32(SGPIO_PORT_BASE + 0xE0) +#define SGPIO_REG9 MMIO32(SGPIO_PORT_BASE + 0xE4) +#define SGPIO_REG10 MMIO32(SGPIO_PORT_BASE + 0xE8) +#define SGPIO_REG11 MMIO32(SGPIO_PORT_BASE + 0xEC) +#define SGPIO_REG12 MMIO32(SGPIO_PORT_BASE + 0xF0) +#define SGPIO_REG13 MMIO32(SGPIO_PORT_BASE + 0xF4) +#define SGPIO_REG14 MMIO32(SGPIO_PORT_BASE + 0xF8) +#define SGPIO_REG15 MMIO32(SGPIO_PORT_BASE + 0xFC) + +/* Slice data shadow registers (REG_SS0 to 15) */ +#define SGPIO_REG_SS(slice) MMIO32(SGPIO_PORT_BASE + 0x100 + (slice * 0x04)) +#define SGPIO_REG_SS0 MMIO32(SGPIO_PORT_BASE + 0x100) +#define SGPIO_REG_SS1 MMIO32(SGPIO_PORT_BASE + 0x104) +#define SGPIO_REG_SS2 MMIO32(SGPIO_PORT_BASE + 0x108) +#define SGPIO_REG_SS3 MMIO32(SGPIO_PORT_BASE + 0x10C) +#define SGPIO_REG_SS4 MMIO32(SGPIO_PORT_BASE + 0x110) +#define SGPIO_REG_SS5 MMIO32(SGPIO_PORT_BASE + 0x114) +#define SGPIO_REG_SS6 MMIO32(SGPIO_PORT_BASE + 0x118) +#define SGPIO_REG_SS7 MMIO32(SGPIO_PORT_BASE + 0x11C) +#define SGPIO_REG_SS8 MMIO32(SGPIO_PORT_BASE + 0x120) +#define SGPIO_REG_SS9 MMIO32(SGPIO_PORT_BASE + 0x124) +#define SGPIO_REG_SS10 MMIO32(SGPIO_PORT_BASE + 0x128) +#define SGPIO_REG_SS11 MMIO32(SGPIO_PORT_BASE + 0x12C) +#define SGPIO_REG_SS12 MMIO32(SGPIO_PORT_BASE + 0x130) +#define SGPIO_REG_SS13 MMIO32(SGPIO_PORT_BASE + 0x134) +#define SGPIO_REG_SS14 MMIO32(SGPIO_PORT_BASE + 0x138) +#define SGPIO_REG_SS15 MMIO32(SGPIO_PORT_BASE + 0x13C) + +/* Reload registers (PRESET0 to 15) */ +#define SGPIO_PRESET(slice) MMIO32(SGPIO_PORT_BASE + 0x140 + (slice * 0x04)) +#define SGPIO_PRESET0 MMIO32(SGPIO_PORT_BASE + 0x140) +#define SGPIO_PRESET1 MMIO32(SGPIO_PORT_BASE + 0x144) +#define SGPIO_PRESET2 MMIO32(SGPIO_PORT_BASE + 0x148) +#define SGPIO_PRESET3 MMIO32(SGPIO_PORT_BASE + 0x14C) +#define SGPIO_PRESET4 MMIO32(SGPIO_PORT_BASE + 0x150) +#define SGPIO_PRESET5 MMIO32(SGPIO_PORT_BASE + 0x154) +#define SGPIO_PRESET6 MMIO32(SGPIO_PORT_BASE + 0x158) +#define SGPIO_PRESET7 MMIO32(SGPIO_PORT_BASE + 0x15C) +#define SGPIO_PRESET8 MMIO32(SGPIO_PORT_BASE + 0x160) +#define SGPIO_PRESET9 MMIO32(SGPIO_PORT_BASE + 0x164) +#define SGPIO_PRESET10 MMIO32(SGPIO_PORT_BASE + 0x168) +#define SGPIO_PRESET11 MMIO32(SGPIO_PORT_BASE + 0x16C) +#define SGPIO_PRESET12 MMIO32(SGPIO_PORT_BASE + 0x170) +#define SGPIO_PRESET13 MMIO32(SGPIO_PORT_BASE + 0x174) +#define SGPIO_PRESET14 MMIO32(SGPIO_PORT_BASE + 0x178) +#define SGPIO_PRESET15 MMIO32(SGPIO_PORT_BASE + 0x17C) + +/* Down counter registers (COUNT0 to 15) */ +#define SGPIO_COUNT(slice) MMIO32(SGPIO_PORT_BASE + 0x180 + (slice * 0x04)) +#define SGPIO_COUNT0 MMIO32(SGPIO_PORT_BASE + 0x180) +#define SGPIO_COUNT1 MMIO32(SGPIO_PORT_BASE + 0x184) +#define SGPIO_COUNT2 MMIO32(SGPIO_PORT_BASE + 0x188) +#define SGPIO_COUNT3 MMIO32(SGPIO_PORT_BASE + 0x18C) +#define SGPIO_COUNT4 MMIO32(SGPIO_PORT_BASE + 0x190) +#define SGPIO_COUNT5 MMIO32(SGPIO_PORT_BASE + 0x194) +#define SGPIO_COUNT6 MMIO32(SGPIO_PORT_BASE + 0x198) +#define SGPIO_COUNT7 MMIO32(SGPIO_PORT_BASE + 0x19C) +#define SGPIO_COUNT8 MMIO32(SGPIO_PORT_BASE + 0x1A0) +#define SGPIO_COUNT9 MMIO32(SGPIO_PORT_BASE + 0x1A4) +#define SGPIO_COUNT10 MMIO32(SGPIO_PORT_BASE + 0x1A8) +#define SGPIO_COUNT11 MMIO32(SGPIO_PORT_BASE + 0x1AC) +#define SGPIO_COUNT12 MMIO32(SGPIO_PORT_BASE + 0x1B0) +#define SGPIO_COUNT13 MMIO32(SGPIO_PORT_BASE + 0x1B4) +#define SGPIO_COUNT14 MMIO32(SGPIO_PORT_BASE + 0x1B8) +#define SGPIO_COUNT15 MMIO32(SGPIO_PORT_BASE + 0x1BC) + +/* Position registers (POS0 to 15) */ +#define SGPIO_POS(slice) MMIO32(SGPIO_PORT_BASE + 0x1C0 + (slice * 0x04)) +#define SGPIO_POS0 MMIO32(SGPIO_PORT_BASE + 0x1C0) +#define SGPIO_POS1 MMIO32(SGPIO_PORT_BASE + 0x1C4) +#define SGPIO_POS2 MMIO32(SGPIO_PORT_BASE + 0x1C8) +#define SGPIO_POS3 MMIO32(SGPIO_PORT_BASE + 0x1CC) +#define SGPIO_POS4 MMIO32(SGPIO_PORT_BASE + 0x1D0) +#define SGPIO_POS5 MMIO32(SGPIO_PORT_BASE + 0x1D4) +#define SGPIO_POS6 MMIO32(SGPIO_PORT_BASE + 0x1D8) +#define SGPIO_POS7 MMIO32(SGPIO_PORT_BASE + 0x1DC) +#define SGPIO_POS8 MMIO32(SGPIO_PORT_BASE + 0x1E0) +#define SGPIO_POS9 MMIO32(SGPIO_PORT_BASE + 0x1E4) +#define SGPIO_POS10 MMIO32(SGPIO_PORT_BASE + 0x1E8) +#define SGPIO_POS11 MMIO32(SGPIO_PORT_BASE + 0x1EC) +#define SGPIO_POS12 MMIO32(SGPIO_PORT_BASE + 0x1F0) +#define SGPIO_POS13 MMIO32(SGPIO_PORT_BASE + 0x1F4) +#define SGPIO_POS14 MMIO32(SGPIO_PORT_BASE + 0x1F8) +#define SGPIO_POS15 MMIO32(SGPIO_PORT_BASE + 0x1FC) + +/* Slice name to slice index mapping */ +#define SGPIO_SLICE_A 0 +#define SGPIO_SLICE_B 1 +#define SGPIO_SLICE_C 2 +#define SGPIO_SLICE_D 3 +#define SGPIO_SLICE_E 4 +#define SGPIO_SLICE_F 5 +#define SGPIO_SLICE_G 6 +#define SGPIO_SLICE_H 7 +#define SGPIO_SLICE_I 8 +#define SGPIO_SLICE_J 9 +#define SGPIO_SLICE_K 10 +#define SGPIO_SLICE_L 11 +#define SGPIO_SLICE_M 12 +#define SGPIO_SLICE_N 13 +#define SGPIO_SLICE_O 14 +#define SGPIO_SLICE_P 15 + +/* Mask for pattern match function of slice A */ +#define SGPIO_MASK_A MMIO32(SGPIO_PORT_BASE + 0x200) + +/* Mask for pattern match function of slice H */ +#define SGPIO_MASK_H MMIO32(SGPIO_PORT_BASE + 0x204) + +/* Mask for pattern match function of slice I */ +#define SGPIO_MASK_I MMIO32(SGPIO_PORT_BASE + 0x208) + +/* Mask for pattern match function of slice P */ +#define SGPIO_MASK_P MMIO32(SGPIO_PORT_BASE + 0x20C) + +/* GPIO input status register */ +#define SGPIO_GPIO_INREG MMIO32(SGPIO_PORT_BASE + 0x210) + +/* GPIO output control register */ +#define SGPIO_GPIO_OUTREG MMIO32(SGPIO_PORT_BASE + 0x214) + +/* GPIO OE control register */ +#define SGPIO_GPIO_OENREG MMIO32(SGPIO_PORT_BASE + 0x218) + +/* Enables the slice COUNT counter */ +#define SGPIO_CTRL_ENABLE MMIO32(SGPIO_PORT_BASE + 0x21C) + +/* Disables the slice COUNT counter */ +#define SGPIO_CTRL_DISABLE MMIO32(SGPIO_PORT_BASE + 0x220) + +/* Shift clock interrupt clear mask */ +#define SGPIO_CLR_EN_0 MMIO32(SGPIO_PORT_BASE + 0xF00) + +/* Shift clock interrupt set mask */ +#define SGPIO_SET_EN_0 MMIO32(SGPIO_PORT_BASE + 0xF04) + +/* Shift clock interrupt enable */ +#define SGPIO_ENABLE_0 MMIO32(SGPIO_PORT_BASE + 0xF08) + +/* Shift clock interrupt status */ +#define SGPIO_STATUS_0 MMIO32(SGPIO_PORT_BASE + 0xF0C) + +/* Shift clock interrupt clear status */ +#define SGPIO_CLR_STATUS_0 MMIO32(SGPIO_PORT_BASE + 0xF10) + +/* Shift clock interrupt set status */ +#define SGPIO_SET_STATUS_0 MMIO32(SGPIO_PORT_BASE + 0xF14) + +/* Exchange clock interrupt clear mask */ +#define SGPIO_CLR_EN_1 MMIO32(SGPIO_PORT_BASE + 0xF20) + +/* Exchange clock interrupt set mask */ +#define SGPIO_SET_EN_1 MMIO32(SGPIO_PORT_BASE + 0xF24) + +/* Exchange clock interrupt enable */ +#define SGPIO_ENABLE_1 MMIO32(SGPIO_PORT_BASE + 0xF28) + +/* Exchange clock interrupt status */ +#define SGPIO_STATUS_1 MMIO32(SGPIO_PORT_BASE + 0xF2C) + +/* Exchange clock interrupt clear status */ +#define SGPIO_CLR_STATUS_1 MMIO32(SGPIO_PORT_BASE + 0xF30) + +/* Exchange clock interrupt set status */ +#define SGPIO_SET_STATUS_1 MMIO32(SGPIO_PORT_BASE + 0xF34) + +/* Pattern match interrupt clear mask */ +#define SGPIO_CLR_EN_2 MMIO32(SGPIO_PORT_BASE + 0xF40) + +/* Pattern match interrupt set mask */ +#define SGPIO_SET_EN_2 MMIO32(SGPIO_PORT_BASE + 0xF44) + +/* Pattern match interrupt enable */ +#define SGPIO_ENABLE_2 MMIO32(SGPIO_PORT_BASE + 0xF48) + +/* Pattern match interrupt status */ +#define SGPIO_STATUS_2 MMIO32(SGPIO_PORT_BASE + 0xF4C) + +/* Pattern match interrupt clear status */ +#define SGPIO_CLR_STATUS_2 MMIO32(SGPIO_PORT_BASE + 0xF50) + +/* Pattern match interrupt set status */ +#define SGPIO_SET_STATUS_2 MMIO32(SGPIO_PORT_BASE + 0xF54) + +/* Input interrupt clear mask */ +#define SGPIO_CLR_EN_3 MMIO32(SGPIO_PORT_BASE + 0xF60) + +/* Input bit match interrupt set mask */ +#define SGPIO_SET_EN_3 MMIO32(SGPIO_PORT_BASE + 0xF64) + +/* Input bit match interrupt enable */ +#define SGPIO_ENABLE_3 MMIO32(SGPIO_PORT_BASE + 0xF68) + +/* Input bit match interrupt status */ +#define SGPIO_STATUS_3 MMIO32(SGPIO_PORT_BASE + 0xF6C) + +/* Input bit match interrupt clear status */ +#define SGPIO_CLR_STATUS_3 MMIO32(SGPIO_PORT_BASE + 0xF70) + +/* Input bit match interrupt set status */ +#define SGPIO_SET_STATUS_3 MMIO32(SGPIO_PORT_BASE + 0xF74) + +#endif diff --git a/include/libopencm3/lpc43xx/ssp.h b/include/libopencm3/lpc43xx/ssp.h new file mode 100644 index 00000000..b3d95db1 --- /dev/null +++ b/include/libopencm3/lpc43xx/ssp.h @@ -0,0 +1,185 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Michael Ossmann +* +* 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 . +*/ + +#ifndef LPC43XX_SSP_H +#define LPC43XX_SSP_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* SSP port base addresses (for convenience) */ +#define SSP0 SSP0_BASE +#define SSP1 SSP1_BASE + + +/* --- SSP registers ------------------------------------------------------- */ + +/* Control Register 0 */ +#define SSP_CR0(port) MMIO32(port + 0x000) +#define SSP0_CR0 SSP_CR0(SSP0) +#define SSP1_CR0 SSP_CR0(SSP1) + +/* Control Register 1 */ +#define SSP_CR1(port) MMIO32(port + 0x004) +#define SSP0_CR1 SSP_CR1(SSP0) +#define SSP1_CR1 SSP_CR1(SSP1) + +/* Data Register */ +#define SSP_DR(port) MMIO32(port + 0x008) +#define SSP0_DR SSP_DR(SSP0) +#define SSP1_DR SSP_DR(SSP1) + +/* Status Register */ +#define SSP_SR(port) MMIO32(port + 0x00C) +#define SSP0_SR SSP_SR(SSP0) +#define SSP1_SR SSP_SR(SSP1) + +#define SSP_SR_TFE BIT0 +#define SSP_SR_TNF BIT1 +#define SSP_SR_RNE BIT2 +#define SSP_SR_RFF BIT3 +#define SSP_SR_BSY BIT4 + +/* Clock Prescale Register */ +#define SSP_CPSR(port) MMIO32(port + 0x010) +#define SSP0_CPSR SSP_CPSR(SSP0) +#define SSP1_CPSR SSP_CPSR(SSP1) + +/* Interrupt Mask Set and Clear Register */ +#define SSP_IMSC(port) MMIO32(port + 0x014) +#define SSP0_IMSC SSP_IMSC(SSP0) +#define SSP1_IMSC SSP_IMSC(SSP1) + +/* Raw Interrupt Status Register */ +#define SSP_RIS(port) MMIO32(port + 0x018) +#define SSP0_RIS SSP_RIS(SSP0) +#define SSP1_RIS SSP_RIS(SSP1) + +/* Masked Interrupt Status Register */ +#define SSP_MIS(port) MMIO32(port + 0x01C) +#define SSP0_MIS SSP_MIS(SSP0) +#define SSP1_MIS SSP_MIS(SSP1) + +/* SSPICR Interrupt Clear Register */ +#define SSP_ICR(port) MMIO32(port + 0x020) +#define SSP0_ICR SSP_ICR(SSP0) +#define SSP1_ICR SSP_ICR(SSP1) + +/* SSP1 DMA control register */ +#define SSP_DMACR(port) MMIO32(port + 0x024) +#define SSP0_DMACR SSP_DMACR(SSP0) +#define SSP1_DMACR SSP_DMACR(SSP1) + +typedef enum { + SSP0_NUM = 0x0, + SSP1_NUM = 0x1 +} ssp_num_t; + +/* +* SSP Control Register 0 +*/ +/* SSP Data Size Bits 0 to 3 */ +typedef enum { + SSP_DATA_4BITS = 0x3, + SSP_DATA_5BITS = 0x4, + SSP_DATA_6BITS = 0x5, + SSP_DATA_7BITS = 0x6, + SSP_DATA_8BITS = 0x7, + SSP_DATA_9BITS = 0x8, + SSP_DATA_10BITS = 0x9, + SSP_DATA_11BITS = 0xA, + SSP_DATA_12BITS = 0xB, + SSP_DATA_13BITS = 0xC, + SSP_DATA_14BITS = 0xD, + SSP_DATA_15BITS = 0xE, + SSP_DATA_16BITS = 0xF +} ssp_datasize_t; + +/* SSP Frame Format/Type Bits 4 & 5 */ +typedef enum { + SSP_FRAME_SPI = 0x00, + SSP_FRAME_TI = BIT4, + SSP_FRAM_MICROWIRE = BIT5 +} ssp_frame_format_t; + +/* Clock Out Polarity / Clock Out Phase Bits Bits 6 & 7 */ +typedef enum { + SSP_CPOL_0_CPHA_0 = 0x0, + SSP_CPOL_1_CPHA_0 = BIT6, + SSP_CPOL_0_CPHA_1 = BIT7, + SSP_CPOL_1_CPHA_1 = (BIT6|BIT7) +} ssp_cpol_cpha_t; + +/* +* SSP Control Register 1 +*/ +/* SSP Mode Bit0 */ +typedef enum { + SSP_MODE_NORMAL = 0x0, + SSP_MODE_LOOPBACK = BIT0 +} ssp_mode_t; + +/* SSP Enable Bit1 */ +#define SSP_ENABLE BIT1 + +/* SSP Master/Slave Mode Bit2 */ +typedef enum { + SSP_MASTER = 0x0, + SSP_SLAVE = BIT2 +} ssp_master_slave_t; + +/* +* SSP Slave Output Disable Bit3 +* Slave Output Disable. This bit is relevant only in slave mode +* (MS = 1). If it is 1, this blocks this SSP controller from driving the +* transmit data line (MISO). +*/ +typedef enum { + SSP_SLAVE_OUT_ENABLE = 0x0, + SSP_SLAVE_OUT_DISABLE = BIT3 +} ssp_slave_option_t; /* This option is relevant only in slave mode */ + +BEGIN_DECLS + +void ssp_disable(ssp_num_t ssp_num); + +/* + * SSP Init + * clk_prescale shall be in range 2 to 254 (even number only). + * Clock computation: PCLK / (CPSDVSR * [SCR+1]) => CPSDVSR=clk_prescale, SCR=serial_clock_rate + */ +void ssp_init(ssp_num_t ssp_num, + ssp_datasize_t data_size, + ssp_frame_format_t frame_format, + ssp_cpol_cpha_t cpol_cpha_format, + u8 serial_clock_rate, + u8 clk_prescale, + ssp_mode_t mode, + ssp_master_slave_t master_slave, + ssp_slave_option_t slave_option); + +u16 ssp_read(ssp_num_t ssp_num); + +void ssp_write(ssp_num_t ssp_num, u16 data); + +END_DECLS + +#endif diff --git a/include/libopencm3/lpc43xx/systick.h b/include/libopencm3/lpc43xx/systick.h new file mode 100644 index 00000000..2ae52c2b --- /dev/null +++ b/include/libopencm3/lpc43xx/systick.h @@ -0,0 +1,88 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +#ifndef LIBOPENCM3_SYSTICK_H +#define LIBOPENCM3_SYSTICK_H + +#include +#include +#include + +/* --- 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/lpc43xx/timer.h b/include/libopencm3/lpc43xx/timer.h new file mode 100644 index 00000000..1064b06f --- /dev/null +++ b/include/libopencm3/lpc43xx/timer.h @@ -0,0 +1,156 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_TIMER_H +#define LPC43XX_TIMER_H + +#include +#include + +/* --- Convenience macros -------------------------------------------------- */ + +/* Timer base addresses */ +#define TIMER0 TIMER0_BASE +#define TIMER1 TIMER1_BASE +#define TIMER2 TIMER2_BASE +#define TIMER3 TIMER3_BASE + + +/* --- Timer registers ----------------------------------------------------- */ + +/* Interrupt Register */ +#define TIMER_IR(timer) MMIO32(timer + 0x000) +#define TIMER0_IR TIMER_IR(TIMER0) +#define TIMER1_IR TIMER_IR(TIMER1) +#define TIMER2_IR TIMER_IR(TIMER2) +#define TIMER3_IR TIMER_IR(TIMER3) + +/* Timer Control Register */ +#define TIMER_TCR(timer) MMIO32(timer + 0x004) +#define TIMER0_TCR TIMER_TCR(TIMER0) +#define TIMER1_TCR TIMER_TCR(TIMER1) +#define TIMER2_TCR TIMER_TCR(TIMER2) +#define TIMER3_TCR TIMER_TCR(TIMER3) + +/* Timer Counter */ +#define TIMER_TC(timer) MMIO32(timer + 0x008) +#define TIMER0_TC TIMER_TC(TIMER0) +#define TIMER1_TC TIMER_TC(TIMER1) +#define TIMER2_TC TIMER_TC(TIMER2) +#define TIMER3_TC TIMER_TC(TIMER3) + +/* Prescale Register */ +#define TIMER_PR(timer) MMIO32(timer + 0x00C) +#define TIMER0_PR TIMER_PR(TIMER0) +#define TIMER1_PR TIMER_PR(TIMER1) +#define TIMER2_PR TIMER_PR(TIMER2) +#define TIMER3_PR TIMER_PR(TIMER3) + +/* Prescale Counter */ +#define TIMER_PC(timer) MMIO32(timer + 0x010) +#define TIMER0_PC TIMER_PC(TIMER0) +#define TIMER1_PC TIMER_PC(TIMER1) +#define TIMER2_PC TIMER_PC(TIMER2) +#define TIMER3_PC TIMER_PC(TIMER3) + +/* Match Control Register */ +#define TIMER_MCR(timer) MMIO32(timer + 0x014) +#define TIMER0_MCR TIMER_MCR(TIMER0) +#define TIMER1_MCR TIMER_MCR(TIMER1) +#define TIMER2_MCR TIMER_MCR(TIMER2) +#define TIMER3_MCR TIMER_MCR(TIMER3) + +/* Match Register 0 */ +#define TIMER_MR0(timer) MMIO32(timer + 0x018) +#define TIMER0_MR0 TIMER_MR0(TIMER0) +#define TIMER1_MR0 TIMER_MR0(TIMER1) +#define TIMER2_MR0 TIMER_MR0(TIMER2) +#define TIMER3_MR0 TIMER_MR0(TIMER3) + +/* Match Register 1 */ +#define TIMER_MR1(timer) MMIO32(timer + 0x01C) +#define TIMER0_MR1 TIMER_MR1(TIMER0) +#define TIMER1_MR1 TIMER_MR1(TIMER1) +#define TIMER2_MR1 TIMER_MR1(TIMER2) +#define TIMER3_MR1 TIMER_MR1(TIMER3) + +/* Match Register 2 */ +#define TIMER_MR2(timer) MMIO32(timer + 0x020) +#define TIMER0_MR2 TIMER_MR2(TIMER0) +#define TIMER1_MR2 TIMER_MR2(TIMER1) +#define TIMER2_MR2 TIMER_MR2(TIMER2) +#define TIMER3_MR2 TIMER_MR2(TIMER3) + +/* Match Register 3 */ +#define TIMER_MR3(timer) MMIO32(timer + 0x024) +#define TIMER0_MR3 TIMER_MR3(TIMER0) +#define TIMER1_MR3 TIMER_MR3(TIMER1) +#define TIMER2_MR3 TIMER_MR3(TIMER2) +#define TIMER3_MR3 TIMER_MR3(TIMER3) + +/* Capture Control Register */ +#define TIMER_CCR(timer) MMIO32(timer + 0x028) +#define TIMER0_CCR TIMER_CCR(TIMER0) +#define TIMER1_CCR TIMER_CCR(TIMER1) +#define TIMER2_CCR TIMER_CCR(TIMER2) +#define TIMER3_CCR TIMER_CCR(TIMER3) + +/* Capture Register 0 */ +#define TIMER_CR0(timer) MMIO32(timer + 0x02C) +#define TIMER0_CR0 TIMER_CR0(TIMER0) +#define TIMER1_CR0 TIMER_CR0(TIMER1) +#define TIMER2_CR0 TIMER_CR0(TIMER2) +#define TIMER3_CR0 TIMER_CR0(TIMER3) + +/* Capture Register 1 */ +#define TIMER_CR1(timer) MMIO32(timer + 0x030) +#define TIMER0_CR1 TIMER_CR1(TIMER0) +#define TIMER1_CR1 TIMER_CR1(TIMER1) +#define TIMER2_CR1 TIMER_CR1(TIMER2) +#define TIMER3_CR1 TIMER_CR1(TIMER3) + +/* Capture Register 2 */ +#define TIMER_CR2(timer) MMIO32(timer + 0x034) +#define TIMER0_CR2 TIMER_CR2(TIMER0) +#define TIMER1_CR2 TIMER_CR2(TIMER1) +#define TIMER2_CR2 TIMER_CR2(TIMER2) +#define TIMER3_CR2 TIMER_CR2(TIMER3) + +/* Capture Register 3 */ +#define TIMER_CR3(timer) MMIO32(timer + 0x038) +#define TIMER0_CR3 TIMER_CR3(TIMER0) +#define TIMER1_CR3 TIMER_CR3(TIMER1) +#define TIMER2_CR3 TIMER_CR3(TIMER2) +#define TIMER3_CR3 TIMER_CR3(TIMER3) + +/* External Match Register */ +#define TIMER_EMR(timer) MMIO32(timer + 0x03C) +#define TIMER0_EMR TIMER_EMR(TIMER0) +#define TIMER1_EMR TIMER_EMR(TIMER1) +#define TIMER2_EMR TIMER_EMR(TIMER2) +#define TIMER3_EMR TIMER_EMR(TIMER3) + +/* Count Control Register */ +#define TIMER_CTCR(timer) MMIO32(timer + 0x070) +#define TIMER0_CTCR TIMER_CTCR(TIMER0) +#define TIMER1_CTCR TIMER_CTCR(TIMER1) +#define TIMER2_CTCR TIMER_CTCR(TIMER2) +#define TIMER3_CTCR TIMER_CTCR(TIMER3) + +#endif diff --git a/include/libopencm3/lpc43xx/usb.h b/include/libopencm3/lpc43xx/usb.h new file mode 100644 index 00000000..96982e44 --- /dev/null +++ b/include/libopencm3/lpc43xx/usb.h @@ -0,0 +1,157 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_USB_H +#define LPC43XX_USB_H + +#include +#include + +/* --- USB0 registers ------------------------------------------------------ */ + +/* Device/host capability registers */ + +/* Capability register length */ +#define USB0_CAPLENGTH MMIO32(USB0_BASE + 0x100) + +/* Host controller structural parameters */ +#define USB0_HCSPARAMS MMIO32(USB0_BASE + 0x104) + +/* Host controller capability parameters */ +#define USB0_HCCPARAMS MMIO32(USB0_BASE + 0x108) + +/* Device interface version number */ +#define USB0_DCIVERSION MMIO32(USB0_BASE + 0x120) + +/* Device controller capability parameters */ +#define USB0_DCCPARAMS MMIO32(USB0_BASE + 0x124) + + +/* Device/host operational registers */ + +/* USB command (device mode) */ +#define USB0_USBCMD_D MMIO32(USB0_BASE + 0x140) + +/* USB command (host mode) */ +#define USB0_USBCMD_H MMIO32(USB0_BASE + 0x140) + +/* USB status (device mode) */ +#define USB0_USBSTS_D MMIO32(USB0_BASE + 0x144) + +/* USB status (host mode) */ +#define USB0_USBSTS_H MMIO32(USB0_BASE + 0x144) + +/* USB interrupt enable (device mode) */ +#define USB0_USBINTR_D MMIO32(USB0_BASE + 0x148) + +/* USB interrupt enable (host mode) */ +#define USB0_USBINTR_H MMIO32(USB0_BASE + 0x148) + +/* USB frame index (device mode) */ +#define USB0_FRINDEX_D MMIO32(USB0_BASE + 0x14C) + +/* USB frame index (host mode) */ +#define USB0_FRINDEX_H MMIO32(USB0_BASE + 0x14C) + +/* USB device address (device mode) */ +#define USB0_DEVICEADDR MMIO32(USB0_BASE + 0x154) + +/* Frame list base address (host mode) */ +#define USB0_PERIODICLISTBASE MMIO32(USB0_BASE + 0x154) + +/* Address of endpoint list in memory */ +#define USB0_ENDPOINTLISTADDR MMIO32(USB0_BASE + 0x158) + +/* Asynchronous list address */ +#define USB0_ASYNCLISTADDR MMIO32(USB0_BASE + 0x158) + +/* Asynchronous buffer status for embedded TT (host mode) */ +#define USB0_TTCTRL MMIO32(USB0_BASE + 0x15C) + +/* Programmable burst size */ +#define USB0_BURSTSIZE MMIO32(USB0_BASE + 0x160) + +/* Host transmit pre-buffer packet tuning (host mode) */ +#define USB0_TXFILLTUNING MMIO32(USB0_BASE + 0x164) + +/* Length of virtual frame */ +#define USB0_BINTERVAL MMIO32(USB0_BASE + 0x174) + +/* Endpoint NAK (device mode) */ +#define USB0_ENDPTNAK MMIO32(USB0_BASE + 0x178) + +/* Endpoint NAK Enable (device mode) */ +#define USB0_ENDPTNAKEN MMIO32(USB0_BASE + 0x17C) + +/* Port 1 status/control (device mode) */ +#define USB0_PORTSC1_D MMIO32(USB0_BASE + 0x184) + +/* Port 1 status/control (host mode) */ +#define USB0_PORTSC1_H MMIO32(USB0_BASE + 0x184) + +/* OTG status and control */ +#define USB0_OTGSC MMIO32(USB0_BASE + 0x1A4) + +/* USB device mode (device mode) */ +#define USB0_USBMODE_D MMIO32(USB0_BASE + 0x1A8) + +/* USB device mode (host mode) */ +#define USB0_USBMODE_H MMIO32(USB0_BASE + 0x1A8) + + +/* Device endpoint registers */ + +/* Endpoint setup status */ +#define USB0_ENDPTSETUPSTAT MMIO32(USB0_BASE + 0x1AC) + +/* Endpoint initialization */ +#define USB0_ENDPTPRIME MMIO32(USB0_BASE + 0x1B0) + +/* Endpoint de-initialization */ +#define USB0_ENDPTFLUSH MMIO32(USB0_BASE + 0x1B4) + +/* Endpoint status */ +#define USB0_ENDPTSTAT MMIO32(USB0_BASE + 0x1B8) + +/* Endpoint complete */ +#define USB0_ENDPTCOMPLETE MMIO32(USB0_BASE + 0x1BC) + +/* Endpoint control 0 */ +#define USB0_ENDPTCTRL0 MMIO32(USB0_BASE + 0x1C0) + +/* Endpoint control 1 */ +#define USB0_ENDPTCTRL1 MMIO32(USB0_BASE + 0x1C4) + +/* Endpoint control 2 */ +#define USB0_ENDPTCTRL2 MMIO32(USB0_BASE + 0x1C8) + +/* Endpoint control 3 */ +#define USB0_ENDPTCTRL3 MMIO32(USB0_BASE + 0x1CC) + +/* Endpoint control 4 */ +#define USB0_ENDPTCTRL4 MMIO32(USB0_BASE + 0x1D0) + +/* Endpoint control 5 */ +#define USB0_ENDPTCTRL5 MMIO32(USB0_BASE + 0x1D4) + + +/* --- USB1 registers ------------------------------------------------------ */ +//TODO + +#endif diff --git a/include/libopencm3/lpc43xx/wwdt.h b/include/libopencm3/lpc43xx/wwdt.h new file mode 100644 index 00000000..b4e63bf5 --- /dev/null +++ b/include/libopencm3/lpc43xx/wwdt.h @@ -0,0 +1,46 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#ifndef LPC43XX_WWDT_H +#define LPC43XX_WWDT_H + +#include +#include + +/* --- Windowed Watchdog Timer (WWDT) registers ---------------------------- */ + +/* Watchdog mode register */ +#define WWDT_MOD MMIO32(WWDT_BASE + 0x000) + +/* Watchdog timer constant register */ +#define WWDT_TC MMIO32(WWDT_BASE + 0x004) + +/* Watchdog feed sequence register */ +#define WWDT_FEED MMIO32(WWDT_BASE + 0x008) + +/* Watchdog timer value register */ +#define WWDT_TV MMIO32(WWDT_BASE + 0x00C) + +/* Watchdog warning interrupt register */ +#define WWDT_WARNINT MMIO32(WWDT_BASE + 0x014) + +/* Watchdog timer window register */ +#define WWDT_WINDOW MMIO32(WWDT_BASE + 0x018) + +#endif diff --git a/include/libopencm3/stm32/can.h b/include/libopencm3/stm32/can.h index 0a057989..d6636d5f 100644 --- a/include/libopencm3/stm32/can.h +++ b/include/libopencm3/stm32/can.h @@ -615,6 +615,8 @@ /* --- CAN functions -------------------------------------------------------- */ +BEGIN_DECLS + void can_reset(u32 canport); int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart, bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp); @@ -639,4 +641,6 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext, void can_fifo_release(u32 canport, u8 fifo); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/crc.h b/include/libopencm3/stm32/crc.h index 6ae40854..3848191f 100644 --- a/include/libopencm3/stm32/crc.h +++ b/include/libopencm3/stm32/crc.h @@ -53,6 +53,30 @@ /* --- CRC function prototypes --------------------------------------------- */ +BEGIN_DECLS + /* TODO */ +/** + * Reset the CRC calculator to initial values. + */ +void crc_reset(void); + +/** + * Add a word to the crc calculator and return the result. + * @param data new word to add to the crc calculator + * @return final crc calculator value + */ +u32 crc_calculate(u32 data); + +/** + * Add a block of data to the CRC calculator and return the final result + * @param datap pointer to the start of a block of 32bit data words + * @param size length of data, in 32bit increments + * @return final CRC calculator value + */ +u32 crc_calculate_block(u32 *datap, int size); + +END_DECLS + #endif diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h index 0402eb02..75d4edbe 100644 --- a/include/libopencm3/stm32/dac.h +++ b/include/libopencm3/stm32/dac.h @@ -1,3 +1,19 @@ +/** @defgroup STM32F_dac_defines DAC Defines + +@brief libopencm3 Defined Constants and Types for the STM32F Digital to Analog Converter + +@ingroup STM32F_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Felix Held +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ + /* * This file is part of the libopencm3 project. * @@ -17,6 +33,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H @@ -69,7 +87,7 @@ /* --- DAC_CR values ------------------------------------------------------- */ /* DMAUDRIE2: DAC channel2 DMA underrun interrupt enable */ -/* doesn't exist in most members of the stm32f1 family */ +/* doesn't exist in most members of the STM32F1 family */ #define DAC_CR_DMAUDRIE2 (1 << 29) /* DMAEN2: DAC channel2 DMA enable */ @@ -80,6 +98,11 @@ * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 */ #define DAC_CR_MAMP2_SHIFT 24 +/** @defgroup dac_mamp2 DAC Channel 2 LFSR Mask and Triangle Wave Amplitude values +@ingroup STM32F_dac_defines + +Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 +@{*/ #define DAC_CR_MAMP2_1 (0x0 << DAC_CR_MAMP2_SHIFT) #define DAC_CR_MAMP2_2 (0x1 << DAC_CR_MAMP2_SHIFT) #define DAC_CR_MAMP2_3 (0x2 << DAC_CR_MAMP2_SHIFT) @@ -92,6 +115,7 @@ #define DAC_CR_MAMP2_10 (0x9 << DAC_CR_MAMP2_SHIFT) #define DAC_CR_MAMP2_11 (0xA << DAC_CR_MAMP2_SHIFT) #define DAC_CR_MAMP2_12 (0xB << DAC_CR_MAMP2_SHIFT) +/**@}*/ /* WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ /* Legend: @@ -102,9 +126,18 @@ * Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) */ #define DAC_CR_WAVE2_SHIFT 22 -#define DAC_CR_WAVE2_DIS (0x0 << DAC_CR_WAVE2_SHIFT) +#define DAC_CR_WAVE2_DIS (0x3 << DAC_CR_WAVE2_SHIFT) +/** @defgroup dac_wave2_en DAC Channel 2 Waveform Generation Enable +@ingroup STM32F_dac_defines + +@li NOISE: Noise wave generation enabled +@li TRI: Triangle wave generation enabled + +@note: only used if bit TEN2 is set (DAC channel2 trigger enabled) +@{*/ #define DAC_CR_WAVE2_NOISE (0x1 << DAC_CR_WAVE2_SHIFT) #define DAC_CR_WAVE2_TRI (0x2 << DAC_CR_WAVE2_SHIFT) +/**@}*/ /* TSEL2[2:0]: DAC channel2 trigger selection */ /* Legend: @@ -125,6 +158,25 @@ * Note: this is *not* valid for the STM32L1 family */ #define DAC_CR_TSEL2_SHIFT 19 +/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection +@ingroup STM32F_dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) +@{*/ #define DAC_CR_TSEL2_T6 (0x0 << DAC_CR_TSEL2_SHIFT) #define DAC_CR_TSEL2_T3 (0x1 << DAC_CR_TSEL2_SHIFT) #define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) @@ -135,6 +187,7 @@ #define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) #define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) #define DAC_CR_TSEL2_SW (0x7 << DAC_CR_TSEL2_SHIFT) +/**@}*/ /* TEN2: DAC channel2 trigger enable */ #define DAC_CR_TEN2 (1 << 18) @@ -146,7 +199,7 @@ #define DAC_CR_EN2 (1 << 16) /* DMAUDRIE1: DAC channel1 DMA underrun interrupt enable */ -/* doesn't exist in most members of the stm32f1 family */ +/* doesn't exist in most members of the STM32F1 family */ #define DAC_CR_DMAUDRIE1 (1 << 13) /* DMAEN1: DAC channel1 DMA enable */ @@ -157,6 +210,11 @@ * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 */ #define DAC_CR_MAMP1_SHIFT 8 +/** @defgroup dac_mamp1 DAC Channel 1 LFSR Mask and Triangle Wave Amplitude values +@ingroup STM32F_dac_defines + +Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 +@{*/ #define DAC_CR_MAMP1_1 (0x0 << DAC_CR_MAMP1_SHIFT) #define DAC_CR_MAMP1_2 (0x1 << DAC_CR_MAMP1_SHIFT) #define DAC_CR_MAMP1_3 (0x2 << DAC_CR_MAMP1_SHIFT) @@ -169,6 +227,7 @@ #define DAC_CR_MAMP1_10 (0x9 << DAC_CR_MAMP1_SHIFT) #define DAC_CR_MAMP1_11 (0xA << DAC_CR_MAMP1_SHIFT) #define DAC_CR_MAMP1_12 (0xB << DAC_CR_MAMP1_SHIFT) +/**@}*/ /* WAVE1[1:0]: DAC channel1 noise/triangle wave generation enable */ /* Legend: @@ -179,9 +238,19 @@ * Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled) */ #define DAC_CR_WAVE1_SHIFT 6 -#define DAC_CR_WAVE1_DIS (0x0 << DAC_CR_WAVE1_SHIFT) +#define DAC_CR_WAVE1_DIS (0x3 << DAC_CR_WAVE1_SHIFT) +/** @defgroup dac_wave1_en DAC Channel 1 Waveform Generation Enable +@ingroup STM32F_dac_defines + +@li DIS: wave generation disabled +@li NOISE: Noise wave generation enabled +@li TRI: Triangle wave generation enabled + +@note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) +@{*/ #define DAC_CR_WAVE1_NOISE (0x1 << DAC_CR_WAVE1_SHIFT) #define DAC_CR_WAVE1_TRI (0x2 << DAC_CR_WAVE1_SHIFT) +/**@}*/ /* TSEL1[2:0]: DAC channel1 trigger selection */ /* Legend: @@ -202,6 +271,25 @@ * Note: this is *not* valid for the STM32L1 family */ #define DAC_CR_TSEL1_SHIFT 3 +/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection +@ingroup STM32F_dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line 9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN2 is set (DAC channel 1 trigger enabled). +@{*/ #define DAC_CR_TSEL1_T6 (0x0 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_T3 (0x1 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) @@ -212,6 +300,7 @@ #define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_SW (0x7 << DAC_CR_TSEL1_SHIFT) +/**@}*/ /* TEN1: DAC channel1 trigger enable */ #define DAC_CR_TEN1 (1 << 2) @@ -292,11 +381,38 @@ #define DAC_DOR2_DACC2DOR_LSB (1 << 0) #define DAC_DOR2_DACC2DOR_MSK (0x0FFF << 0) +/** DAC channel identifier */ +typedef enum { + CHANNEL_1, CHANNEL_2, CHANNEL_D +} data_channel; + +/** DAC data size (8/12 bits), alignment (right/left) */ +typedef enum { + RIGHT8, RIGHT12, LEFT12 +} data_align; /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS -/* TODO */ +void dac_enable(data_channel dac_channel); +void dac_disable(data_channel dac_channel); +void dac_buffer_enable(data_channel dac_channel); +void dac_buffer_disable(data_channel dac_channel); +void dac_dma_enable(data_channel dac_channel); +void dac_dma_disable(data_channel dac_channel); +void dac_trigger_enable(data_channel dac_channel); +void dac_trigger_disable(data_channel dac_channel); +void dac_set_trigger_source(u32 dac_trig_src); +void dac_set_waveform_generation(u32 dac_wave_ens); +void dac_disable_waveform_generation(data_channel dac_channel); +void dac_set_waveform_characteristics(u32 dac_mamp); +void dac_load_data_buffer_single(u32 dac_data, data_align dac_data_format, data_channel dac_channel); +void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data_format); +void dac_software_trigger(data_channel dac_channel); +END_DECLS #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/doc-stm32f.h b/include/libopencm3/stm32/doc-stm32f.h new file mode 100644 index 00000000..b0532de3 --- /dev/null +++ b/include/libopencm3/stm32/doc-stm32f.h @@ -0,0 +1,24 @@ +/** @defgroup STM32F_defines STM32F Top Level Defines + +@brief Defined Constants and Types for the STM32F series + +@ingroup STM32F + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ + +/** @defgroup STM32F_files STM32F Top Level Files + +@brief Common Files for ST Microelectronics STM32F series. + +@ingroup STM32F + +*/ + + diff --git a/include/libopencm3/stm32/exti.h b/include/libopencm3/stm32/exti.h index d1935ad1..7645825d 100644 --- a/include/libopencm3/stm32/exti.h +++ b/include/libopencm3/stm32/exti.h @@ -61,10 +61,14 @@ typedef enum trigger_e { EXTI_TRIGGER_BOTH, } exti_trigger_type; +BEGIN_DECLS + void exti_set_trigger(u32 extis, exti_trigger_type trig); void exti_enable_request(u32 extis); void exti_disable_request(u32 extis); void exti_reset_request(u32 extis); void exti_select_source(u32 exti, u32 gpioport); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f1/adc.h b/include/libopencm3/stm32/f1/adc.h index 563e75dc..b1396a59 100644 --- a/include/libopencm3/stm32/f1/adc.h +++ b/include/libopencm3/stm32/f1/adc.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F1xx_adc_defines ADC Defines + +@brief Defined Constants and Types for the STM32F1xx Analog to Digital Converters + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Edward Cheeseman + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +31,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_ADC_H #define LIBOPENCM3_ADC_H @@ -26,9 +42,15 @@ /* --- Convenience macros -------------------------------------------------- */ /* ADC port base addresses (for convenience) */ +/****************************************************************************/ +/** @defgroup adc_reg_base ADC register base addresses +@ingroup STM32F1xx_adc_defines + +@{*/ #define ADC1 ADC1_BASE #define ADC2 ADC2_BASE #define ADC3 ADC3_BASE +/**@}*/ /* --- ADC registers ------------------------------------------------------- */ @@ -140,6 +162,35 @@ #define ADC2_DR ADC_DR(ADC2) #define ADC3_DR ADC_DR(ADC3) +/* --- ADC Channels ------------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup adc_channel ADC Channel Numbers +@ingroup STM32F1xx_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_MASK 0x1F +#define ADC_SHIFT 0 + /* --- ADC_SR values ------------------------------------------------------- */ #define ADC_SR_STRT (1 << 4) @@ -171,20 +222,42 @@ * SIM: Slow interleaved mode only. * ATM: Alternate trigger mode only. */ +/****************************************************************************/ +/* ADC_CR1 DUALMOD[3:0] ADC Mode Selection */ +/** @defgroup adc_cr1_dualmod ADC Mode Selection +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Independent (non-dual) mode */ #define ADC_CR1_DUALMOD_IND (0x0 << 16) +/** Combined regular simultaneous + injected simultaneous mode. */ #define ADC_CR1_DUALMOD_CRSISM (0x1 << 16) +/** Combined regular simultaneous + alternate trigger mode. */ #define ADC_CR1_DUALMOD_CRSATM (0x2 << 16) +/** Combined injected simultaneous + fast interleaved mode. */ #define ADC_CR1_DUALMOD_CISFIM (0x3 << 16) +/** Combined injected simultaneous + slow interleaved mode. */ #define ADC_CR1_DUALMOD_CISSIM (0x4 << 16) +/** Injected simultaneous mode only. */ #define ADC_CR1_DUALMOD_ISM (0x5 << 16) +/** Regular simultaneous mode only. */ #define ADC_CR1_DUALMOD_RSM (0x6 << 16) +/** Fast interleaved mode only. */ #define ADC_CR1_DUALMOD_FIM (0x7 << 16) +/** Slow interleaved mode only. */ #define ADC_CR1_DUALMOD_SIM (0x8 << 16) +/** Alternate trigger mode only. */ #define ADC_CR1_DUALMOD_ATM (0x9 << 16) +/**@}*/ #define ADC_CR1_DUALMOD_MASK (0xF << 16) #define ADC_CR1_DUALMOD_SHIFT 16 /* DISCNUM[2:0]: Discontinous mode channel count. */ +/****************************************************************************/ +/** @defgroup adc_cr1_discnum ADC Number of channels in discontinuous mode. +@ingroup STM32F1xx_adc_defines + +@{*/ #define ADC_CR1_DISCNUM_1CHANNELS (0x0 << 13) #define ADC_CR1_DISCNUM_2CHANNELS (0x1 << 13) #define ADC_CR1_DISCNUM_3CHANNELS (0x2 << 13) @@ -193,31 +266,32 @@ #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: Discontinous mode on injected channels. */ +/* JDISCEN: */ /** Discontinous mode on injected channels. */ #define ADC_CR1_JDISCEN (1 << 12) -/* DISCEN: Discontinous mode on regular channels. */ +/* DISCEN: */ /** Discontinous mode on regular channels. */ #define ADC_CR1_DISCEN (1 << 11) -/* JAUTO: Automatic Injection Group conversion. */ +/* JAUTO: */ /** Automatic Injection Group conversion. */ #define ADC_CR1_JAUTO (1 << 10) -/* AWDSGL: Enable the watchdog on a single channel in scan mode. */ +/* AWDSGL: */ /** Enable the watchdog on a single channel in scan mode. */ #define ADC_CR1_AWDSGL (1 << 9) -/* SCAN: Scan mode. */ +/* SCAN: */ /** Scan mode. */ #define ADC_CR1_SCAN (1 << 8) -/* JEOCIE: Interrupt enable for injected channels. */ +/* JEOCIE: */ /** Interrupt enable for injected channels. */ #define ADC_CR1_JEOCIE (1 << 7) -/* AWDIE: Analog watchdog interrupt enable. */ +/* AWDIE: */ /** Analog watchdog interrupt enable. */ #define ADC_CR1_AWDIE (1 << 6) -/* EOCIE: Interrupt enable EOC. */ +/* EOCIE: */ /** Interrupt enable EOC. */ #define ADC_CR1_EOCIE (1 << 5) /* AWDCH[4:0]: Analog watchdog channel bits. (Up to 17 other values reserved) */ @@ -227,6 +301,12 @@ * 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 STM32F1xx_adc_defines + +@{*/ #define ADC_CR1_AWDCH_CHANNEL0 (0x00 << 0) #define ADC_CR1_AWDCH_CHANNEL1 (0x01 << 0) #define ADC_CR1_AWDCH_CHANNEL2 (0x02 << 0) @@ -245,41 +325,72 @@ #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 ------------------------------------------------------ */ -/* TSVREFE: Temperature sensor and V_REFINT enable. (ADC1 only!) */ +/* TSVREFE: */ /** Temperature sensor and V_REFINT enable. (ADC1 only!) */ #define ADC_CR2_TSVREFE (1 << 23) -/* SWSTART: Start conversion of regular channels. */ +/* SWSTART: */ /** Start conversion of regular channels. */ #define ADC_CR2_SWSTART (1 << 22) -/* JSWSTART: Start conversion of injected channels. */ +/* JSWSTART: */ /** Start conversion of injected channels. */ #define ADC_CR2_JSWSTART (1 << 21) -/* EXTTRIG: External trigger conversion mode for regular channels. */ +/* EXTTRIG: */ /** External trigger conversion mode for regular channels. */ #define ADC_CR2_EXTTRIG (1 << 20) /* EXTSEL[2:0]: External event select for regular group. */ /* The following are only valid for ADC1 and ADC2. */ +/****************************************************************************/ +/* ADC_CR2 EXTSEL[2:0] ADC Trigger Identifier for ADC1 and ADC2 */ +/** @defgroup adc_trigger_regular_12 ADC Trigger Identifier for ADC1 and ADC2 +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Timer 1 Compare Output 1 */ #define ADC_CR2_EXTSEL_TIM1_CC1 (0x0 << 17) +/** Timer 1 Compare Output 2 */ #define ADC_CR2_EXTSEL_TIM1_CC2 (0x1 << 17) +/** Timer 1 Compare Output 3 */ #define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 17) +/** Timer 2 Compare Output 2 */ #define ADC_CR2_EXTSEL_TIM2_CC2 (0x3 << 17) +/** Timer 3 Trigger Output */ #define ADC_CR2_EXTSEL_TIM3_TRGO (0x4 << 17) +/** Timer 4 Compare Output 4 */ #define ADC_CR2_EXTSEL_TIM4_CC4 (0x5 << 17) +/** External Interrupt 11 */ #define ADC_CR2_EXTSEL_EXTI11 (0x6 << 17) +/** Software Trigger */ #define ADC_CR2_EXTSEL_SWSTART (0x7 << 17) +/**@}*/ /* The following are only valid for ADC3 */ +/****************************************************************************/ +/* ADC_CR2 EXTSEL[2:0] ADC Trigger Identifier for ADC3 */ +/** @defgroup adc_trigger_regular_3 ADC Trigger Identifier for ADC3 +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Timer 2 Compare Output 1 */ #define ADC_CR2_EXTSEL_TIM3_CC1 (0x0 << 17) +/** Timer 2 Compare Output 3 */ #define ADC_CR2_EXTSEL_TIM2_CC3 (0x1 << 17) +/** Timer 1 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 17) +/** Timer 8 Compare Output 1 */ #define ADC_CR2_EXTSEL_TIM8_CC1 (0x3 << 17) +/** Timer 8 Trigger Output */ #define ADC_CR2_EXTSEL_TIM8_TRGO (0x4 << 17) +/** Timer 5 Compare Output 1 */ #define ADC_CR2_EXTSEL_TIM5_CC1 (0x5 << 17) +/** Timer 5 Compare Output 3 */ #define ADC_CR2_EXTSEL_TIM5_CC3 (0x6 << 17) +/**@}*/ #define ADC_CR2_EXTSEL_MASK (0x7 << 17) #define ADC_CR2_EXTSEL_SHIFT 17 @@ -291,21 +402,54 @@ /* JEXTSEL[2:0]: External event selection for injected group. */ /* The following are only valid for ADC1 and ADC2. */ +/****************************************************************************/ +/* ADC_CR2 JEXTSEL[2:0] ADC Injected Trigger Identifier for ADC1 and ADC2 */ +/** @defgroup adc_trigger_injected_12 ADC Injected Trigger Identifier for ADC1 and ADC2 +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Timer 1 Trigger Output */ #define ADC_CR2_JEXTSEL_TIM1_TRGO (0x0 << 12) +/** Timer 1 Compare Output 4 */ #define ADC_CR2_JEXTSEL_TIM1_CC4 (0x1 << 12) +/** Timer 2 Trigger Output */ #define ADC_CR2_JEXTSEL_TIM2_TRGO (0x2 << 12) +/** Timer 2 Compare Output 1 */ #define ADC_CR2_JEXTSEL_TIM2_CC1 (0x3 << 12) +/** Timer 3 Compare Output 4 */ #define ADC_CR2_JEXTSEL_TIM3_CC4 (0x4 << 12) +/** Timer 4 Trigger Output */ #define ADC_CR2_JEXTSEL_TIM4_TRGO (0x5 << 12) +/** External Interrupt 15 */ #define ADC_CR2_JEXTSEL_EXTI15 (0x6 << 12) +/** Injected Software Trigger */ #define ADC_CR2_JEXTSEL_JSWSTART (0x7 << 12) /* Software start. */ +/**@}*/ /* The following are the different meanings for ADC3 only. */ +/****************************************************************************/ +/* ADC_CR2 JEXTSEL[2:0] ADC Injected Trigger Identifier for ADC3 */ +/** @defgroup adc_trigger_injected_3 ADC Injected Trigger Identifier for ADC3 +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Timer 1 Trigger Output */ +#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x0 << 12) +/** Timer 1 Compare Output 4 */ +#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x1 << 12) +/** Timer 4 Compare Output 3 */ #define ADC_CR2_JEXTSEL_TIM4_CC3 (0x2 << 12) +/** Timer 8 Compare Output 2 */ #define ADC_CR2_JEXTSEL_TIM8_CC2 (0x3 << 12) +/** Timer 8 Compare Output 4 */ #define ADC_CR2_JEXTSEL_TIM8_CC4 (0x4 << 12) +/** Timer 5 Trigger Output */ #define ADC_CR2_JEXTSEL_TIM5_TRGO (0x5 << 12) +/** Timer53 Compare Output 4 */ #define ADC_CR2_JEXTSEL_TIM5_CC4 (0x6 << 12) +/** Injected Software Trigger */ +#define ADC_CR2_JEXTSEL_JSWSTART (0x7 << 12) /* Software start. */ +/**@}*/ #define ADC_CR2_JEXTSEL_MASK (0x7 << 12) #define ADC_CR2_JEXTSEL_SHIFT 12 @@ -340,7 +484,6 @@ #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 @@ -357,6 +500,12 @@ #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 STM32F1xx_adc_defines + +@{*/ #define ADC_SMPR1_SMP_1DOT5CYC 0x0 #define ADC_SMPR1_SMP_7DOT5CYC 0x1 #define ADC_SMPR1_SMP_13DOT5CYC 0x2 @@ -365,6 +514,7 @@ #define ADC_SMPR1_SMP_55DOT5CYC 0x5 #define ADC_SMPR1_SMP_71DOT5CYC 0x6 #define ADC_SMPR1_SMP_239DOT5CYC 0x7 +/**@}*/ /* --- ADC_SMPR2 values ---------------------------------------------------- */ @@ -388,6 +538,12 @@ #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 STM32F1xx_adc_defines + +@{*/ #define ADC_SMPR2_SMP_1DOT5CYC 0x0 #define ADC_SMPR2_SMP_7DOT5CYC 0x1 #define ADC_SMPR2_SMP_13DOT5CYC 0x2 @@ -396,9 +552,15 @@ #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 Generic +@ingroup STM32F1xx_adc_defines +@{*/ #define ADC_SMPR_SMP_1DOT5CYC 0x0 #define ADC_SMPR_SMP_7DOT5CYC 0x1 #define ADC_SMPR_SMP_13DOT5CYC 0x2 @@ -407,6 +569,7 @@ #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 ---------------------------------- */ @@ -429,6 +592,13 @@ #define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQ15_LSB) #define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQ14_LSB) #define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQ13_LSB) +/* TODO Fix error +#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 ----------------------------------------------------- */ @@ -444,6 +614,14 @@ #define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQ9_LSB) #define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQ8_LSB) #define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQ7_LSB) +/* TODO Fix error +#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 ----------------------------------------------------- */ @@ -459,7 +637,14 @@ #define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQ3_LSB) #define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQ2_LSB) #define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQ1_LSB) - +/* TODO Fix error +#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 @@ -472,6 +657,13 @@ #define ADC_JSQR_JSQ3_MSK (0x1f << ADC_JSQ3_LSB) #define ADC_JSQR_JSQ2_MSK (0x1f << ADC_JSQ2_LSB) #define ADC_JSQR_JSQ1_MSK (0x1f << ADC_JSQ1_LSB) +/* TODO Fix error +#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 --------------------------------------------- */ @@ -481,10 +673,11 @@ #define ADC_JDATA_MSK (0xffff << ADC_JDATA_LSB) #define ADC_DATA_MSK (0xffff << ADC_DA) #define ADC_ADC2DATA_MSK (0xffff << ADC_ADC2DATA_LSB) - /* ADC1 only (dual mode) */ + /* ADC1 only (dual mode) */ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS /* TODO */ void adc_enable_analog_watchdog_regular(u32 adc); @@ -532,4 +725,8 @@ 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[]); +END_DECLS + #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/f1/desig.h b/include/libopencm3/stm32/f1/desig.h new file mode 100644 index 00000000..74cfb353 --- /dev/null +++ b/include/libopencm3/stm32/f1/desig.h @@ -0,0 +1,56 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +#ifndef LIBOPENCM3_DESIG_H +#define LIBOPENCM3_DESIG_H + +#include +#include + +/* --- Device Electronic Signature -------------------------------- */ + +/* Flash size register */ +#define DESIG_FLASH_SIZE MMIO16(DESIG_FLASH_SIZE_BASE + 0x00) + +/* Unique ID register (96 bits) */ +/* Note: ST says these may be accessed in any width if you choose */ +#define DESIG_UID_15_0 MMIO16(DESIG_UNIQUE_ID_BASE + 0x00) +/* Listed as "This field value is also reserved for a future feature" WTH?! */ +#define DESIG_UID_31_16 MMIO16(DESIG_UNIQUE_ID_BASE + 0x02) +#define DESIG_UID_63_32 MMIO32(DESIG_UNIQUE_ID_BASE + 0x04) +#define DESIG_UID_95_64 MMIO32(DESIG_UNIQUE_ID_BASE + 0x08) + +BEGIN_DECLS + +/** + * Read the onboard flash size + * @return flash size in KB + */ +u16 desig_get_flash_size(void); + +/** + * Read the full 96 bit unique identifier + * Note: ST specifies that bits 31..16 are _also_ reserved for future use + * @param result pointer to at least 3xu32s (96 bits) + */ +void desig_get_unique_id(u32 result[]); + +END_DECLS + +#endif diff --git a/include/libopencm3/stm32/f1/dma.h b/include/libopencm3/stm32/f1/dma.h index 5aa01835..b08803f7 100644 --- a/include/libopencm3/stm32/f1/dma.h +++ b/include/libopencm3/stm32/f1/dma.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F1xx_dma_defines DMA Defines + +@ingroup STM32F1xx_defines + +@brief Defined Constants and Types for the STM32F1xx DMA Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -18,6 +32,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_DMA_H #define LIBOPENCM3_DMA_H @@ -241,24 +257,39 @@ #define DMA_CCR_MEM2MEM (1 << 14) /* PL[13:12]: Channel priority level */ +/** @defgroup dma_ch_pri DMA Channel Priority Levels +@ingroup STM32F1xx_dma_defines + +@{*/ #define DMA_CCR_PL_LOW (0x0 << 12) #define DMA_CCR_PL_MEDIUM (0x1 << 12) #define DMA_CCR_PL_HIGH (0x2 << 12) #define DMA_CCR_PL_VERY_HIGH (0x3 << 12) +/**@}*/ #define DMA_CCR_PL_MASK (0x3 << 12) #define DMA_CCR_PL_SHIFT 12 /* MSIZE[11:10]: Memory size */ +/** @defgroup dma_ch_memwidth DMA Channel Memory Word Width +@ingroup STM32F1xx_dma_defines + +@{*/ #define DMA_CCR_MSIZE_8BIT (0x0 << 10) #define DMA_CCR_MSIZE_16BIT (0x1 << 10) #define DMA_CCR_MSIZE_32BIT (0x2 << 10) +/**@}*/ #define DMA_CCR_MSIZE_MASK (0x3 << 10) #define DMA_CCR_MSIZE_SHIFT 10 /* PSIZE[9:8]: Peripheral size */ +/** @defgroup dma_ch_perwidth DMA Channel Peripheral Word Width +@ingroup STM32F1xx_dma_defines + +@{*/ #define DMA_CCR_PSIZE_8BIT (0x0 << 8) #define DMA_CCR_PSIZE_16BIT (0x1 << 8) #define DMA_CCR_PSIZE_32BIT (0x2 << 8) +/**@}*/ #define DMA_CCR_PSIZE_MASK (0x3 << 8) #define DMA_CCR_PSIZE_SHIFT 8 @@ -300,6 +331,10 @@ /* --- Generic values ------------------------------------------------------ */ +/** @defgroup dma_ch DMA Channel Number +@ingroup STM32F1xx_dma_defines + +@{*/ #define DMA_CHANNEL1 1 #define DMA_CHANNEL2 2 #define DMA_CHANNEL3 3 @@ -307,9 +342,12 @@ #define DMA_CHANNEL5 5 #define DMA_CHANNEL6 6 #define DMA_CHANNEL7 7 +/**@}*/ /* --- function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void dma_channel_reset(u32 dma, u8 channel); void dma_enable_mem2mem_mode(u32 dma, u8 channel); void dma_set_priority(u32 dma, u8 channel, u32 prio); @@ -332,4 +370,8 @@ void dma_set_peripheral_address(u32 dma, u8 channel, u32 address); void dma_set_memory_address(u32 dma, u8 channel, u32 address); void dma_set_number_of_data(u32 dma, u8 channel, u16 number); +END_DECLS + #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/f1/doc-stm32f1.h b/include/libopencm3/stm32/f1/doc-stm32f1.h new file mode 100644 index 00000000..04293a66 --- /dev/null +++ b/include/libopencm3/stm32/f1/doc-stm32f1.h @@ -0,0 +1,15 @@ +/** @defgroup STM32F1xx_defines STM32F1xx Defines + +@brief Defined Constants and Types for the STM32F1xx series + +@ingroup STM32F1xx + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ + diff --git a/include/libopencm3/stm32/f1/flash.h b/include/libopencm3/stm32/f1/flash.h index 2c026d6a..919b4d4a 100644 --- a/include/libopencm3/stm32/f1/flash.h +++ b/include/libopencm3/stm32/f1/flash.h @@ -89,6 +89,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void flash_prefetch_buffer_enable(void); void flash_prefetch_buffer_disable(void); void flash_halfcycle_enable(void); @@ -110,4 +112,6 @@ void flash_wait_for_last_operation(void); void flash_erase_option_bytes(void); void flash_program_option_bytes(u32 address, u16 data); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f1/gpio.h b/include/libopencm3/stm32/f1/gpio.h index e4e11bec..a1e74cc2 100644 --- a/include/libopencm3/stm32/f1/gpio.h +++ b/include/libopencm3/stm32/f1/gpio.h @@ -1,3 +1,18 @@ +/** @defgroup STM32F1xx_gpio_defines GPIO Defines + +@brief Defined Constants and Types for the STM32F1xx General Purpose I/O + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 Piotr Esden-Tempski + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +32,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ +/**@{*/ #ifndef LIBOPENCM3_GPIO_H #define LIBOPENCM3_GPIO_H @@ -27,6 +43,10 @@ /* --- Convenience macros -------------------------------------------------- */ /* GPIO port base addresses (for convenience) */ +/** @defgroup gpio_port_id GPIO Port IDs +@ingroup STM32F1xx_gpio_defines + +@{*/ #define GPIOA GPIO_PORT_A_BASE #define GPIOB GPIO_PORT_B_BASE #define GPIOC GPIO_PORT_C_BASE @@ -34,8 +54,13 @@ #define GPIOE GPIO_PORT_E_BASE #define GPIOF GPIO_PORT_F_BASE #define GPIOG GPIO_PORT_G_BASE +/**@}*/ /* GPIO number definitions (for convenience) */ +/** @defgroup gpio_pin_id GPIO Pin Identifiers +@ingroup STM32F1xx_gpio_defines + +@{*/ #define GPIO0 (1 << 0) #define GPIO1 (1 << 1) #define GPIO2 (1 << 2) @@ -53,6 +78,7 @@ #define GPIO14 (1 << 14) #define GPIO15 (1 << 15) #define GPIO_ALL 0xffff +/**@}*/ /* --- Alternate function GPIOs -------------------------------------------- */ @@ -593,22 +619,50 @@ /* --- GPIO_CRL/GPIO_CRH values -------------------------------------------- */ -/* CNF[1:0] values when MODE[1:0] is 00 (input mode) */ -#define GPIO_CNF_INPUT_ANALOG 0x00 -#define GPIO_CNF_INPUT_FLOAT 0x01 /* Default */ -#define GPIO_CNF_INPUT_PULL_UPDOWN 0x02 +/** @defgroup gpio_cnf GPIO Pin Configuration +@ingroup STM32F1xx_gpio_defines +If mode specifies input, configuration can be +@li Analog input +@li Floating input +@li Pull up/down input -/* Output mode (MODE[1:0]) values */ -#define GPIO_MODE_INPUT 0x00 /* Default */ +If mode specifies output, configuration can be +@li Digital push-pull +@li Digital open drain +@li Alternate function push-pull or analog output +@li Alternate function open drain or analog output +@{*/ +/* CNF[1:0] values when MODE[1:0] is 00 (input mode) */ +/** Analog Input */ +#define GPIO_CNF_INPUT_ANALOG 0x00 +/** Digital Input Floating */ +#define GPIO_CNF_INPUT_FLOAT 0x01 /* Default */ +/** Digital Input Pull Up and Down */ +#define GPIO_CNF_INPUT_PULL_UPDOWN 0x02 +/* CNF[1:0] values when MODE[1:0] is != 00 (one of the output modes) */ +/** Digital Output Pushpull */ +#define GPIO_CNF_OUTPUT_PUSHPULL 0x00 +/** Digital Output Open Drain */ +#define GPIO_CNF_OUTPUT_OPENDRAIN 0x01 +/** Alternate Function Output Pushpull */ +#define GPIO_CNF_OUTPUT_ALTFN_PUSHPULL 0x02 +/** Alternate Function Output Open Drain */ +#define GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN 0x03 +/**@}*/ + +/* Pin mode (MODE[1:0]) values */ +/** @defgroup gpio_mode GPIO Pin Mode +@ingroup STM32F1xx_gpio_defines +@li Input (default after reset) +@li Output mode at 10 MHz maximum speed +@li Output mode at 2 MHz maximum speed +@li Output mode at 50 MHz maximum speed +@{*/ +#define GPIO_MODE_INPUT 0x00 /* Default */ #define GPIO_MODE_OUTPUT_10_MHZ 0x01 #define GPIO_MODE_OUTPUT_2_MHZ 0x02 #define GPIO_MODE_OUTPUT_50_MHZ 0x03 - -/* CNF[1:0] values when MODE[1:0] is != 00 (one of the output modes) */ -#define GPIO_CNF_OUTPUT_PUSHPULL 0x00 -#define GPIO_CNF_OUTPUT_OPENDRAIN 0x01 -#define GPIO_CNF_OUTPUT_ALTFN_PUSHPULL 0x02 -#define GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN 0x03 +/**@}*/ /* --- GPIO_IDR values ----------------------------------------------------- */ @@ -652,19 +706,31 @@ /* External interrupt configuration register 4 (AFIO_EXTICR4) */ #define AFIO_EXTICR4 MMIO32(AFIO_BASE + 0x14) +/* AF remap and debug I/O configuration register (AFIO_MAPR) */ +#define AFIO_MAPR2 MMIO32(AFIO_BASE + 0x1C) + /* --- AFIO_EVCR values ---------------------------------------------------- */ /* EVOE: Event output enable */ #define AFIO_EVCR_EVOE (1 << 7) /* PORT[2:0]: Port selection */ +/** @defgroup afio_evcr_port EVENTOUT Port selection +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_EVCR_PORT_PA (0x0 << 4) #define AFIO_EVCR_PORT_PB (0x1 << 4) #define AFIO_EVCR_PORT_PC (0x2 << 4) #define AFIO_EVCR_PORT_PD (0x3 << 4) #define AFIO_EVCR_PORT_PE (0x4 << 4) +/**@}*/ /* PIN[3:0]: Pin selection */ +/** @defgroup afio_evcr_pin EVENTOUT Pin selection +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_EVCR_PIN_Px0 (0x0 << 0) #define AFIO_EVCR_PIN_Px1 (0x1 << 0) #define AFIO_EVCR_PIN_Px2 (0x2 << 0) @@ -681,120 +747,211 @@ #define AFIO_EVCR_PIN_Px13 (0xD << 0) #define AFIO_EVCR_PIN_Px14 (0xE << 0) #define AFIO_EVCR_PIN_Px15 (0xF << 0) +/**@}*/ /* --- AFIO_MAPR values ---------------------------------------------------- */ /* 31 reserved */ -/* PTP_PPS_REMAP: Ethernet PTP PPS remapping +/** @defgroup afio_remap_cld Alternate Function Remap Controls for Connectivity +Line Devices only +@ingroup STM32F1xx_gpio_defines + +@{*/ +/* PTP_PPS_REMAP: *//** Ethernet PTP PPS remapping * (only connectivity line devices) */ #define AFIO_MAPR_PTP_PPS_REMAP (1 << 30) -/* TIM2ITR1_IREMAP: TIM2 internal trigger 1 remapping +/* TIM2ITR1_IREMAP: *//** TIM2 internal trigger 1 remapping * (only connectivity line devices) */ #define AFIO_MAPR_TIM2ITR1_IREMAP (1 << 29) -/* SPI3_REMAP: SPI3/I2S3 remapping +/* SPI3_REMAP: *//** SPI3/I2S3 remapping * (only connectivity line devices) */ #define AFIO_MAPR_SPI3_REMAP (1 << 28) +/* MII_REMAP: */ /** MII or RMII selection + * (only connectivity line devices) */ +#define AFIO_MAPR_MII_RMII_SEL (1 << 23) + +/* CAN2_REMAP: */ /** CAN2 I/O remapping + * (only connectivity line devices) */ +#define AFIO_MAPR_CAN2_REMAP (1 << 22) + +/* ETH_REMAP: */ /** Ethernet MAC I/O remapping + * (only connectivity line devices) */ +#define AFIO_MAPR_ETH_REMAP (1 << 21) + +/**@}*/ + /* 27 reserved */ /* SWJ_CFG[2:0]: Serial wire JTAG configuration */ +/** @defgroup afio_swj_disable Serial Wire JTAG disables +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_SWJ_MASK (0x7 << 24) +/** Full Serial Wire JTAG capability */ #define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) +/** Full Serial Wire JTAG capability without JNTRST */ #define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST (0x1 << 24) +/** JTAG-DP disabled with SW-DP enabled */ #define AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON (0x2 << 24) +/** JTAG-DP disabled and SW-DP disabled */ #define AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF (0x4 << 24) +/**@}*/ -/* MII_REMAP: MII or RMII selection - * (only connectivity line devices) */ -#define AFIO_MAPR_MII_RMII_SEL (1 << 23) +/** @defgroup afio_remap Alternate Function Remap Controls +@ingroup STM32F1xx_gpio_defines -/* CAN2_REMAP: CAN2 I/O remapping - * (only connectivity line devices) */ -#define AFIO_MAPR_CAN2_REMAP (1 << 22) - -/* ETH_REMAP: Ethernet MAC I/O remapping - * (only connectivity line devices) */ -#define AFIO_MAPR_ETH_REMAP (1 << 21) - -/* ADC2_ETRGREG_REMAP: ADC2 external trigger regulator conversion remapping +@{*/ +/* ADC2_ETRGREG_REMAP: */ /** ADC2 external trigger regulator conversion remapping * (only low-, medium-, high- and XL-densitiy devices) */ #define AFIO_MAPR_ADC2_ETRGREG_REMAP (1 << 20) -/* ADC2_ETRGINJ_REMAP: ADC2 external trigger injected conversion remapping +/* ADC2_ETRGINJ_REMAP: */ /** ADC2 external trigger injected conversion remapping * (only low-, medium-, high- and XL-densitiy devices) */ #define AFIO_MAPR_ADC2_ETRGINJ_REMAP (1 << 19) -/* ADC1_ETRGREG_REMAP: ADC1 external trigger regulator conversion remapping +/* ADC1_ETRGREG_REMAP: */ /** ADC1 external trigger regulator conversion remapping * (only low-, medium-, high- and XL-densitiy devices) */ #define AFIO_MAPR_ADC1_ETRGREG_REMAP (1 << 18) -/* ADC1_ETRGINJ_REMAP: ADC1 external trigger injected conversion remapping +/* ADC1_ETRGINJ_REMAP: */ /** ADC1 external trigger injected conversion remapping * (only low-, medium-, high- and XL-densitiy devices) */ #define AFIO_MAPR_ADC1_ETRGINJ_REMAP (1 << 17) -/* TIM5CH4_IREMAP: TIM5 channel4 internal remap */ +/* TIM5CH4_IREMAP: */ /** TIM5 channel4 internal remap */ #define AFIO_MAPR_TIM5CH4_IREMAP (1 << 16) -/* PD01_REMAP: Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ +/* PD01_REMAP: */ /** Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ #define AFIO_MAPR_PD01_REMAP (1 << 15) +/* TIM4_REMAP: */ /** TIM4 remapping */ +#define AFIO_MAPR_TIM4_REMAP (1 << 12) + +/* USART2_REMAP[1:0]: */ /** USART2 remapping */ +#define AFIO_MAPR_USART2_REMAP (1 << 3) + +/* USART1_REMAP[1:0]: */ /** USART1 remapping */ +#define AFIO_MAPR_USART1_REMAP (1 << 2) + +/* I2C1_REMAP[1:0]: */ /** I2C1 remapping */ +#define AFIO_MAPR_I2C1_REMAP (1 << 1) + +/* SPI1_REMAP[1:0]: */ /** SPI1 remapping */ +#define AFIO_MAPR_SPI1_REMAP (1 << 0) +/**@}*/ + /* CAN_REMAP[1:0]: CAN1 alternate function remapping */ +/** @defgroup afio_remap_can1 Alternate Function Remap Controls for CAN 1 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_CAN1_REMAP_PORTA (0x0 << 13) #define AFIO_MAPR_CAN1_REMAP_PORTB (0x2 << 13) /* Not on 36pin pkg */ #define AFIO_MAPR_CAN1_REMAP_PORTD (0x3 << 13) - -/* TIM4_REMAP: TIM4 remapping */ -#define AFIO_MAPR_TIM4_REMAP (1 << 12) +/**@}*/ /* TIM3_REMAP[1:0]: TIM3 remapping */ +/** @defgroup afio_remap_tim3 Alternate Function Remap Controls for Timer 3 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_TIM3_REMAP_NO_REMAP (0x0 << 10) #define AFIO_MAPR_TIM3_REMAP_PARTIAL_REMAP (0x2 << 10) #define AFIO_MAPR_TIM3_REMAP_FULL_REMAP (0x3 << 10) +/**@}*/ /* TIM2_REMAP[1:0]: TIM2 remapping */ +/** @defgroup afio_remap_tim2 Alternate Function Remap Controls for Timer 2 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_TIM2_REMAP_NO_REMAP (0x0 << 8) #define AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP1 (0x1 << 8) #define AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP2 (0x2 << 8) #define AFIO_MAPR_TIM2_REMAP_FULL_REMAP (0x3 << 8) +/**@}*/ /* TIM1_REMAP[1:0]: TIM1 remapping */ +/** @defgroup afio_remap_tim1 Alternate Function Remap Controls for Timer 1 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_TIM1_REMAP_NO_REMAP (0x0 << 6) #define AFIO_MAPR_TIM1_REMAP_PARTIAL_REMAP (0x1 << 6) #define AFIO_MAPR_TIM1_REMAP_FULL_REMAP (0x3 << 6) +/**@}*/ /* USART3_REMAP[1:0]: USART3 remapping */ +/** @defgroup afio_remap_usart3 Alternate Function Remap Controls for USART 3 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_USART3_REMAP_NO_REMAP (0x0 << 4) #define AFIO_MAPR_USART3_REMAP_PARTIAL_REMAP (0x1 << 4) #define AFIO_MAPR_USART3_REMAP_FULL_REMAP (0x3 << 4) +/**@}*/ -/* USART2_REMAP[1:0]: USART2 remapping */ -#define AFIO_MAPR_USART2_REMAP (1 << 3) +/** @defgroup afio_remap2 Alternate Function Remap Controls Secondary Set +@ingroup STM32F1xx_gpio_defines -/* USART1_REMAP[1:0]: USART1 remapping */ -#define AFIO_MAPR_USART1_REMAP (1 << 2) +@{*/ +/* FSMC_NADV_DISCONNECT: */ /** The NADV is disconnected from its allocated pin */ +#define AFIO_MAPR2_FSMC_NADV_DISCONNECT (1 << 10) -/* I2C1_REMAP[1:0]: I2C1 remapping */ -#define AFIO_MAPR_I2C1_REMAP (1 << 1) +/* TIM14_REMAP: */ /** TIM14 remapping */ +#define AFIO_MAPR2_TIM14_REMAP (1 << 9) -/* SPI1_REMAP[1:0]: SPI1 remapping */ -#define AFIO_MAPR_SPI1_REMAP (1 << 0) +/* TIM13_REMAP: */ /** TIM13 remapping */ +#define AFIO_MAPR2_TIM13_REMAP (1 << 8) + +/* TIM11_REMAP: */ /** TIM11 remapping */ +#define AFIO_MAPR2_TIM11_REMAP (1 << 7) + +/* TIM10_REMAP: */ /** TIM10 remapping */ +#define AFIO_MAPR2_TIM10_REMAP (1 << 6) + +/* TIM9_REMAP: */ /** TIM9 remapping */ +#define AFIO_MAPR2_TIM9_REMAP (1 << 5) + +/**@}*/ /* --- AFIO_EXTICR1 values ------------------------------------------------- */ /* --- AFIO_EXTICR2 values ------------------------------------------------- */ /* --- AFIO_EXTICR3 values ------------------------------------------------- */ /* --- AFIO_EXTICR4 values ------------------------------------------------- */ -/* EXTI0 - EXTI15 interrupt source selection registers */ +/** @defgroup afio_exti Alternate Function EXTI pin number +@ingroup STM32F1xx_gpio_defines -/* Note: For using them we should define a function that calculates the right - * registers, using definitions is probably not a good idea. - */ +@{*/ + +#define AFIO_EXTI0 0 +#define AFIO_EXTI1 1 +#define AFIO_EXTI2 2 +#define AFIO_EXTI3 3 +#define AFIO_EXTI4 4 +#define AFIO_EXTI5 5 +#define AFIO_EXTI6 6 +#define AFIO_EXTI7 7 +#define AFIO_EXTI8 8 +#define AFIO_EXTI9 9 +#define AFIO_EXTI10 10 +#define AFIO_EXTI11 11 +#define AFIO_EXTI12 12 +#define AFIO_EXTI13 13 +#define AFIO_EXTI14 14 +#define AFIO_EXTI15 15 + +/**@}*/ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios); void gpio_set(u32 gpioport, u16 gpios); void gpio_clear(u32 gpioport, u16 gpios); @@ -803,5 +960,12 @@ 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); +void gpio_set_eventout(u8 evoutport, u8 evoutpin); +void gpio_primary_remap(u8 swjenable, u32 maps); +void gpio_secondary_remap(u32 maps); + +END_DECLS #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/f1/memorymap.h b/include/libopencm3/stm32/f1/memorymap.h index f8528d41..5cc432e2 100644 --- a/include/libopencm3/stm32/f1/memorymap.h +++ b/include/libopencm3/stm32/f1/memorymap.h @@ -26,6 +26,7 @@ /* Memory map for all busses */ #define PERIPH_BASE ((u32)0x40000000) +#define INFO_BASE ((u32)0x1ffff000) #define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) #define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) #define PERIPH_BASE_AHB (PERIPH_BASE + 0x18000) @@ -110,4 +111,8 @@ /* FSMC */ #define FSMC_BASE (PERIPH_BASE + 0x60000000) +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x7e0) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x7e8) + #endif diff --git a/include/libopencm3/stm32/f1/nvic_f1.h b/include/libopencm3/stm32/f1/nvic_f1.h index 884f728c..5223bb6b 100644 --- a/include/libopencm3/stm32/f1/nvic_f1.h +++ b/include/libopencm3/stm32/f1/nvic_f1.h @@ -1,3 +1,13 @@ +/** @brief Defined Constants and Types for the STM32F1xx Nested Vectored Interrupt Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -27,6 +37,10 @@ */ /* 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 @@ -95,5 +109,6 @@ #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/rcc.h b/include/libopencm3/stm32/f1/rcc.h index 9cbe1e76..855e43bb 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -1,3 +1,18 @@ +/** @defgroup STM32F1xx_rcc_defines RCC Defines + +@brief libopencm3 STM32F1xx Reset and Clock Control + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Federico Ruiz-Ugalde \ +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +32,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ +/**@{*/ #ifndef LIBOPENCM3_RCC_H #define LIBOPENCM3_RCC_H @@ -62,6 +78,10 @@ /* --- RCC_CFGR values ----------------------------------------------------- */ /* MCO: Microcontroller clock output */ +/** @defgroup rcc_cfgr_co RCC_CFGR Microcontroller Clock Output Source +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_MCO_NOCLK 0x0 #define RCC_CFGR_MCO_SYSCLK 0x4 #define RCC_CFGR_MCO_HSICLK 0x5 @@ -71,16 +91,26 @@ #define RCC_CFGR_MCO_PLL3CLK_DIV2 0x9 /* (**) */ #define RCC_CFGR_MCO_XT1 0xa /* (**) */ #define RCC_CFGR_MCO_PLL3 0xb /* (**) */ +/**@}*/ /* USBPRE: USB prescaler (RCC_CFGR[22]) */ +/** @defgroup rcc_cfgr_usbpre RCC_CFGR USB prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_USBPRE_PLL_CLK_DIV1_5 0x0 #define RCC_CFGR_USBPRE_PLL_CLK_NODIV 0x1 +/**@}*/ /* OTGFSPRE: USB OTG FS prescaler (RCC_CFGR[22]; only in conn. line STM32s) */ #define RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3 0x0 #define RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV2 0x1 /* PLLMUL: PLL multiplication factor */ +/** @defgroup rcc_cfgr_pmf RCC_CFGR PLL Multiplication Factor +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL2 0x0 /* (XX) */ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL3 0x1 /* (XX) */ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL4 0x2 @@ -98,38 +128,69 @@ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL6_5 0xd /* 0xd: PLL x 6.5 for conn. line */ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL16 0xe /* (XX) */ // #define PLLMUL_PLL_CLK_MUL16 0xf /* (XX) */ /* Errata? 17? */ +/**@}*/ /* TODO: conn. line differs. */ /* PLLXTPRE: HSE divider for PLL entry */ +/** @defgroup rcc_cfgr_hsepre RCC_CFGR HSE Divider for PLL +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_PLLXTPRE_HSE_CLK 0x0 #define RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2 0x1 +/**@}*/ /* PLLSRC: PLL entry clock source */ +/** @defgroup rcc_cfgr_pcs RCC_CFGR PLL Clock Source +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_PLLSRC_HSI_CLK_DIV2 0x0 #define RCC_CFGR_PLLSRC_HSE_CLK 0x1 #define RCC_CFGR_PLLSRC_PREDIV1_CLK 0x1 /* On conn. line */ +/**@}*/ /* ADCPRE: ADC prescaler */ +/****************************************************************************/ +/** @defgroup rcc_cfgr_adcpre RCC ADC Clock Prescaler enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_ADCPRE_PCLK2_DIV2 0x0 #define RCC_CFGR_ADCPRE_PCLK2_DIV4 0x1 #define RCC_CFGR_ADCPRE_PCLK2_DIV6 0x2 #define RCC_CFGR_ADCPRE_PCLK2_DIV8 0x3 +/**@}*/ /* PPRE2: APB high-speed prescaler (APB2) */ +/** @defgroup rcc_cfgr_apb2pre RCC_CFGR APB2 Prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ #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) */ +/** @defgroup rcc_cfgr_apb1pre RCC_CFGR APB1 Prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ #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 */ +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB Prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_HPRE_SYSCLK_NODIV 0x0 #define RCC_CFGR_HPRE_SYSCLK_DIV2 0x8 #define RCC_CFGR_HPRE_SYSCLK_DIV4 0x9 @@ -139,6 +200,7 @@ #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_HSICLK 0x0 @@ -146,9 +208,14 @@ #define RCC_CFGR_SWS_SYSCLKSEL_PLLCLK 0x2 /* SW: System clock switch */ +/** @defgroup rcc_cfgr_scs RCC_CFGR System Clock Selection +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_SW_SYSCLKSEL_HSICLK 0x0 #define RCC_CFGR_SW_SYSCLKSEL_HSECLK 0x1 #define RCC_CFGR_SW_SYSCLKSEL_PLLCLK 0x2 +/**@}*/ /* --- RCC_CIR values ------------------------------------------------------ */ @@ -187,6 +254,10 @@ /* --- RCC_APB2RSTR values ------------------------------------------------- */ +/** @defgroup rcc_apb2rstr_rst RCC_APB2RSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_APB2RSTR_ADC3RST (1 << 15) /* (XX) */ #define RCC_APB2RSTR_USART1RST (1 << 14) #define RCC_APB2RSTR_TIM8RST (1 << 13) /* (XX) */ @@ -202,9 +273,14 @@ #define RCC_APB2RSTR_IOPBRST (1 << 3) #define RCC_APB2RSTR_IOPARST (1 << 2) #define RCC_APB2RSTR_AFIORST (1 << 0) +/**@}*/ /* --- RCC_APB1RSTR values ------------------------------------------------- */ +/** @defgroup rcc_apb1rstr_rst RCC_APB1RSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_APB1RSTR_DACRST (1 << 29) #define RCC_APB1RSTR_PWRRST (1 << 28) #define RCC_APB1RSTR_BKPRST (1 << 27) @@ -227,9 +303,14 @@ #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 STM32F1xx_rcc_defines + +@{*/ #define RCC_AHBENR_ETHMACENRX (1 << 16) #define RCC_AHBENR_ETHMACENTX (1 << 15) #define RCC_AHBENR_ETHMACEN (1 << 14) @@ -241,9 +322,14 @@ #define RCC_AHBENR_SRAMEN (1 << 2) #define RCC_AHBENR_DMA2EN (1 << 1) #define RCC_AHBENR_DMA1EN (1 << 0) +/**@}*/ /* --- RCC_APB2ENR values -------------------------------------------------- */ +/** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_APB2ENR_ADC3EN (1 << 15) /* (XX) */ #define RCC_APB2ENR_USART1EN (1 << 14) #define RCC_APB2ENR_TIM8EN (1 << 13) /* (XX) */ @@ -259,9 +345,14 @@ #define RCC_APB2ENR_IOPBEN (1 << 3) #define RCC_APB2ENR_IOPAEN (1 << 2) #define RCC_APB2ENR_AFIOEN (1 << 0) +/**@}*/ /* --- RCC_APB1ENR values -------------------------------------------------- */ +/** @defgroup rcc_apb1enr_en RCC_APB1ENR enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_APB1ENR_DACEN (1 << 29) #define RCC_APB1ENR_PWREN (1 << 28) #define RCC_APB1ENR_BKPEN (1 << 27) @@ -284,6 +375,7 @@ #define RCC_APB1ENR_TIM4EN (1 << 2) #define RCC_APB1ENR_TIM3EN (1 << 1) #define RCC_APB1ENR_TIM2EN (1 << 0) +/**@}*/ /* --- RCC_BDCR values ----------------------------------------------------- */ @@ -308,8 +400,13 @@ /* --- RCC_AHBRSTR values -------------------------------------------------- */ +/** @defgroup rcc_ahbrstr_rst RCC_AHBRSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_AHBRSTR_ETHMACRST (1 << 14) #define RCC_AHBRSTR_OTGFSRST (1 << 12) +/**@}*/ /* --- RCC_CFGR2 values ---------------------------------------------------- */ @@ -379,6 +476,8 @@ typedef enum { PLL, HSE, HSI, LSE, LSI } osc_t; +BEGIN_DECLS + 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); @@ -408,10 +507,15 @@ 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); +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); +END_DECLS + #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/f1/rtc.h b/include/libopencm3/stm32/f1/rtc.h index 5e203ab9..04aea01d 100644 --- a/include/libopencm3/stm32/f1/rtc.h +++ b/include/libopencm3/stm32/f1/rtc.h @@ -126,6 +126,8 @@ typedef enum { RTC_SEC, RTC_ALR, RTC_OW, } rtcflag_t; +BEGIN_DECLS + void rtc_awake_from_off(osc_t clock_source); void rtc_enter_config_mode(void); void rtc_exit_config_mode(void); @@ -144,4 +146,6 @@ u32 rtc_check_flag(rtcflag_t flag_val); void rtc_awake_from_standby(void); void rtc_auto_awake(osc_t clock_source, u32 prescale_val); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f1/scb.h b/include/libopencm3/stm32/f1/scb.h index 12a74a29..181aa7a0 100644 --- a/include/libopencm3/stm32/f1/scb.h +++ b/include/libopencm3/stm32/f1/scb.h @@ -293,10 +293,15 @@ /* 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/flash.h b/include/libopencm3/stm32/f2/flash.h index 5b4483f7..2c787578 100644 --- a/include/libopencm3/stm32/f2/flash.h +++ b/include/libopencm3/stm32/f2/flash.h @@ -116,6 +116,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void flash_dcache_enable(void); void flash_dcache_disable(void); void flash_icache_enable(void); @@ -145,4 +147,6 @@ void flash_program_byte(u32 address, u8 data, u32 program_size); void flash_wait_for_last_operation(void); void flash_program_option_bytes(u32 data); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f2/gpio.h b/include/libopencm3/stm32/f2/gpio.h index 1a9fd0fb..66167697 100644 --- a/include/libopencm3/stm32/f2/gpio.h +++ b/include/libopencm3/stm32/f2/gpio.h @@ -254,6 +254,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + /* * Note: The F2 series has a completely new GPIO peripheral with different * configuration options. Here we implement a different API partly to more @@ -275,4 +277,6 @@ u16 gpio_port_read(u32 gpioport); void gpio_port_write(u32 gpioport, u16 data); void gpio_port_config_lock(u32 gpioport, u16 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f2/rcc.h b/include/libopencm3/stm32/f2/rcc.h index dfce266c..4ffa2427 100644 --- a/include/libopencm3/stm32/f2/rcc.h +++ b/include/libopencm3/stm32/f2/rcc.h @@ -479,6 +479,8 @@ typedef enum { PLL, HSE, HSI, LSE, LSI } osc_t; +BEGIN_DECLS + 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); @@ -509,4 +511,6 @@ u32 rcc_get_system_clock_source(int i); void rcc_clock_setup_hse_3v3(const clock_scale_t *clock); void rcc_backupdomain_reset(void); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f2/scb.h b/include/libopencm3/stm32/f2/scb.h index 12a74a29..181aa7a0 100644 --- a/include/libopencm3/stm32/f2/scb.h +++ b/include/libopencm3/stm32/f2/scb.h @@ -293,10 +293,15 @@ /* 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/timer.h b/include/libopencm3/stm32/f2/timer.h index 3436bbad..737d6f08 100644 --- a/include/libopencm3/stm32/f2/timer.h +++ b/include/libopencm3/stm32/f2/timer.h @@ -52,6 +52,10 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void timer_set_option(u32 timer_peripheral, u32 option); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/flash.h b/include/libopencm3/stm32/f4/flash.h index f85d56f4..22213334 100644 --- a/include/libopencm3/stm32/f4/flash.h +++ b/include/libopencm3/stm32/f4/flash.h @@ -115,6 +115,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void flash_dcache_enable(void); void flash_dcache_disable(void); void flash_icache_enable(void); @@ -144,4 +146,6 @@ void flash_program_byte(u32 address, u8 data, u32 program_size); void flash_wait_for_last_operation(void); void flash_program_option_bytes(u32 data); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/gpio.h b/include/libopencm3/stm32/f4/gpio.h index a5b4361c..b7da9c6a 100644 --- a/include/libopencm3/stm32/f4/gpio.h +++ b/include/libopencm3/stm32/f4/gpio.h @@ -254,6 +254,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + /* * Note: The F4 series has a completely new GPIO peripheral with different * configuration options. Here we implement a different API partly to more @@ -275,4 +277,6 @@ u16 gpio_port_read(u32 gpioport); void gpio_port_write(u32 gpioport, u16 data); void gpio_port_config_lock(u32 gpioport, u16 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/pwr.h b/include/libopencm3/stm32/f4/pwr.h index ede1ae7e..25fb163c 100644 --- a/include/libopencm3/stm32/f4/pwr.h +++ b/include/libopencm3/stm32/f4/pwr.h @@ -63,6 +63,10 @@ typedef enum { SCALE2, } vos_scale_t; +BEGIN_DECLS + void pwr_set_vos_scale(vos_scale_t scale); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/rcc.h b/include/libopencm3/stm32/f4/rcc.h index 648ccb00..16885841 100644 --- a/include/libopencm3/stm32/f4/rcc.h +++ b/include/libopencm3/stm32/f4/rcc.h @@ -482,6 +482,8 @@ typedef enum { PLL, HSE, HSI, LSE, LSI } osc_t; +BEGIN_DECLS + 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); @@ -512,4 +514,6 @@ u32 rcc_get_system_clock_source(int i); void rcc_clock_setup_hse_3v3(const clock_scale_t *clock); void rcc_backupdomain_reset(void); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/scb.h b/include/libopencm3/stm32/f4/scb.h index 12a74a29..181aa7a0 100644 --- a/include/libopencm3/stm32/f4/scb.h +++ b/include/libopencm3/stm32/f4/scb.h @@ -293,10 +293,15 @@ /* 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/timer.h b/include/libopencm3/stm32/f4/timer.h index 6d19990c..988d02c4 100644 --- a/include/libopencm3/stm32/f4/timer.h +++ b/include/libopencm3/stm32/f4/timer.h @@ -52,6 +52,10 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void timer_set_option(u32 timer_peripheral, u32 option); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/i2c.h b/include/libopencm3/stm32/i2c.h index 1606b643..13257eba 100644 --- a/include/libopencm3/stm32/i2c.h +++ b/include/libopencm3/stm32/i2c.h @@ -316,6 +316,8 @@ /* --- I2C funtion prototypes----------------------------------------------- */ +BEGIN_DECLS + void i2c_reset(u32 i2c); void i2c_peripheral_enable(u32 i2c); void i2c_peripheral_disable(u32 i2c); @@ -331,4 +333,6 @@ void i2c_set_trise(u32 i2c, u16 trise); void i2c_send_7bit_address(u32 i2c, u8 slave, u8 readwrite); void i2c_send_data(u32 i2c, u8 data); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/iwdg.h b/include/libopencm3/stm32/iwdg.h index 2d244824..4e44907d 100644 --- a/include/libopencm3/stm32/iwdg.h +++ b/include/libopencm3/stm32/iwdg.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F_iwdg_defines IWDG Defines + +@brief libopencm3 Defined Constants and Types for the STM32F Independent Watchdog Timer + +@ingroup STM32F_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +31,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_IWDG_H #define LIBOPENCM3_IWDG_H @@ -42,9 +58,14 @@ /* Bits [31:16]: Reserved. */ /* KEY[15:0]: Key value (write-only, reads as 0x0000) */ +/** @defgroup iwdg_key IWDG Key Values +@ingroup STM32F_iwdg_defines + +@{*/ #define IWDG_KR_RESET 0xaaaa #define IWDG_KR_UNLOCK 0x5555 #define IWDG_KR_START 0xcccc +/**@}*/ /* --- IWDG_PR values ------------------------------------------------------ */ @@ -52,6 +73,10 @@ /* PR[2:0]: Prescaler divider */ #define IWDG_PR_LSB 0 +/** @defgroup iwdg_prediv IWDG Prescaler divider +@ingroup STM32F_iwdg_defines + +@{*/ #define IWDG_PR_DIV4 0x0 #define IWDG_PR_DIV8 0x1 #define IWDG_PR_DIV16 0x2 @@ -59,6 +84,7 @@ #define IWDG_PR_DIV64 0x4 #define IWDG_PR_DIV128 0x5 #define IWDG_PR_DIV256 0x6 +/**@}*/ /* Double definition: 0x06 and 0x07 both mean DIV256 as per datasheet. */ /* #define IWDG_PR_DIV256 0x7 */ @@ -78,8 +104,18 @@ /* PVU: Watchdog prescaler value update */ #define IWDG_SR_PVU (1 << 0) -/* --- IWDG funtion prototypes---------------------------------------------- */ +/* --- IWDG function prototypes---------------------------------------------- */ -/* TODO */ +BEGIN_DECLS + +void iwdg_start(void); +void iwdg_set_period_ms(u32 period); +bool iwdg_reload_busy(void); +bool iwdg_prescaler_busy(void); +void iwdg_reset(void); + +END_DECLS #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h index 36a8fe51..694fab88 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/stm32/nvic.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F_nvic_defines NVIC Defines + +@brief libopencm3 STM32F Nested Vectored Interrupt Controller + +@ingroup STM32F_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -16,6 +30,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ +/**@{*/ #ifndef LIBOPENCM3_NVIC_H #define LIBOPENCM3_NVIC_H @@ -65,6 +80,11 @@ /* --- IRQ channel numbers-------------------------------------------------- */ /* Cortex M3 System Interrupts */ +/** @defgroup nvic_sysint Cortex M3 System Interrupts +@ingroup STM32F_nvic_defines + +IRQ numbers -3 and -6 to -9 are reserved +@{*/ #define NVIC_NMI_IRQ -14 #define NVIC_HARD_FAULT_IRQ -13 #define NVIC_MEM_MANAGE_IRQ -12 @@ -76,9 +96,10 @@ /* irq number -3 reserved */ #define NVIC_PENDSV_IRQ -2 #define NVIC_SYSTICK_IRQ -1 +/**@}*/ -/* Note: User interrupts are family specific and are defined in a familiy +/* Note: User interrupts are family specific and are defined in a family * specific header file in the corresponding subfolder. */ @@ -95,6 +116,8 @@ /* --- NVIC functions ------------------------------------------------------ */ +BEGIN_DECLS + void nvic_enable_irq(u8 irqn); void nvic_disable_irq(u8 irqn); u8 nvic_get_pending_irq(u8 irqn); @@ -103,6 +126,10 @@ 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); +void nvic_generate_software_interrupt(u16 irqn); + +END_DECLS #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/pwr.h b/include/libopencm3/stm32/pwr.h index 423ab1af..e709f3d6 100644 --- a/include/libopencm3/stm32/pwr.h +++ b/include/libopencm3/stm32/pwr.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F1xx_pwr_defines PWR Defines + +@ingroup STM32F_defines + +@brief libopencm3 STM32F Power Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 17 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +31,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_PWR_H #define LIBOPENCM3_PWR_H @@ -40,14 +56,20 @@ /* PLS[7:5]: PVD level selection */ #define PWR_CR_PLS_LSB 5 -#define PWR_CR_PLS_2V2 0x0 -#define PWR_CR_PLS_2V3 0x1 -#define PWR_CR_PLS_2V4 0x2 -#define PWR_CR_PLS_2V5 0x3 -#define PWR_CR_PLS_2V6 0x4 -#define PWR_CR_PLS_2V7 0x5 -#define PWR_CR_PLS_2V8 0x6 -#define PWR_CR_PLS_2V9 0x7 +/** @defgroup pwr_pls PVD level selection +@ingroup STM32F_pwr_defines + +@{*/ +#define PWR_CR_PLS_2V2 (0x0 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V3 (0x1 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V4 (0x2 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V5 (0x3 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V6 (0x4 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V7 (0x5 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V8 (0x6 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V9 (0x7 << PWR_CR_PLS_LSB) +/**@}*/ +#define PWR_CR_PLS_MASK (0x7 << PWR_CR_PLS_LSB) /* PVDE: Power voltage detector enable */ #define PWR_CR_PVDE (1 << 4) @@ -84,6 +106,26 @@ /* --- PWR function prototypes ------------------------------------------- */ -/* TODO */ +BEGIN_DECLS + +void pwr_disable_backup_domain_write_protect(void); +void pwr_enable_backup_domain_write_protect(void); +void pwr_enable_power_voltage_detect(u32 pvd_level); +void pwr_disable_power_voltage_detect(void); +void pwr_clear_standby_flag(void); +void pwr_clear_wakeup_flag(void); +void pwr_set_standby_mode(void); +void pwr_set_stop_mode(void); +void pwr_voltage_regulator_on_in_stop(void); +void pwr_voltage_regulator_low_power_in_stop(void); +void pwr_enable_wakeup_pin(void); +void pwr_disable_wakeup_pin(void); +bool pwr_voltage_high(void); +bool pwr_get_standby_flag(void); +bool pwr_get_wakeup_flag(void); + +END_DECLS #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/sdio.h b/include/libopencm3/stm32/sdio.h new file mode 100644 index 00000000..16244ed5 --- /dev/null +++ b/include/libopencm3/stm32/sdio.h @@ -0,0 +1,426 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Felix Held + * + * 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 . + */ + +#ifndef LIBOPENCM3_SDIO_H +#define LIBOPENCM3_SDIO_H + +#include +#include + + +/* --- SDIO registers ------------------------------------------------------ */ + +/* SDIO power control register (SDIO_POWER) */ +#define SDIO_POWER MMIO32(SDIO_BASE + 0x00) + +/* SDI clock control register (SDIO_CLKCR) */ +#define SDIO_CLKCR MMIO32(SDIO_BASE + 0x04) + +/* SDIO argument register (SDIO_ARG) */ +#define SDIO_ARG MMIO32(SDIO_BASE + 0x08) + +/* SDIO command register (SDIO_CMD) */ +#define SDIO_CMD MMIO32(SDIO_BASE + 0x0C) + +/* SDIO command response register (SDIO_RESPCMD) */ +#define SDIO_RESPCMD MMIO32(SDIO_BASE + 0x10) + +/* SDIO response 1..4 register (SDIO_RESPx) */ +#define SDIO_RESP1 MMIO32(SDIO_BASE + 0x14) +#define SDIO_RESP2 MMIO32(SDIO_BASE + 0x18) +#define SDIO_RESP3 MMIO32(SDIO_BASE + 0x1C) +#define SDIO_RESP4 MMIO32(SDIO_BASE + 0x20) + +/* SDIO data timer register (SDIO_DTIMER) */ +#define SDIO_DTIMER MMIO32(SDIO_BASE + 0x24) + +/* SDIO data length register (SDIO_DLEN) */ +#define SDIO_DLEN MMIO32(SDIO_BASE + 0x28) + +/* SDIO data control register (SDIO_DCTRL) */ +#define SDIO_DCTRL MMIO32(SDIO_BASE + 0x2C) + +/* SDIO data counter register (SDIO_DCOUNT) */ +/* read only, write has no effect */ +#define SDIO_DCOUNT MMIO32(SDIO_BASE + 0x30) + +/* SDIO status register (SDIO_STA) */ +#define SDIO_STA MMIO32(SDIO_BASE + 0x34) + +/* SDIO interrupt clear register (SDIO_ICR) */ +#define SDIO_ICR MMIO32(SDIO_BASE + 0x38) + +/* SDIO mask register (SDIO_MASK) */ +#define SDIO_MASK MMIO32(SDIO_BASE + 0x3C) + +/* SDIO FIFO counter register (SDIO_FIFOCNT) */ +#define SDIO_FIFOCNT MMIO32(SDIO_BASE + 0x48) + +/* SDIO data FIFO register (SDIO_FIFO) */ +/* the SDIO data FIFO is 32 32bit words long, beginning at this address */ +#define SDIO_FIFO MMIO32(SDIO_BASE + 0x80) + + +/* --- SDIO_POWER values --------------------------------------------------- */ + +#define SDIO_POWER_PWRCTRL_SHIFT 0 +#define SDIO_POWER_PWRCTRL_PWROFF (0x0 << SDIO_POWER_PWRCTRL_SHIFT) +/* what does "10: Reserved power-up" mean? */ +#define SDIO_POWER_PWRCTRL_RSVPWRUP (0x2 << SDIO_POWER_PWRCTRL_SHIFT) +#define SDIO_POWER_PWRCTRL_PWRON (0x3 << SDIO_POWER_PWRCTRL_SHIFT) + + +/* --- SDIO_POWER values --------------------------------------------------- */ + +/* HWFC_EN: HW Flow Control enable */ +#define SDIO_CLKCR_HWFC_EN (1 << 14) + +/* NEGEDGE: SDIO_CK dephasing selection bit */ +#define SDIO_CLKCR_NEGEDGE (1 << 13) + +/* WIDBUS: Wide bus mode enable bit */ +/* set the width of the data bus */ +#define SDIO_CLKCR_WIDBUS_SHIFT 11 +#define SDIO_CLKCR_WIDBUS_1 (0x0 << SDIO_CLKCR_WIDBUS_SHIFT) +#define SDIO_CLKCR_WIDBUS_4 (0x1 << SDIO_CLKCR_WIDBUS_SHIFT) +#define SDIO_CLKCR_WIDBUS_8 (0x2 << SDIO_CLKCR_WIDBUS_SHIFT) + +/* BYPASS: Clock divider bypass enable bit */ +#define SDIO_CLKCR_BYPASS (1 << 10) + +/* PWRSAV: Power saving configuration bit */ +#define SDIO_CLKCR_PWRSAV (1 << 9) + +/* CLKEN: Clock enable bit */ +#define SDIO_CLKCR_CLKEN (1 << 8) + +/* CLKDIV: Clock divide factor */ +#define SDIO_CLKCR_CLKDIV_SHIFT 0 +#define SDIO_CLKCR_CLKDIV_MSK (0xFF << SDIO_CLKCR_CLKDIV_SHIFT) + + +/* --- SDIO_CMD values ---------------------------------------------------- */ + +/* ATACMD: CE-ATA command */ +#define SDIO_CMD_ATACMD (1 << 14) + +/* nIEN: not Interrupt Enable */ +#define SDIO_CMD_NIEN (1 << 13) + +/* ENCMDcompl: Enable CMD completion */ +#define SDIO_CMD_ENCMDCOMPL (1 << 12) + +/* SDIOSuspend: SD I/O suspend command */ +#define SDIO_CMD_SDIOSUSPEND (1 << 11) + +/* CPSMEN: Command path state machine (CPSM) Enable bit */ +#define SDIO_CMD_CPSMEN (1 << 10) + +/* WAITPEND: CPSM Waits for ends of data transfer (CmdPend internal signal) */ +#define SDIO_CMD_WAITPEND (1 << 9) + +/* WAITINT: CPSM waits for interrupt request */ +#define SDIO_CMD_WAITINT (1 << 8) + +/* WAITRESP: Wait for response bits */ +#define SDIO_CMD_WAITRESP_SHIFT 6 +/* 00: No response, expect CMDSENT flag */ +#define SDIO_CMD_WAITRESP_NO_0 (0x0 << SDIO_CMD_WAITRESP_SHIFT) +/* 01: Short response, expect CMDREND or CCRCFAIL flag */ +#define SDIO_CMD_WAITRESP_SHORT (0x1 << SDIO_CMD_WAITRESP_SHIFT) +/* 10: No response, expect CMDSENT flag */ +#define SDIO_CMD_WAITRESP_NO_2 (0x2 << SDIO_CMD_WAITRESP_SHIFT) +/* 11: Long response, expect CMDREND or CCRCFAIL flag */ +#define SDIO_CMD_WAITRESP_LONG (0x3 << SDIO_CMD_WAITRESP_SHIFT) + +/* CMDINDEX: Command index */ +#define SDIO_CMD_CMDINDEX_SHIFT 0 +#define SDIO_CMD_CMDINDEX_MSK (0x3F << SDIO_CMD_CMDINDEX_SHIFT) + + +/* --- SDIO_RESPCMD values ------------------------------------------------ */ + +#define SDIO_RESPCMD_SHIFT 0 +#define SDIO_RESPCMD_MSK (0x3F << SDIO_RESPCMD_SHIFT) + + +/* --- SDIO_DCTRL values -------------------------------------------------- */ + +/* SDIOEN: SD I/O enable functions */ +#define SDIO_DCTRL_SDIOEN (1 << 11) + +/* RWMOD: Read wait mode */ +/* 0: Read Wait control stopping SDIO_D2 + * 1: Read Wait control using SDIO_CK + */ +#define SDIO_DCTRL_RWMOD (1 << 10) + +/* RWSTOP: Read wait stop */ +/* 0: Read wait in progress if RWSTART bit is set + * 1: Enable for read wait stop if RWSTART bit is set + */ +#define SDIO_DCTRL_RWSTOP (1 << 9) + +/* RWSTART: Read wait start */ +#define SDIO_DCTRL_RWSTART (1 << 8) + +/* DBLOCKSIZE: Data block size */ +/* SDIO_DCTRL_DBLOCKSIZE_n + * blocksize is 2**n bytes with 0<=n<=14 + */ +#define SDIO_DCTRL_DBLOCKSIZE_SHIFT 4 +#define SDIO_DCTRL_DBLOCKSIZE_0 (0x0 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_1 (0x1 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_2 (0x2 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_3 (0x3 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_4 (0x4 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_5 (0x5 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_6 (0x6 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_7 (0x7 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_8 (0x8 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_9 (0x9 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_10 (0xA << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_11 (0xB << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_12 (0xC << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_13 (0xD << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_14 (0xE << SDIO_DCTRL_DBLOCKSIZE_SHIFT) + +/* DMAEN: DMA enable bit */ +#define SDIO_DCTRL_DMAEN (1 << 3) + +/* DTMODE: Data transfer mode selection 1: Stream or SDIO multibyte transfer */ +#define SDIO_DCTRL_DTMODE (1 << 2) + +/* DTDIR: Data transfer direction selection */ +/* 0: From controller to card. + * 1: From card to controller. + */ +#define SDIO_DCTRL_DTDIR (1 << 1) + +/* DTEN: Data transfer enabled bit */ +#define SDIO_DCTRL_DTEN (1 << 0) + + +/* --- SDIO_STA values ---------------------------------------------------- */ + +/* CEATAEND: CE-ATA command completion signal received for CMD61 */ +#define SDIO_STA_CEATAEND (1 << 23) + +/* SDIOIT: SDIO interrupt received */ +#define SDIO_STA_SDIOIT (1 << 22) + +/* RXDAVL: Data available in receive FIFO */ +#define SDIO_STA_RXDAVL (1 << 21) + +/* TXDAVL: Data available in transmit FIFO */ +#define SDIO_STA_TXDAVL (1 << 20) + +/* RXFIFOE: Receive FIFO empty */ +#define SDIO_STA_RXFIFOE (1 << 19) + +/* TXFIFOE: Transmit FIFO empty */ +/* HW Flow Control enabled -> TXFIFOE signals becomes activated when the FIFO + * contains 2 words. + */ +#define SDIO_STA_TXFIFOE (1 << 18) + +/* RXFIFOF: Receive FIFO full */ +/* HW Flow Control enabled => RXFIFOF signals becomes activated 2 words before + * the FIFO is full. + */ +#define SDIO_STA_RXFIFOF (1 << 17) + +/* TXFIFOF: Transmit FIFO full */ +#define SDIO_STA_TXFIFOF (1 << 16) + +/* RXFIFOHF: Receive FIFO half full: there are at least 8 words in the FIFO */ +#define SDIO_STA_RXFIFOHF (1 << 15) + +/* TXFIFOHE: Transmit FIFO half empty: at least 8 words can be written into + * the FIFO + */ +#define SDIO_STA_TXFIFOHE (1 << 14) + +/* RXACT: Data receive in progress */ +#define SDIO_STA_RXACT (1 << 13) + +/* TXACT: Data transmit in progress */ +#define SDIO_STA_TXACT (1 << 12) + +/* CMDACT: Command transfer in progress */ +#define SDIO_STA_CMDACT (1 << 11) + +/* DBCKEND: Data block sent/received (CRC check passed) */ +#define SDIO_STA_DBCKEND (1 << 10) + +/* STBITERR: Start bit not detected on all data signals in wide bus mode */ +#define SDIO_STA_STBITERR (1 << 9) + +/* DATAEND: Data end (data counter, SDIDCOUNT, is zero) */ +#define SDIO_STA_DATAEND (1 << 8) + +/* CMDSENT: Command sent (no response required) */ +#define SDIO_STA_CMDSENT (1 << 7) + +/* CMDREND: Command response received (CRC check passed) */ +#define SDIO_STA_CMDREND (1 << 6) + +/* RXOVERR: Received FIFO overrun error */ +#define SDIO_STA_RXOVERR (1 << 5) + +/* TXUNDERR: Transmit FIFO underrun error */ +#define SDIO_STA_TXUNDERR (1 << 4) + +/* DTIMEOUT: Data timeout */ +#define SDIO_STA_DTIMEOUT (1 << 3) + +/* CTIMEOUT: Command response timeout */ +#define SDIO_STA_CTIMEOUT (1 << 2) + +/* DCRCFAIL: Data block sent/received (CRC check failed) */ +#define SDIO_STA_DCRCFAIL (1 << 1) + +/* CCRCFAIL: Command response received (CRC check failed) */ +#define SDIO_STA_CCRCFAIL (1 << 0) + + +/* --- SDIO_ICR values ---------------------------------------------------- */ + +/* CEATAENDC: CEATAEND flag clear bit */ +#define SDIO_ICR_CEATAENDC (1 << 23) + +/* SDIOITC: SDIOIT flag clear bit */ +#define SDIO_ICR_SDIOITC (1 << 22) + +/* DBCKENDC: DBCKEND flag clear bit */ +#define SDIO_ICR_DBCKENDC (1 << 10) + +/* STBITERRC: STBITERR flag clear bit */ +#define SDIO_ICR_STBITERRC (1 << 9) + +/* DATAENDC: DATAEND flag clear bit */ +#define SDIO_ICR_DATAENDC (1 << 8) + +/* CMDSENTC: CMDSENT flag clear bit */ +#define SDIO_ICR_CMDSENTC (1 << 7) + +/* CMDRENDC: CMDREND flag clear bit */ +#define SDIO_ICR_CMDRENDC (1 << 6) + +/* RXOVERRC: RXOVERR flag clear bit */ +#define SDIO_ICR_RXOVERRC (1 << 5) + +/* TXUNDERRC: TXUNDERR flag clear bit */ +#define SDIO_ICR_TXUNDERRC (1 << 4) + +/* DTIMEOUTC: DTIMEOUT flag clear bit */ +#define SDIO_ICR_DTIMEOUTC (1 << 3) + +/* CTIMEOUTC: CTIMEOUT flag clear bit */ +#define SDIO_ICR_CTIMEOUTC (1 << 2) + +/* DCRCFAILC: DCRCFAIL flag clear bit */ +#define SDIO_ICR_DCRCFAILC (1 << 1) + +/* CCRCFAILC: CCRCFAIL flag clear bit */ +#define SDIO_ICR_CCRCFAILC (1 << 0) + + +/* --- SDIO_MASK values --------------------------------------------------- */ + +/* CEATAENDIE: CE-ATA command completion signal received interrupt enable */ +#define SDIO_MASK_CEATAENDIE (1 << 23) + +/* SDIOITIE: SDIO mode interrupt received interrupt enable */ +#define SDIO_MASK_SDIOITIE (1 << 22) + +/* RXDAVLIE: Data available in Rx FIFO interrupt enable */ +#define SDIO_MASK_RXDAVLIE (1 << 21) + +/* TXDAVLIE: Data available in Tx FIFO interrupt enable */ +#define SDIO_MASK_TXDAVLIE (1 << 20) + +/* RXFIFOEIE: Rx FIFO empty interrupt enable */ +#define SDIO_MASK_RXFIFOEIE (1 << 19) + +/* TXFIFOEIE: Tx FIFO empty interrupt enable */ +#define SDIO_MASK_TXFIFOEIE (1 << 18) + +/* RXFIFOFIE: Rx FIFO full interrupt enable */ +#define SDIO_MASK_RXFIFOFIE (1 << 17) + +/* TXFIFOFIE: Tx FIFO full interrupt enable */ +#define SDIO_MASK_TXFIFOFIE (1 << 16) + +/* RXFIFOHFIE: Rx FIFO half full interrupt enable */ +#define SDIO_MASK_RXFIFOHFIE (1 << 15) + +/* TXFIFOHEIE: Tx FIFO half empty interrupt enable */ +#define SDIO_MASK_TXFIFOHEIE (1 << 14) + +/* RXACTIE: Data receive acting interrupt enable */ +#define SDIO_MASK_RXACTIE (1 << 13) + +/* TXACTIE: Data transmit acting interrupt enable */ +#define SDIO_MASK_TXACTIE (1 << 12) + +/* CMDACTIE: Command acting interrupt enable */ +#define SDIO_MASK_CMDACTIE (1 << 11) + +/* DBCKENDIE: Data block end interrupt enable */ +#define SDIO_MASK_DBCKENDIE (1 << 10) + +/* STBITERRIE: Start bit error interrupt enable */ +#define SDIO_MASK_STBITERRIE (1 << 9) + +/* DATAENDIE: Data end interrupt enable */ +#define SDIO_MASK_DATAENDIE (1 << 8) + +/* CMDSENTIE: Command sent interrupt enable */ +#define SDIO_MASK_CMDSENTIE (1 << 7) + +/* CMDRENDIE: Command response received interrupt enable */ +#define SDIO_MASK_CMDRENDIE (1 << 6) + +/* RXOVERRIE: Rx FIFO overrun error interrupt enable */ +#define SDIO_MASK_RXOVERRIE (1 << 5) + +/* TXUNDERRIE: Tx FIFO underrun error interrupt enable */ +#define SDIO_MASK_TXUNDERRIE (1 << 4) + +/* DTIMEOUTIE: Data timeout interrupt enable */ +#define SDIO_MASK_DTIMEOUTIE (1 << 3) + +/* CTIMEOUTIE: Command timeout interrupt enable */ +#define SDIO_MASK_CTIMEOUTIE (1 << 2) + +/* DCRCFAILIE: Data CRC fail interrupt enable */ +#define SDIO_MASK_DCRCFAILIE (1 << 1) + +/* CCRCFAILIE: Command CRC fail interrupt enable */ +#define SDIO_MASK_CCRCFAILIE (1 << 0) + + +/* --- Function prototypes ------------------------------------------------- */ + + +/* TODO */ + + +#endif diff --git a/include/libopencm3/stm32/spi.h b/include/libopencm3/stm32/spi.h index e64dd0fc..11ba8206 100644 --- a/include/libopencm3/stm32/spi.h +++ b/include/libopencm3/stm32/spi.h @@ -297,6 +297,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void spi_reset(u32 spi_peripheral); int spi_init_master(u32 spi, u32 br, u32 cpol, u32 cpha, u32 dff, u32 lsbfirst); void spi_enable(u32 spi); @@ -343,4 +345,6 @@ void spi_disable_tx_dma(u32 spi); void spi_enable_rx_dma(u32 spi); void spi_disable_rx_dma(u32 spi); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/systick.h b/include/libopencm3/stm32/systick.h index 376bea07..e42c4e6f 100644 --- a/include/libopencm3/stm32/systick.h +++ b/include/libopencm3/stm32/systick.h @@ -1,3 +1,18 @@ +/** @defgroup STM32F_systick_defines SysTick Defines + +@brief libopencm3 Defined Constants and Types for the STM32F SysTick + +@ingroup STM32F_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 19 August 2012 + +LGPL License Terms @ref lgpl_license + */ + /* * This file is part of the libopencm3 project. * @@ -17,6 +32,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_SYSTICK_H #define LIBOPENCM3_SYSTICK_H @@ -45,8 +62,14 @@ /* CLKSOURCE: Clock source selection */ #define STK_CTRL_CLKSOURCE (1 << 2) #define STK_CTRL_CLKSOURCE_LSB 2 +/** @defgroup systick_clksource Clock source selection +@ingroup STM32F_systick_defines + +@{*/ #define STK_CTRL_CLKSOURCE_AHB_DIV8 0 #define STK_CTRL_CLKSOURCE_AHB 1 +/**@}*/ + /* TICKINT: SysTick exception request enable */ #define STK_CTRL_TICKINT (1 << 1) /* ENABLE: Counter enable */ @@ -70,6 +93,8 @@ /* --- Function Prototypes ------------------------------------------------- */ +BEGIN_DECLS + void systick_set_reload(u32 value); u32 systick_get_value(void); void systick_set_clocksource(u8 clocksource); @@ -79,4 +104,8 @@ void systick_counter_enable(void); void systick_counter_disable(void); u8 systick_get_countflag(void); +END_DECLS + #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/timer.h b/include/libopencm3/stm32/timer.h index 3c8c8c2c..b6f89497 100644 --- a/include/libopencm3/stm32/timer.h +++ b/include/libopencm3/stm32/timer.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F_tim_defines Timers Defines + +@brief libopencm3 Defined Constants and Types for the STM32F1xx Timers + +@ingroup STM32F_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Piotr Esden-Tempski + +@date 18 May 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +31,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_TIMER_H #define LIBOPENCM3_TIMER_H @@ -26,6 +42,11 @@ /* --- Convenience macros -------------------------------------------------- */ /* Timer register base adresses (for convenience) */ +/****************************************************************************/ +/** @defgroup tim_reg_base Timer register base addresses +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM1 TIM1_BASE #define TIM2 TIM2_BASE #define TIM3 TIM3_BASE @@ -34,6 +55,7 @@ #define TIM6 TIM6_BASE #define TIM7 TIM7_BASE #define TIM8 TIM8_BASE +/**@}*/ /* --- Timer registers ----------------------------------------------------- */ @@ -227,25 +249,43 @@ /* --- TIMx_CR1 values ----------------------------------------------------- */ +/****************************************************************************/ +/** @defgroup tim_x_cr1_cdr TIMx_CR1 CKD[1:0] Clock Division Ratio +@ingroup STM32F1xx_tim_defines + +@{*/ /* CKD[1:0]: Clock division */ #define TIM_CR1_CKD_CK_INT (0x0 << 8) #define TIM_CR1_CKD_CK_INT_MUL_2 (0x1 << 8) #define TIM_CR1_CKD_CK_INT_MUL_4 (0x2 << 8) #define TIM_CR1_CKD_CK_INT_MASK (0x3 << 8) +/**@}*/ /* ARPE: Auto-reload preload enable */ #define TIM_CR1_ARPE (1 << 7) /* CMS[1:0]: Center-aligned mode selection */ +/****************************************************************************/ +/** @defgroup tim_x_cr1_cms TIMx_CR1 CMS[1:0]: Center-aligned Mode Selection +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM_CR1_CMS_EDGE (0x0 << 5) #define TIM_CR1_CMS_CENTER_1 (0x1 << 5) #define TIM_CR1_CMS_CENTER_2 (0x2 << 5) #define TIM_CR1_CMS_CENTER_3 (0x3 << 5) #define TIM_CR1_CMS_MASK (0x3 << 5) +/**@}*/ /* DIR: Direction */ +/****************************************************************************/ +/** @defgroup tim_x_cr1_dir TIMx_CR1 DIR: Direction +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM_CR1_DIR_UP (0 << 4) #define TIM_CR1_DIR_DOWN (1 << 4) +/**@}*/ /* OPM: One pulse mode */ #define TIM_CR1_OPM (1 << 3) @@ -261,32 +301,43 @@ /* --- TIMx_CR2 values ----------------------------------------------------- */ -/* OIS4: Output idle state 4 (OC4 output) */ +/****************************************************************************/ +/** @defgroup tim_x_cr2_ois TIMx_CR2_OIS: Force Output Idle State Control Values +@ingroup STM32F1xx_tim_defines + +@{*/ +/* OIS4:*//** Output idle state 4 (OC4 output) */ #define TIM_CR2_OIS4 (1 << 14) -/* OIS3N: Output idle state 3 (OC3N output) */ +/* OIS3N:*//** Output idle state 3 (OC3N output) */ #define TIM_CR2_OIS3N (1 << 13) -/* OIS3: Output idle state 3 (OC3 output) */ +/* OIS3:*//** Output idle state 3 (OC3 output) */ #define TIM_CR2_OIS3 (1 << 12) -/* OIS2N: Output idle state 2 (OC2N output) */ +/* OIS2N:*//** Output idle state 2 (OC2N output) */ #define TIM_CR2_OIS2N (1 << 11) -/* OIS2: Output idle state 2 (OC2 output) */ +/* OIS2:*//** Output idle state 2 (OC2 output) */ #define TIM_CR2_OIS2 (1 << 10) -/* OIS1N: Output idle state 1 (OC1N output) */ +/* OIS1N:*//** Output idle state 1 (OC1N output) */ #define TIM_CR2_OIS1N (1 << 9) -/* OIS1: Output idle state 1 (OC1 output) */ +/* OIS1:*//** Output idle state 1 (OC1 output) */ #define TIM_CR2_OIS1 (1 << 8) #define TIM_CR2_OIS_MASK (0x7f << 8) +/**@}*/ /* TI1S: TI1 selection */ #define TIM_CR2_TI1S (1 << 7) /* MMS[2:0]: Master mode selection */ +/****************************************************************************/ +/** @defgroup tim_mastermode TIMx_CR2 MMS[6:4]: Master Mode Selection +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM_CR2_MMS_RESET (0x0 << 4) #define TIM_CR2_MMS_ENABLE (0x1 << 4) #define TIM_CR2_MMS_UPDATE (0x2 << 4) @@ -296,6 +347,7 @@ #define TIM_CR2_MMS_COMPARE_OC3REF (0x6 << 4) #define TIM_CR2_MMS_COMPARE_OC4REF (0x7 << 4) #define TIM_CR2_MMS_MASK (0x7 << 4) +/**@}*/ /* CCDS: Capture/compare DMA selection */ #define TIM_CR2_CCDS (1 << 3) @@ -344,137 +396,186 @@ #define TIM_SMCR_MSM (1 << 7) /* TS[2:0]: Trigger selection */ +/** @defgroup tim_ts TS Trigger selection +@ingroup STM32F1xx_tim_defines + +@{*/ +/** Internal Trigger 0 (ITR0) */ #define TIM_SMCR_TS_ITR0 (0x0 << 4) +/** Internal Trigger 1 (ITR1) */ #define TIM_SMCR_TS_ITR1 (0x1 << 4) +/** Internal Trigger 2 (ITR2) */ #define TIM_SMCR_TS_ITR2 (0x2 << 4) +/** Internal Trigger 3 (ITR3) */ #define TIM_SMCR_TS_ITR3 (0x3 << 4) +/** TI1 Edge Detector (TI1F_ED) */ #define TIM_SMCR_TS_IT1F_ED (0x4 << 4) +/** Filtered Timer Input 1 (TI1FP1) */ #define TIM_SMCR_TS_IT1FP1 (0x5 << 4) +/** Filtered Timer Input 2 (TI1FP2) */ #define TIM_SMCR_TS_IT1FP2 (0x6 << 4) +/** External Trigger input (ETRF) */ #define TIM_SMCR_TS_ETRF (0x7 << 4) #define TIM_SMCR_TS_MASK (0x7 << 4) +/**@}*/ /* SMS[2:0]: Slave mode selection */ +/** @defgroup tim_sms SMS Slave mode selection +@ingroup STM32F1xx_tim_defines + +@{*/ +/** Slave mode disabled */ #define TIM_SMCR_SMS_OFF (0x0 << 0) +/** Encoder mode 1 - Counter counts up/down on TI2FP2 edge depending on TI1FP1 +level. */ #define TIM_SMCR_SMS_EM1 (0x1 << 0) +/** Encoder mode 2 - Counter counts up/down on TI1FP1 edge depending on TI2FP2 +level. */ #define TIM_SMCR_SMS_EM2 (0x2 << 0) +/** Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges +depending on the level of the complementary input. */ #define TIM_SMCR_SMS_EM3 (0x3 << 0) +/** Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter +and generates an update of the registers. */ #define TIM_SMCR_SMS_RM (0x4 << 0) +/** Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. */ #define TIM_SMCR_SMS_GM (0x5 << 0) +/** Trigger Mode - The counter starts at a rising edge of the trigger TRGI. */ #define TIM_SMCR_SMS_TM (0x6 << 0) +/** External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. */ #define TIM_SMCR_SMS_ECM1 (0x7 << 0) #define TIM_SMCR_SMS_MASK (0x7 << 0) +/**@}*/ /* --- TIMx_DIER values ---------------------------------------------------- */ -/* TDE: Trigger DMA request enable */ +/****************************************************************************/ +/** @defgroup tim_irq_enable TIMx_DIER Timer DMA and Interrupt Enable Values +@ingroup STM32F1xx_tim_defines + +@{*/ +/* TDE:*//** Trigger DMA request enable */ #define TIM_DIER_TDE (1 << 14) -/* COMDE: COM DMA request enable */ +/* COMDE:*//** COM DMA request enable */ #define TIM_DIER_COMDE (1 << 13) -/* CC4DE: Capture/Compare 4 DMA request enable */ +/* CC4DE:*//** Capture/Compare 4 DMA request enable */ #define TIM_DIER_CC4DE (1 << 12) -/* CC3DE: Capture/Compare 3 DMA request enable */ +/* CC3DE:*//** Capture/Compare 3 DMA request enable */ #define TIM_DIER_CC3DE (1 << 11) -/* CC2DE: Capture/Compare 2 DMA request enable */ +/* CC2DE:*//** Capture/Compare 2 DMA request enable */ #define TIM_DIER_CC2DE (1 << 10) -/* CC1DE: Capture/Compare 1 DMA request enable */ +/* CC1DE:*//** Capture/Compare 1 DMA request enable */ #define TIM_DIER_CC1DE (1 << 9) -/* UDE: Update DMA request enable */ +/* UDE*//**: Update DMA request enable */ #define TIM_DIER_UDE (1 << 8) -/* BIE: Break interrupt enable */ +/* BIE:*//** Break interrupt enable */ #define TIM_DIER_BIE (1 << 7) -/* TIE: Trigger interrupt enable */ +/* TIE:*//** Trigger interrupt enable */ #define TIM_DIER_TIE (1 << 6) -/* COMIE: COM interrupt enable */ +/* COMIE:*//** COM interrupt enable */ #define TIM_DIER_COMIE (1 << 5) -/* CC4IE: Capture/compare 4 interrupt enable */ +/* CC4IE:*//** Capture/compare 4 interrupt enable */ #define TIM_DIER_CC4IE (1 << 4) -/* CC3IE: Capture/compare 3 interrupt enable */ +/* CC3IE:*//** Capture/compare 3 interrupt enable */ #define TIM_DIER_CC3IE (1 << 3) -/* CC2IE: Capture/compare 2 interrupt enable */ +/* CC2IE:*//** Capture/compare 2 interrupt enable */ #define TIM_DIER_CC2IE (1 << 2) -/* CC1IE: Capture/compare 1 interrupt enable */ +/* CC1IE:*//** Capture/compare 1 interrupt enable */ #define TIM_DIER_CC1IE (1 << 1) -/* UIE: Update interrupt enable */ +/* UIE:*//** Update interrupt enable */ #define TIM_DIER_UIE (1 << 0) +/**@}*/ /* --- TIMx_SR values ------------------------------------------------------ */ +/****************************************************************************/ +/** @defgroup tim_sr_values TIMx_SR Timer Status Register Flags +@ingroup STM32F1xx_tim_defines -/* CC4OF: Capture/compare 4 overcapture flag */ +@{*/ + +/* CC4OF:*//** Capture/compare 4 overcapture flag */ #define TIM_SR_CC4OF (1 << 12) -/* CC3OF: Capture/compare 3 overcapture flag */ +/* CC3OF:*//** Capture/compare 3 overcapture flag */ #define TIM_SR_CC3OF (1 << 11) -/* CC2OF: Capture/compare 2 overcapture flag */ +/* CC2OF:*//** Capture/compare 2 overcapture flag */ #define TIM_SR_CC2OF (1 << 10) -/* CC1OF: Capture/compare 1 overcapture flag */ +/* CC1OF:*//** Capture/compare 1 overcapture flag */ #define TIM_SR_CC1OF (1 << 9) -/* BIF: Break interrupt flag */ +/* BIF:*//** Break interrupt flag */ #define TIM_SR_BIF (1 << 7) -/* TIF: Trigger interrupt flag */ +/* TIF:*//** Trigger interrupt flag */ #define TIM_SR_TIF (1 << 6) -/* COMIF: COM interrupt flag */ +/* COMIF:*//** COM interrupt flag */ #define TIM_SR_COMIF (1 << 5) -/* CC4IF: Capture/compare 4 interrupt flag */ +/* CC4IF:*//** Capture/compare 4 interrupt flag */ #define TIM_SR_CC4IF (1 << 4) -/* CC3IF: Capture/compare 3 interrupt flag */ +/* CC3IF:*//** Capture/compare 3 interrupt flag */ #define TIM_SR_CC3IF (1 << 3) -/* CC2IF: Capture/compare 2 interrupt flag */ +/* CC2IF:*//** Capture/compare 2 interrupt flag */ #define TIM_SR_CC2IF (1 << 2) -/* CC1IF: Capture/compare 1 interrupt flag */ +/* CC1IF:*//** Capture/compare 1 interrupt flag */ #define TIM_SR_CC1IF (1 << 1) -/* UIF: Update interrupt flag */ +/* UIF:*//** Update interrupt flag */ #define TIM_SR_UIF (1 << 0) +/**@}*/ /* --- TIMx_EGR values ----------------------------------------------------- */ -/* BG: Break generation */ +/****************************************************************************/ +/** @defgroup tim_event_gen TIMx_EGR Timer Event Generator Values +@ingroup STM32F1xx_tim_defines + +@{*/ + +/* BG:*//** Break generation */ #define TIM_EGR_BG (1 << 7) -/* TG: Trigger generation */ +/* TG:*//** Trigger generation */ #define TIM_EGR_TG (1 << 6) -/* COMG: Capture/compare control update generation */ +/* COMG:*//** Capture/compare control update generation */ #define TIM_EGR_COMG (1 << 5) -/* CC4G: Capture/compare 4 generation */ +/* CC4G:*//** Capture/compare 4 generation */ #define TIM_EGR_CC4G (1 << 4) -/* CC3G: Capture/compare 3 generation */ +/* CC3G:*//** Capture/compare 3 generation */ #define TIM_EGR_CC3G (1 << 3) -/* CC2G: Capture/compare 2 generation */ +/* CC2G:*//** Capture/compare 2 generation */ #define TIM_EGR_CC2G (1 << 2) -/* CC1G: Capture/compare 1 generation */ +/* CC1G:*//** Capture/compare 1 generation */ #define TIM_EGR_CC1G (1 << 1) -/* UG: Update generation */ +/* UG:*//** Update generation */ #define TIM_EGR_UG (1 << 0) +/**@}*/ /* --- TIMx_CCMR1 values --------------------------------------------------- */ @@ -805,11 +906,17 @@ #define TIM_BDTR_OSSI (1 << 10) /* LOCK[1:0]: Lock configuration */ +/****************************************************************************/ +/** @defgroup tim_lock TIM_BDTR_LOCK Timer Lock Values +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM_BDTR_LOCK_OFF (0x0 << 8) #define TIM_BDTR_LOCK_LEVEL_1 (0x1 << 8) #define TIM_BDTR_LOCK_LEVEL_2 (0x2 << 8) #define TIM_BDTR_LOCK_LEVEL_3 (0x3 << 8) #define TIM_BDTR_LOCK_MASK (0x3 << 8) +/**@}*/ /* DTG[7:0]: Dead-time generator set-up */ #define TIM_BDTR_DTG_MASK 0x00FF @@ -828,7 +935,7 @@ /* --- TIMx convenience defines -------------------------------------------- */ -/* Output Compare channel designators */ +/** Output Compare channel designators */ enum tim_oc_id { TIM_OC1=0, TIM_OC1N, @@ -839,7 +946,7 @@ enum tim_oc_id { TIM_OC4, }; -/* Output Compare mode designators */ +/** Output Compare mode designators */ enum tim_oc_mode { TIM_OCM_FROZEN, TIM_OCM_ACTIVE, @@ -851,7 +958,7 @@ enum tim_oc_mode { TIM_OCM_PWM2, }; -/* Input Capture channel designators */ +/** Input Capture channel designators */ enum tim_ic_id { TIM_IC1, TIM_IC2, @@ -859,7 +966,13 @@ enum tim_ic_id { TIM_IC4, }; -/* Input Capture input filter */ +/** Input Capture input filter. The frequency used to sample the +input and the number of events needed to validate an output transition. + +TIM_IC_CK_INT_N_x No division from the Deadtime and Sampling Clock frequency (DTF), +filter length x +TIM_IC_DTF_DIV_y_N_x Division by y from the DTF, filter length x + */ enum tim_ic_filter { TIM_IC_OFF, TIM_IC_CK_INT_N_2, @@ -879,7 +992,9 @@ enum tim_ic_filter { TIM_IC_DTF_DIV_32_N_8, }; -/* Input Capture input prescaler */ +/** Input Capture input prescaler. + +TIM_IC_PSC_x Input capture is done every x events*/ enum tim_ic_psc { TIM_IC_PSC_OFF, TIM_IC_PSC_2, @@ -887,7 +1002,10 @@ enum tim_ic_psc { TIM_IC_PSC_8, }; -/* Input Capture input prescaler */ +/** Input Capture input source. + +The direction of the channel (input/output) as well as the input used. + */ enum tim_ic_input { TIM_IC_OUT = 0, TIM_IC_IN_TI1 = 1, @@ -897,13 +1015,16 @@ enum tim_ic_input { TIM_IC_IN_TI4 = 6, }; -/* Input Capture input prescaler */ +/** Input Capture input polarity */ enum tim_ic_pol { TIM_IC_RISING, TIM_IC_FALLING, }; -/* --- TIM functions ------------------------------------------------------- */ +/* --- TIM function prototypes ------------------------------------------------------- */ + +BEGIN_DECLS + void timer_reset(u32 timer_peripheral); void timer_enable_irq(u32 timer_peripheral, u32 irq); void timer_disable_irq(u32 timer_peripheral, u32 irq); @@ -983,4 +1104,8 @@ void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol); void timer_slave_set_mode(u32 timer, u8 mode); void timer_slave_set_trigger(u32 timer, u8 trigger); +END_DECLS + #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/usart.h b/include/libopencm3/stm32/usart.h index d9f2c8d8..9ec6c3db 100644 --- a/include/libopencm3/stm32/usart.h +++ b/include/libopencm3/stm32/usart.h @@ -270,8 +270,8 @@ /* CR1_PCE / CR1_PS combined values */ #define USART_PARITY_NONE 0x00 -#define USART_PARITY_ODD USART_CR1_PS -#define USART_PARITY_EVEN (USART_CR1_PS | USART_CR1_PCE) +#define USART_PARITY_EVEN USART_CR1_PCE +#define USART_PARITY_ODD (USART_CR1_PS | USART_CR1_PCE) #define USART_PARITY_MASK (USART_CR1_PS | USART_CR1_PCE) /* CR1_TE/CR1_RE combined values */ @@ -294,6 +294,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void usart_set_baudrate(u32 usart, u32 baud); void usart_set_databits(u32 usart, u32 bits); void usart_set_stopbits(u32 usart, u32 stopbits); @@ -313,4 +315,6 @@ void usart_disable_rx_dma(u32 usart); void usart_enable_tx_dma(u32 usart); void usart_disable_tx_dma(u32 usart); +END_DECLS + #endif diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index f453bc2c..e4b35785 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -22,6 +22,8 @@ #include +BEGIN_DECLS + typedef struct _usbd_driver usbd_driver; extern const usbd_driver stm32f103_usb_driver; extern const usbd_driver stm32f107_usb_driver; @@ -73,4 +75,6 @@ extern void usbd_ep_nak_set(u8 addr, u8 nak); /* Optional */ extern void usbd_cable_connect(u8 on); +END_DECLS + #endif diff --git a/lib/Makefile.include b/lib/Makefile.include new file mode 100644 index 00000000..f2f1f7b2 --- /dev/null +++ b/lib/Makefile.include @@ -0,0 +1,50 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 Piotr Esden-Tempski +## +## 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 . +## + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +endif + +all: $(SRCLIBDIR)/$(LIBNAME).a + +$(SRCLIBDIR)/$(LIBNAME).a: $(SRCLIBDIR)/$(LIBNAME).ld $(OBJS) + @printf " AR $(shell basename $(@))\n" + $(Q)$(AR) $(ARFLAGS) $(SRCLIBDIR)/$(shell basename $(@)) $(OBJS) + +$(SRCLIBDIR)/$(LIBNAME).ld: $(LIBNAME).ld + @printf " CP $(LIBNAME).ld\n" + $(Q)cp $^ $@ + $(Q)if [ -f $(LIBNAME)_rom_to_ram.ld ]; then cp $(LIBNAME)_rom_to_ram.ld $(SRCLIBDIR); fi + +%.o: %.c + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) -o $@ -c $< + +clean: + @printf " CLEAN lib/stm32/f1\n" + $(Q)rm -f *.o *.d + $(Q)rm -f $(SRCLIBDIR)/$(LIBNAME).a + $(Q)rm -f $(SRCLIBDIR)/$(LIBNAME).ld + $(Q)rm -f $(SRCLIBDIR)/$(LIBNAME)_rom_to_ram.ld + +.PHONY: clean + +-include $(OBJS:.o=.d) diff --git a/lib/lm3s/Makefile b/lib/lm3s/Makefile index 7ebc3651..bdad3a47 100644 --- a/lib/lm3s/Makefile +++ b/lib/lm3s/Makefile @@ -32,26 +32,4 @@ OBJS = gpio.o vector.o # VPATH += ../usb -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -endif - -all: $(LIBNAME).a - -$(LIBNAME).a: $(OBJS) - @printf " AR $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(AR) $(ARFLAGS) $@ $^ - -%.o: %.c - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -clean: - @printf " CLEAN lib/lpc13xx\n" - $(Q)rm -f *.o *.d - $(Q)rm -f $(LIBNAME).a - -.PHONY: clean - --include $(OBJS:.o=.d) +include ../Makefile.include diff --git a/lib/lm3s/libopencm3_lm3s.ld b/lib/lm3s/libopencm3_lm3s.ld index c1453fe3..ceb391ac 100644 --- a/lib/lm3s/libopencm3_lm3s.ld +++ b/lib/lm3s/libopencm3_lm3s.ld @@ -24,31 +24,50 @@ /* 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 */ - _etext = .; + . = ALIGN(4); } >rom - . = ORIGIN(ram); + /* + * 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 AT >rom + } >ram /* * The .eh_frame section appears to be used for C++ exception handling. @@ -56,12 +75,7 @@ SECTIONS */ /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 = .; } diff --git a/lib/lm3s/vector.c b/lib/lm3s/vector.c index 5968d769..3a1c4d15 100644 --- a/lib/lm3s/vector.c +++ b/lib/lm3s/vector.c @@ -20,7 +20,7 @@ #define WEAK __attribute__ ((weak)) /* Symbols exported by the linker script(s): */ -extern unsigned _etext, _data, _edata, _ebss, _stack; +extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; void main(void); void reset_handler(void); @@ -61,9 +61,10 @@ void (*const vector_table[]) (void) = { void reset_handler(void) { volatile unsigned *src, *dest; + __asm__("MSR msp, %0" : : "r"(&_stack)); - for (src = &_etext, dest = &_data; dest < &_edata; src++, dest++) + for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) *dest = *src; while (dest < &_ebss) diff --git a/lib/lpc13xx/Makefile b/lib/lpc13xx/Makefile index e4f2096a..158a5bf4 100644 --- a/lib/lpc13xx/Makefile +++ b/lib/lpc13xx/Makefile @@ -32,27 +32,4 @@ OBJS = gpio.o # VPATH += ../usb -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -endif - -all: $(LIBNAME).a - -$(LIBNAME).a: $(OBJS) - @printf " AR $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(AR) $(ARFLAGS) $@ $^ - -%.o: %.c - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -clean: - @printf " CLEAN lib/lpc13xx\n" - $(Q)rm -f *.o *.d - $(Q)rm -f $(LIBNAME).a - -.PHONY: clean - --include $(OBJS:.o=.d) - +include ../Makefile.include diff --git a/lib/lpc13xx/libopencm3_lpc13xx.ld b/lib/lpc13xx/libopencm3_lpc13xx.ld index 5f1630f2..4e0f1dfe 100644 --- a/lib/lpc13xx/libopencm3_lpc13xx.ld +++ b/lib/lpc13xx/libopencm3_lpc13xx.ld @@ -24,31 +24,50 @@ /* 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 */ - _etext = .; + . = ALIGN(4); } >rom - . = ORIGIN(ram); + /* + * 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 AT >rom + } >ram /* * The .eh_frame section appears to be used for C++ exception handling. @@ -56,12 +75,7 @@ SECTIONS */ /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 = .; } diff --git a/lib/lpc17xx/Makefile b/lib/lpc17xx/Makefile index c29f690d..f688716f 100644 --- a/lib/lpc17xx/Makefile +++ b/lib/lpc17xx/Makefile @@ -32,27 +32,4 @@ OBJS = gpio.o vector.o # VPATH += ../usb -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -endif - -all: $(LIBNAME).a - -$(LIBNAME).a: $(OBJS) - @printf " AR $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(AR) $(ARFLAGS) $@ $^ - -%.o: %.c - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -clean: - @printf " CLEAN lib/lpc17xx\n" - $(Q)rm -f *.o *.d - $(Q)rm -f $(LIBNAME).a - -.PHONY: clean - --include $(OBJS:.o=.d) - +include ../Makefile.include diff --git a/lib/lpc17xx/libopencm3_lpc17xx.ld b/lib/lpc17xx/libopencm3_lpc17xx.ld index 30a2c0fb..4e0f1dfe 100644 --- a/lib/lpc17xx/libopencm3_lpc17xx.ld +++ b/lib/lpc17xx/libopencm3_lpc17xx.ld @@ -1,4 +1,3 @@ - /* * This file is part of the libopencm3 project. * @@ -31,28 +30,44 @@ ENTRY(reset_handler) /* Define sections. */ SECTIONS { - . = ORIGIN(rom); - .text : { *(.vectors) /* Vector table */ *(.text*) /* Program code */ + . = ALIGN(4); *(.rodata*) /* Read-only data */ - _etext = .; + . = ALIGN(4); } >rom - . = ORIGIN(ram); + /* + * 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 AT >rom + } >ram /* * The .eh_frame section appears to be used for C++ exception handling. @@ -60,12 +75,7 @@ SECTIONS */ /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 = .; } diff --git a/lib/lpc17xx/vector.c b/lib/lpc17xx/vector.c index 016db7ab..518f5621 100644 --- a/lib/lpc17xx/vector.c +++ b/lib/lpc17xx/vector.c @@ -19,8 +19,8 @@ #define WEAK __attribute__ ((weak)) -/* Symbols exported by the linker script(s). */ -extern unsigned _etext, _data, _edata, _ebss, _stack; +/* Symbols exported by the linker script(s): */ +extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; void main(void); void reset_handler(void); @@ -60,9 +60,10 @@ void (*const vector_table[]) (void) = { void reset_handler(void) { volatile unsigned *src, *dest; + __asm__("MSR msp, %0" : : "r"(&_stack)); - for (src = &_etext, dest = &_data; dest < &_edata; src++, dest++) + for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) *dest = *src; while (dest < &_ebss) diff --git a/lib/lpc43xx/Makefile b/lib/lpc43xx/Makefile new file mode 100644 index 00000000..67e74d7e --- /dev/null +++ b/lib/lpc43xx/Makefile @@ -0,0 +1,38 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2012 Michael Ossmann +## Copyright (C) 2012 Benjamin Vernoux +## +## 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 . +## + +LIBNAME = libopencm3_lpc43xx + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +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 +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = gpio.o vector.o scu.o i2c.o ssp.o nvic.o systick.o + +# VPATH += ../usb + +include ../Makefile.include diff --git a/lib/lpc43xx/gpio.c b/lib/lpc43xx/gpio.c new file mode 100644 index 00000000..1256fd03 --- /dev/null +++ b/lib/lpc43xx/gpio.c @@ -0,0 +1,35 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * + * 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 . + */ + +#include + +void gpio_set(u32 gpioport, u32 gpios) +{ + GPIO_SET(gpioport) = gpios; +} + +void gpio_clear(u32 gpioport, u32 gpios) +{ + GPIO_CLR(gpioport) = gpios; +} + +void gpio_toggle(u32 gpioport, u32 gpios) +{ + GPIO_NOT(gpioport) = gpios; +} \ No newline at end of file diff --git a/lib/lpc43xx/i2c.c b/lib/lpc43xx/i2c.c new file mode 100644 index 00000000..f006615e --- /dev/null +++ b/lib/lpc43xx/i2c.c @@ -0,0 +1,93 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +/* + * This is a very minimal I2C driver just to make sure we can get the + * peripheral working. + */ + +#include +#include +#include + +void i2c0_init(void) +{ + /* enable input on SCL and SDA pins */ + SCU_SFSI2C0 = SCU_I2C0_NOMINAL; + + /* use IRC as clock source for APB1 (including I2C0) */ + CGU_BASE_APB1_CLK = (CGU_SRC_IRC << CGU_BASE_CLK_SEL_SHIFT); + + /* FIXME assuming we're on IRC at 12 MHz */ + + /* 400 kHz I2C */ + I2C0_SCLH = 15; + I2C0_SCLL = 15; + + /* 100 kHz I2C */ + /* + I2C0_SCLH = 60; + I2C0_SCLL = 60; + */ + + /* clear the control bits */ + I2C0_CONCLR = (I2C_CONCLR_AAC | I2C_CONCLR_SIC + | I2C_CONCLR_STAC | I2C_CONCLR_I2ENC); + + /* enable I2C0 */ + I2C0_CONSET = I2C_CONSET_I2EN; +} + +/* transmit start bit */ +void i2c0_tx_start(void) +{ + I2C0_CONCLR = I2C_CONCLR_SIC; + I2C0_CONSET = I2C_CONSET_STA; + while (!(I2C0_CONSET & I2C_CONSET_SI)); + I2C0_CONCLR = I2C_CONCLR_STAC; +} + +/* transmit data byte */ +void i2c0_tx_byte(u8 byte) +{ + if (I2C0_CONSET & I2C_CONSET_STA) + I2C0_CONCLR = I2C_CONCLR_STAC; + I2C0_DAT = byte; + I2C0_CONCLR = I2C_CONCLR_SIC; + while (!(I2C0_CONSET & I2C_CONSET_SI)); +} + +/* receive data byte */ +u8 i2c0_rx_byte(void) +{ + if (I2C0_CONSET & I2C_CONSET_STA) + I2C0_CONCLR = I2C_CONCLR_STAC; + I2C0_CONCLR = I2C_CONCLR_SIC; + while (!(I2C0_CONSET & I2C_CONSET_SI)); + return I2C0_DAT; +} + +/* transmit stop bit */ +void i2c0_stop(void) +{ + if (I2C0_CONSET & I2C_CONSET_STA) + I2C0_CONCLR = I2C_CONCLR_STAC; + I2C0_CONSET = I2C_CONSET_STO; + I2C0_CONCLR = I2C_CONCLR_SIC; +} diff --git a/lib/lpc43xx/libopencm3_lpc43xx.ld b/lib/lpc43xx/libopencm3_lpc43xx.ld new file mode 100644 index 00000000..9402a542 --- /dev/null +++ b/lib/lpc43xx/libopencm3_lpc43xx.ld @@ -0,0 +1,90 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +/* Generic linker script for LPC43XX 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 : { + . = ALIGN(0x400); + _text_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + *(.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 = .; + _etext_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + _etext_rom = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ + + .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 = .; + + /* Leave room above stack for IAP to run. */ + __StackTop = ORIGIN(ram) + LENGTH(ram) - 32; + PROVIDE(_stack = __StackTop); +} diff --git a/lib/lpc43xx/libopencm3_lpc43xx_rom_to_ram.ld b/lib/lpc43xx/libopencm3_lpc43xx_rom_to_ram.ld new file mode 100644 index 00000000..06f77086 --- /dev/null +++ b/lib/lpc43xx/libopencm3_lpc43xx_rom_to_ram.ld @@ -0,0 +1,91 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +/* Generic linker script for LPC43XX 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 : { + . = ALIGN(0x400); + _text_ram = (. - ORIGIN(rom)) + ORIGIN(ram); /* Start of Code in RAM */ + + *(.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 = .; + _etext_ram = (. - ORIGIN(rom)) + ORIGIN(ram); + _etext_rom = (. - ORIGIN(rom)) + ORIGIN(rom_flash); + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram_data AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram_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) } + + . = ALIGN(4); + end = .; + + /* Leave room above stack for IAP to run. */ + __StackTop = ORIGIN(ram) + LENGTH(ram) - 32; + PROVIDE(_stack = __StackTop); +} diff --git a/lib/lpc43xx/nvic.c b/lib/lpc43xx/nvic.c new file mode 100644 index 00000000..47933127 --- /dev/null +++ b/lib/lpc43xx/nvic.c @@ -0,0 +1,76 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Fergus Noble + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ +#include +#include + +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/scu.c b/lib/lpc43xx/scu.c new file mode 100644 index 00000000..addf5e2c --- /dev/null +++ b/lib/lpc43xx/scu.c @@ -0,0 +1,30 @@ +/* +* This file is part of the libopencm3 project. +* +* Copyright (C) 2012 Benjamin Vernoux +* +* 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 . +*/ + +#include + +/* For pin_conf_normal value see scu.h define SCU_CONF_XXX or Configuration for different I/O pins types */ +void scu_pinmux(scu_grp_pin_t group_pin, u32 scu_conf) +{ + MMIO32(group_pin) = scu_conf; +} + +/* For other special SCU register USB1, I2C0, ADC0/1, DAC, EMC clock delay See scu.h */ + +/* For Pin interrupt select register see scu.h SCU_PINTSEL0 & SCU_PINTSEL1 */ diff --git a/lib/lpc43xx/ssp.c b/lib/lpc43xx/ssp.c new file mode 100644 index 00000000..e9cf5b09 --- /dev/null +++ b/lib/lpc43xx/ssp.c @@ -0,0 +1,160 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +#include +#include + +#define CGU_SRC_32K 0x00 +#define CGU_SRC_IRC 0x01 +#define CGU_SRC_ENET_RX 0x02 +#define CGU_SRC_ENET_TX 0x03 +#define CGU_SRC_GP_CLKIN 0x04 +#define CGU_SRC_XTAL 0x06 +#define CGU_SRC_PLL0USB 0x07 +#define CGU_SRC_PLL0AUDIO 0x08 +#define CGU_SRC_PLL1 0x09 +#define CGU_SRC_IDIVA 0x0C +#define CGU_SRC_IDIVB 0x0D +#define CGU_SRC_IDIVC 0x0E +#define CGU_SRC_IDIVD 0x0F +#define CGU_SRC_IDIVE 0x10 + +#define CGU_AUTOBLOCK_CLOCK_BIT 11 +#define CGU_BASE_CLK_SEL_SHIFT 24 /* clock source selection (5 bits) */ + +/* Disable SSP */ +void ssp_disable(ssp_num_t ssp_num) +{ + u32 ssp_port; + + if(ssp_num == SSP0_NUM) + { + ssp_port = SSP0; + }else + { + ssp_port = SSP1; + } + /* Disable SSP */ + SSP_CR1(ssp_port) = 0x0; +} + +/* +* SSP Init function +*/ +void ssp_init(ssp_num_t ssp_num, + ssp_datasize_t data_size, + ssp_frame_format_t frame_format, + ssp_cpol_cpha_t cpol_cpha_format, + u8 serial_clock_rate, + u8 clk_prescale, + ssp_mode_t mode, + ssp_master_slave_t master_slave, + ssp_slave_option_t slave_option) +{ + u32 ssp_port; + u32 clock; + + if(ssp_num == SSP0_NUM) + { + ssp_port = SSP0; + }else + { + ssp_port = SSP1; + } + + /* use PLL1 as clock source for SSP1 */ + CGU_BASE_SSP1_CLK = (CGU_SRC_PLL1< + * Copyright (C) 2012 Benjamin Vernoux + * + * 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 . + */ + +#include + +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 new file mode 100644 index 00000000..23008bc9 --- /dev/null +++ b/lib/lpc43xx/vector.c @@ -0,0 +1,264 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2012 Michael Ossmann + * + * 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 . + */ + +#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/stm32/crc.c b/lib/stm32/crc.c new file mode 100644 index 00000000..bbbe1fd2 --- /dev/null +++ b/lib/stm32/crc.c @@ -0,0 +1,44 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +#include + +void crc_reset(void) +{ + CRC_CR |= CRC_CR_RESET; +} + +u32 crc_calculate(u32 data) +{ + CRC_DR = data; + // Data sheet says this blocks until it's ready.... + return CRC_DR; +} + +u32 crc_calculate_block(u32 *datap, int size) +{ + int i; + for (i = 0; i < size; i++) { + CRC_DR = datap[i]; + } + return CRC_DR; +} + + + diff --git a/lib/stm32/dac.c b/lib/stm32/dac.c new file mode 100644 index 00000000..55440bfe --- /dev/null +++ b/lib/stm32/dac.c @@ -0,0 +1,520 @@ +/** @defgroup STM32F_dac_file DAC + +@ingroup STM32F_files + +@brief libopencm3 STM32Fxx Digital to Analog Converter + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +This library supports the Digital to Analog Conversion System in the +STM32F series of ARM Cortex Microcontrollers by ST Microelectronics. + +The DAC is present only in a limited set of devices, notably some +of the connection line, high density and XL devices. + +Two DAC channels are available, however unlike the ADC channels these +are separate DAC devices controlled by the same register block. + +The DAC is on APB1. Its clock must be enabled in RCC and the GPIO +ports set to alternate function output before it can be used. +The digital output driver is disabled so the output driver mode +(push-pull/open drain) is arbitrary. + +The DAC has a holding (buffer) register and an output register from +which the analog output is derived. The holding register must be +loaded first. If triggering is enabled the output register is loaded +from the holding register after a trigger occurs. If triggering is +not enabled the holding register contents are transferred directly +to the output register. + +@note To avoid nonlinearities, do not allow outputs to range close +to zero or V_analog. + +@section dac_api_dual Dual Channel Conversion + +There are dual modes in which both DACs are used to output data +simultaneously or independently on both channels. The data must be +presented according to the formats described in the datasheets. A +convenience function @ref dac_load_data_buffer_dual is provided +for software controlled use. + +A variety of modes are available depending on whether independent +or simultaneous output is desired, and whether waveforms are to be +superimposed. Refer to the datasheets. + +If DMA is used, only enable it for one of the channels. The DMA +requests will then serve data in dual format to the data register +dedicated to dual mode. The data will then be split and loaded to the +appropriate DAC following the next trigger. There are three registers +available, one for each of the formats: 12 bit right-aligned, 12 bit +left-aligned and 8 bit right-aligned. The desired format is determined +by specifying the appropriate register to the DMA controller. + +@section dac_api_basic_ex Basic DAC handling API. + +Set the DAC's GPIO port to any alternate function output mode. Enable the +DAC clock. Enable the DAC, set a trigger source and load the buffer +with the first value. After the DAC is triggered, load the buffer with +the next value. This example uses software triggering and added noise. +The trigger and further buffer load calls are made when data is to be +sent out. + +@code + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_DACEN); + dac_disable(CHANNEL_1); + dac_set_waveform_characteristics(DAC_CR_MAMP1_8); + dac_set_waveform_generation(DAC_CR_WAVE1_NOISE); + dac_enable(CHANNEL_1); + dac_set_trigger_source(DAC_CR_TSEL1_SW); + dac_load_data_buffer_single(0, RIGHT12, CHANNEL_1); + .... + dac_software_trigger(CHANNEL_1); + dac_load_data_buffer_single(value, RIGHT12, CHANNEL_1); +@endcode + +@section dac_api_dma_ex Simultaneous Dual DAC with DMA. + +This example in part sets up the DAC channel 1 DMA (DMA2 channel 3) to read +16 bit data from memory into the right-aligned 8 bit dual register DAC_DHR8RD. +Both DAC channels are enabled, and both triggers are set to the same timer +2 input as required for simultaneous operation. DMA is enabled for DAC channel +1 only to ensure that only one DMA request is generated. + +@code + dma_set_memory_size(DMA2,DMA_CHANNEL3,DMA_CCR_MSIZE_16BIT); + dma_set_peripheral_size(DMA2,DMA_CHANNEL3,DMA_CCR_PSIZE_16BIT); + dma_set_read_from_memory(DMA2,DMA_CHANNEL3); + dma_set_peripheral_address(DMA2,DMA_CHANNEL3,(u32) &DAC_DHR8RD); + dma_enable_channel(DMA2,DMA_CHANNEL3); + ... + dac_trigger_enable(CHANNEL_D); + dac_set_trigger_source(DAC_CR_TSEL1_T2 | DAC_CR_TSEL2_T2); + dac_dma_enable(CHANNEL_1); + dac_enable(CHANNEL_D); +@endcode + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * 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 . + */ + +/**@{*/ + +#include + +#define MASK8 0xFF +#define MASK12 0xFFF + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Enable. + +Enable a digital to analog converter channel. After setting this enable, the DAC +requires a twakeup time typically around 10 microseconds before it +actually wakes up. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_EN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_EN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_EN1 | DAC_CR_EN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Disable. + +Disable a digital to analog converter channel. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_EN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_EN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_EN1 | DAC_CR_EN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Enable. + +Enable a digital to analog converter channel output drive buffer. This is an optional +amplifying buffer that provides additional drive for the output signal. The +buffer is enabled by default after a reset and needs to be explicitly disabled +if required. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_buffer_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_BOFF1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_BOFF2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Disable. + +Disable a digital to analog converter channel output drive buffer. Disabling this will +reduce power consumption slightly and will increase the output impedance of the DAC. +The buffers are enabled by default after a reset. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_buffer_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_BOFF1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_BOFF2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel DMA Enable. + +Enable a digital to analog converter channel DMA mode (connected to DMA2 channel +3 for DAC channel 1 and DMA2 channel 4 for DAC channel 2). A DMA request is +generated following an external trigger. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_dma_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_DMAEN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_DMAEN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel DMA Disable. + +Disable a digital to analog converter channel DMA mode. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_dma_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_DMAEN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_DMAEN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Trigger Enable. + +Enable a digital to analog converter channel external trigger mode. This allows an +external trigger to initiate register transfers from the buffer register to the DAC +output register, followed by a DMA transfer to the buffer register if DMA is enabled. +The trigger source must also be selected. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_trigger_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_TEN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_TEN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_TEN1 | DAC_CR_TEN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Trigger Disable. + +Disable a digital to analog converter channel external trigger. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_trigger_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_TEN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_TEN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_TEN1 | DAC_CR_TEN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Set DAC Channel Trigger Source. + +Sets the digital to analog converter trigger source, which can be taken from various +timers, an external trigger or a software trigger. + +@param[in] dac_trig_src u32. Taken from @ref dac_trig2_sel or @ref dac_trig1_sel or +a logical OR of one of each of these to set both channels simultaneously. +*/ + +void dac_set_trigger_source(u32 dac_trig_src) +{ + DAC_CR |= dac_trig_src; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Enable and Set DAC Channel Waveform Generation. + +Enable the digital to analog converter waveform generation as either pseudo-random +noise or triangular wave. These signals are superimposed on existing output values +in the DAC output registers. + +@note The DAC trigger must be enabled for this to work. + +@param[in] dac_wave_ens u32. Taken from @ref dac_wave1_en or @ref dac_wave2_en or +a logical OR of one of each of these to set both channels simultaneously. +*/ + +void dac_set_waveform_generation(u32 dac_wave_ens) +{ + DAC_CR |= dac_wave_ens; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Disable DAC Channel Waveform Generation. + +Disable a digital to analog converter channel superimposed waveform generation. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_disable_waveform_generation(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_WAVE1_DIS; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_WAVE2_DIS; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_WAVE1_DIS | DAC_CR_WAVE2_DIS); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Set DAC Channel LFSR Mask or Triangle Wave Amplitude. + +Sets the digital to analog converter superimposed waveform generation characteristics. +@li If the noise generation mode is set, this sets the length of the PRBS sequence and +hence the amplitude of the output noise signal. Default setting is length 1. +@li If the triangle wave generation mode is set, this sets the amplitude of the +output signal as 2^(n)-1 where n is the parameter value. Default setting is 1. + +@note High amplitude levels of these waveforms can overload the DAC and distort the +signal output. +@note This must be called before enabling the DAC as the settings will then become read-only. +@note The DAC trigger must be enabled for this to work. + +@param[in] dac_mamp u32. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a logical OR +of one of each of these to set both channels simultaneously. +*/ + +void dac_set_waveform_characteristics(u32 dac_mamp) +{ + DAC_CR |= dac_mamp; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Load DAC Data Register. + +Loads the appropriate digital to analog converter data register with 12 or 8 bit +data to be converted on a channel. The data can be aligned as follows: +@li right-aligned 8 bit data in bits 0-7 +@li right-aligned 12 bit data in bits 0-11 +@li left aligned 12 bit data in bits 4-15 + +This function can also be used to load the dual channel registers if the data is +formatted according to the datasheets: +@li right-aligned 8 bit data in bits 0-7 for channel 1 and 8-15 for channel 2 +@li right-aligned 12 bit data in bits 0-11 for channel 1 and 16-27 for channel 2 +@li left aligned 12 bit data in bits 4-15 for channel 1 and 20-31 for channel 2 + +@param[in] dac_data u32 with appropriate alignment. +@param[in] dac_data_format enum ::data_align. Alignment and size. +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_load_data_buffer_single(u32 dac_data, data_align dac_data_format, data_channel dac_channel) +{ + if (dac_channel == CHANNEL_1) + { + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8R1 = dac_data; + break; + case RIGHT12: + DAC_DHR12R1 = dac_data; + break; + case LEFT12: + DAC_DHR12L1 = dac_data; + break; + } + } + else if (dac_channel == CHANNEL_2) + { + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8R2 = dac_data; + break; + case RIGHT12: + DAC_DHR12R2 = dac_data; + break; + case LEFT12: + DAC_DHR12L2 = dac_data; + break; + } + } + else + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8RD = dac_data; + break; + case RIGHT12: + DAC_DHR12RD = dac_data; + break; + case LEFT12: + DAC_DHR12LD = dac_data; + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Load DAC Dual Data Register. + +Loads the appropriate digital to analog converter dual data register with 12 or +8 bit data to be converted for both channels. This allows high bandwidth +simultaneous or independent analog output. The data in both channels are aligned +identically. + +@param[in] dac_data1 u32 for channel 1 with appropriate alignment. +@param[in] dac_data2 u32 for channel 2 with appropriate alignment. +@param[in] dac_data_format enum ::data_align. Right or left aligned, and 8 or 12 bit. +*/ + +void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data_format) +{ + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8RD = ((dac_data1 & MASK8) | ((dac_data2 & MASK8) << 8)); + break; + case RIGHT12: + DAC_DHR12RD = ((dac_data1 & MASK12) | ((dac_data2 & MASK12) << 12)); + break; + case LEFT12: + DAC_DHR12LD = ((dac_data1 & MASK12) | ((dac_data2 & MASK12) << 16)); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Trigger the DAC by a Software Trigger. + +If the trigger source is set to be a software trigger, cause a trigger to occur. +The trigger is cleared by hardware after conversion. + +@param[in] dac_channel enum ::data_channel. +*/ + +void dac_software_trigger(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG1; + break; + case CHANNEL_2: + DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG2; + break; + case CHANNEL_D: + DAC_SWTRIGR |= (DAC_SWTRIGR_SWTRIG1 | DAC_SWTRIGR_SWTRIG2); + break; + } +} +/**@}*/ + diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index d598f847..3b4252ba 100644 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -31,31 +31,9 @@ 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 \ usb_f103.o usb.o usb_control.o usb_standard.o can.o \ - timer.o usb_f107.o + timer.o usb_f107.o desig.o crc.o VPATH += ../../usb:../ -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -endif - -all: $(LIBNAME).a - -$(LIBNAME).a: $(OBJS) - @printf " AR $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(AR) $(ARFLAGS) $@ $^ - -%.o: %.c - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -clean: - @printf " CLEAN lib/stm32/f1\n" - $(Q)rm -f *.o *.d - $(Q)rm -f $(LIBNAME).a - -.PHONY: clean - --include $(OBJS:.o=.d) +include ../../Makefile.include diff --git a/lib/stm32/f1/adc.c b/lib/stm32/f1/adc.c index f07164fd..433cdd2e 100644 --- a/lib/stm32/f1/adc.c +++ b/lib/stm32/f1/adc.c @@ -1,3 +1,70 @@ +/** @defgroup STM32F1xx_adc_file ADC + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Analog to Digital Converters + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Edward Cheeseman +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +This library supports the A/D Converter Control System in the STM32F1xx 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. + +Each A/D converter has up to 18 channels: +@li On ADC1 the analog channels 16 and 17 are internally connected to the temperature +sensor and VREFINT, respectively. +@li On ADC2 the analog channels 16 and 17 are internally connected to VSS. +@li On ADC3 the analog channels 9, 14, 15, 16 and 17 are internally connected to VSS. + +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_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 dual mode to independent. + +@code + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + adc_power_on(ADC1); + adc_calibration(ADC1); + rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); + rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); + adc_set_dual_mode(ADC_CR1_DUALMOD_IND); + adc_disable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); + adc_set_single_channel(ADC1, ADC_CHANNEL0); + 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. * @@ -27,10 +94,12 @@ * rcc_peripheral_clear_reset(&RCC_APB2RSTR, ADC1RST); * * rcc_set_adc_clk(ADC_PRE_PLCK2_DIV2); - * adc_set_mode(ADC1, TODO); + * adc_set_dual_mode(ADC1, TODO); * reg16 = adc_read(ADC1, ADC_CH_0); */ +/**@{*/ + #include void rcc_set_adc_clk(u32 prescaler) @@ -50,6 +119,14 @@ void adc_set_mode(u32 block, /* TODO */ u8 mode) mode = mode; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read from a Conversion Result Register + +@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. +*/ + void adc_read(u32 block, u32 channel) { /* TODO */ @@ -59,61 +136,177 @@ void adc_read(u32 block, u32 channel) channel = channel; } +/*-----------------------------------------------------------------------------*/ +/** @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_discontinous_mode_regular(u32 adc) { ADC_CR1(adc) |= ADC_CR1_DISCEN; } +/*-----------------------------------------------------------------------------*/ +/** @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_discontinous_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_discontinous_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_discontinous_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_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; @@ -125,56 +318,140 @@ void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel) 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_jeoc_interrupt(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_jeoc_interrupt(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 Enable The Temperature Sensor + +This enables both the sensor and the reference voltage measurements on channels +16 and 17. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_temperature_sensor(u32 adc) { ADC_CR2(adc) |= ADC_CR2_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(u32 adc) { ADC_CR2(adc) &= ~ADC_CR2_TSVREFE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Regular Channels + +This starts conversion on a set of defined regular channels if the ADC trigger +is set to be a software trigger. It is cleared by hardware once conversion +starts. + +Note this is a software trigger and requires triggering to be enabled and the +trigger source to be set appropriately otherwise conversion will not start. +This is not the same as the ADC start conversion operation. + +@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. */ @@ -184,6 +461,20 @@ void adc_start_conversion_regular(u32 adc) 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 if the ADC trigger +is set to be a software trigger. It is cleared by hardware once conversion +starts. + +Note this is a software trigger and requires triggering to be enabled and the +trigger source to be set appropriately otherwise conversion will not start. +This is not the same as the ADC start conversion operation. + +@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. */ @@ -193,6 +484,36 @@ void adc_start_conversion_injected(u32 adc) while (ADC_CR2(adc) & ADC_CR2_JSWSTART); } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + +This enables an external trigger for set of defined regular channels. + +For ADC1 and ADC2 +@li Timer 1 CC1 event +@li Timer 1 CC2 event +@li Timer 1 CC3 event +@li Timer 2 CC2 event +@li Timer 3 TRGO event +@li Timer 4 CC4 event +@li EXTI (TIM8_TRGO is also possible on some devices, see datasheet) +@li Software Start + +For ADC3 +@li Timer 3 CC1 event +@li Timer 2 CC3 event +@li Timer 1 CC3 event +@li Timer 8 CC1 event +@li Timer 8 TRGO event +@li Timer 5 CC1 event +@li Timer 5 CC3 event +@li Software Start + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_regular_12 +for ADC1 and ADC2, or @ref adc_trigger_regular_3 for ADC3 +*/ + void adc_enable_external_trigger_regular(u32 adc, u32 trigger) { u32 reg32; @@ -204,11 +525,47 @@ void adc_enable_external_trigger_regular(u32 adc, u32 trigger) ADC_CR2(adc) |= ADC_CR2_EXTTRIG; } +/*-----------------------------------------------------------------------------*/ +/** @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_EXTTRIG; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + +This enables an external trigger for set of defined injected channels. + +For ADC1 and ADC2 +@li Timer 1 TRGO event +@li Timer 1 CC4 event +@li Timer 2 TRGO event +@li Timer 2 CC1 event +@li Timer 3 CC4 event +@li Timer 4 TRGO event +@li EXTI (TIM8 CC4 is also possible on some devices, see datasheet) +@li Software Start + +For ADC3 +@li Timer 1 TRGO event +@li Timer 1 CC4 event +@li Timer 4 CC3 event +@li Timer 8 CC2 event +@li Timer 8 CC4 event +@li Timer 5 TRGO event +@li Timer 5 CC4 event +@li Software Start + +@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_12 +for ADC1 and ADC2, or @ref adc_trigger_injected_3 for ADC3 +*/ + void adc_enable_external_trigger_injected(u32 adc, u32 trigger) { u32 reg32; @@ -220,65 +577,169 @@ void adc_enable_external_trigger_injected(u32 adc, u32 trigger) ADC_CR2(adc) |= ADC_CR2_JEXTTRIG; } +/*-----------------------------------------------------------------------------*/ +/** @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_JEXTTRIG; } +/*-----------------------------------------------------------------------------*/ +/** @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 Initialize Calibration Registers + +This resets the calibration registers. It is not clear if this is required to be +done before every calibration operation. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_reset_calibration(u32 adc) { ADC_CR2(adc) |= ADC_CR2_RSTCAL; while (ADC_CR2(adc) & ADC_CR2_RSTCAL); } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Calibration + +The calibration data for the ADC is recomputed. The hardware clears the +calibration status flag when calibration is complete. This function does not return +until this happens and the ADC is ready for use. + +The ADC must have been powered down for at least 2 ADC clock cycles, then powered on. +before calibration starts + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_calibration(u32 adc) { ADC_CR2(adc) |= ADC_CR2_CAL; while (ADC_CR2(adc) & ADC_CR2_CAL); } +/*-----------------------------------------------------------------------------*/ +/** @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_continous_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 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 initiate a conversion. + +@todo fix this. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_on(u32 adc) { ADC_CR2(adc) |= ADC_CR2_ADON; } +/*-----------------------------------------------------------------------------*/ +/** @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 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_conversion_time(u32 adc, u8 channel, u8 time) { u32 reg32; @@ -296,6 +757,16 @@ void adc_set_conversion_time(u32 adc, u8 channel, u8 time) } } +/*-----------------------------------------------------------------------------*/ +/** @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_conversion_time_on_all_channels(u32 adc, u8 time) { u8 i; @@ -310,6 +781,13 @@ void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) 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; @@ -319,6 +797,13 @@ void adc_set_watchdog_high_threshold(u32 adc, u16 threshold) 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; @@ -328,6 +813,18 @@ void adc_set_watchdog_low_threshold(u32 adc, u16 threshold) 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; @@ -352,6 +849,18 @@ void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]) 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; @@ -368,3 +877,6 @@ void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]) ADC_JSQR(adc) = reg32; } + +/**@}*/ + diff --git a/lib/stm32/f1/desig.c b/lib/stm32/f1/desig.c new file mode 100644 index 00000000..7ae968e1 --- /dev/null +++ b/lib/stm32/f1/desig.c @@ -0,0 +1,37 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +#include + +u16 desig_get_flash_size(void) +{ + return DESIG_FLASH_SIZE; +} + +void desig_get_unique_id(u32 result[]) +{ + // Could also just return a pointer to the start? read it as they wish? + u16 bits15_0 = DESIG_UID_15_0; + u32 bits31_16 = DESIG_UID_31_16; + u32 bits63_32 = DESIG_UID_63_32; + u32 bits95_64 = DESIG_UID_95_64; + result[0] = bits95_64; + result[1] = bits63_32; + result[2] = bits31_16 << 16 | bits15_0; +} diff --git a/lib/stm32/f1/dma.c b/lib/stm32/f1/dma.c index 6bcb396e..04cb8a10 100644 --- a/lib/stm32/f1/dma.c +++ b/lib/stm32/f1/dma.c @@ -1,3 +1,24 @@ +/** @defgroup STM32F1xx-dma-file DMA + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx DMA Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@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). + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,8 +38,19 @@ * along with this library. If not, see . */ +/**@{*/ + #include +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Reset + +The channel is disabled and configuration registers are cleared. + +@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_channel_reset(u32 dma, u8 channel) { /* Disable channel. */ @@ -35,18 +67,51 @@ void dma_channel_reset(u32 dma, u8 channel) DMA_IFCR(dma) |= DMA_IFCR_CIF(channel); } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Memory to Memory Transfers + +Memory to memory transfers do not require a trigger to activate each transfer. +Transfers begin immediately the channel has been enabled, and proceed without +intervention. + +@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_mem2mem_mode(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_MEM2MEM; DMA_CCR(dma, channel) &= ~DMA_CCR_CIRC; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set Priority + +Channel Priority has four levels: low to very high. This has precedence over the +hardware priority. + +@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 +@param[in] prio unsigned int32. Priority level @ref dma_ch_pri. +*/ + void dma_set_priority(u32 dma, u8 channel, u32 prio) { DMA_CCR(dma, channel) &= ~(DMA_CCR_PL_MASK); DMA_CCR(dma, channel) |= prio; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel 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. + +@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 +@param[in] mem_size unsigned int32. Memory word width @ref dma_ch_memwidth. +*/ + void dma_set_memory_size(u32 dma, u8 channel, u32 mem_size) { @@ -54,89 +119,249 @@ void dma_set_memory_size(u32 dma, u8 channel, u32 mem_size) DMA_CCR(dma, channel) |= mem_size; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel 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. + +@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 +@param[in] peripheral_size unsigned int32. Peripheral word width @ref dma_ch_perwidth. +*/ + void dma_set_peripheral_size(u32 dma, u8 channel, u32 peripheral_size) { DMA_CCR(dma, channel) &= ~(DMA_CCR_PSIZE_MASK); DMA_CCR(dma, channel) |= peripheral_size; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel 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. + +@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_memory_increment_mode(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_MINC; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Memory 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_enable_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 +original transfer block size, memory and peripheral base addresses are +reloaded and the process repeats. + +@note This cannot be used with memory to memory mode, which is explictly +disabled here. + +@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_circular_mode(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_CIRC; DMA_CCR(dma, channel) &= ~DMA_CCR_MEM2MEM; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Transfers from a Peripheral + +The data direction is set to read from a peripheral. + +@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_set_read_from_peripheral(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_DIR; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Transfers from Memory + +The data direction is set to read from memory. + +@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_set_read_from_memory(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_DIR; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Error + +@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_transfer_error_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_TEIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Error + +@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_transfer_error_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_TEIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Half Complete + +@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_half_transfer_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_HTIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Half Complete + +@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_half_transfer_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_HTIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Complete + +@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_transfer_complete_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_TCIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Complete + +@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_transfer_complete_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_TCIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable + +@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_channel(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_EN; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable + +@note The DMA channel registers retain their values when the channel is disabled. + +@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_channel(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_EN; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel 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 channel must be disabled before setting this address. This function +has no effect if the channel is enabled. + +@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 +@param[in] address unsigned int32. Peripheral Address. +*/ + void dma_set_peripheral_address(u32 dma, u8 channel, u32 address) { - DMA_CPAR(dma, channel) = (u32) address; + if (!(DMA_CCR(dma, channel) & DMA_CCR_EN)) + DMA_CPAR(dma, channel) = (u32) address; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set the Base Memory Address + +@note The DMA channel must be disabled before setting this address. This function +has no effect if the channel is enabled. + +@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 +@param[in] address unsigned int32. Memory Initial Address. +*/ + void dma_set_memory_address(u32 dma, u8 channel, u32 address) { - DMA_CMAR(dma, channel) = (u32) address; + if (!(DMA_CCR(dma, channel) & DMA_CCR_EN)) + DMA_CMAR(dma, channel) = (u32) address; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set the Transfer Block Size + +@note The DMA channel must be disabled before setting this count value. The count +is not changed if the channel is enabled. + +@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 +@param[in] number unsigned int16. Number of data words to transfer (65535 maximum). +*/ + void dma_set_number_of_data(u32 dma, u8 channel, u16 number) { DMA_CNDTR(dma, channel) = number; } +/**@}*/ + diff --git a/lib/stm32/f1/gpio.c b/lib/stm32/f1/gpio.c index 4f7e663d..06020125 100644 --- a/lib/stm32/f1/gpio.c +++ b/lib/stm32/f1/gpio.c @@ -1,3 +1,61 @@ +/** @defgroup STM32F1xx_gpio_file GPIO + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx General Purpose I/O + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +This library supports the General Purpose I/O System in the STM32F1xx series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Each I/O port has 16 individually configurable bits. Many I/O pins share GPIO +functionality with a number of alternate functions and must be configured to the +alternate function mode if these are to be accessed. A feature is available to +remap alternative functions to a limited set of alternative pins in the event +of a clash of requirements. + +The data registers associated with each port for input and output are 32 bit with +the upper 16 bits unused. The output buffer must be written as a 32 bit word, but +individual bits may be set or reset separately in atomic operations to avoid race +conditions during interrupts. Bits may also be individually locked to prevent +accidental configuration changes. Once locked the configuration cannot be changed +until after the next reset. + +Each port bit can be configured as analog or digital input, the latter can be +floating or pulled up or down. As outputs they can be configured as either +push-pull or open drain, digital I/O or alternate function, and with maximum +output speeds of 2MHz, 10MHz, or 50MHz. + +On reset all ports are configured as digital floating input. + +@section gpio_api_ex Basic GPIO Handling API. + +Example 1: Push-pull digital output actions on ports C2 and C9 + +@code + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO2 | GPIO9); + gpio_set(GPIOC, GPIO2 | GPIO9); + gpio_clear(GPIOC, GPIO2); + gpio_toggle(GPIOC, GPIO2 | GPIO9); + gpio_port_write(GPIOC, 0x204); +@endcode + +Example 1: Digital input on port C12 + +@code + gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT, GPIO12); + reg16 = gpio_port_read(GPIOC); +@endcode + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -33,9 +91,23 @@ * TODO: * - GPIO remapping support */ +/**@{*/ #include +/*-----------------------------------------------------------------------------*/ +/** @brief Set GPIO Pin Mode + +Sets the mode (input/output) and configuration (analog/digitial and +open drain/push pull), for a set of GPIO pins on a given GPIO port. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] mode Unsigned int8. Pin mode @ref gpio_mode +@param[in] cnf Unsigned int8. Pin configuration @ref gpio_cnf +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be set, use logical OR '|' to separate them. +*/ + void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios) { u16 i, offset = 0; @@ -73,69 +145,99 @@ void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios) GPIO_CRH(gpioport) = crh; } -/** - * Set one or more pins of the given GPIO port to 1. - * - * @param gpioport The GPIO port to use (GPIOA - GPIOG). - * @param gpios The GPIO pin(s) to set to 1 (GPIO0 - GPIO15, or GPIO_ALL). - * If multiple pins shall be set, use '|' to separate them. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Set a Group of Pins Atomic + +Set one or more pins of the given GPIO port to 1 in an atomic operation. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use logical OR '|' to separate them. +*/ void gpio_set(u32 gpioport, u16 gpios) { GPIO_BSRR(gpioport) = gpios; } -/** - * Clear one or more pins of the given GPIO port to 0. - * - * @param gpioport The GPIO port to use (GPIOA - GPIOG). - * @param gpios The GPIO pin(s) to set to 0 (GPIO0 - GPIO15, or GPIO_ALL). - * If multiple pins shall be cleared, use '|' to separate them. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Clear a Group of Pins Atomic + +Clear one or more pins of the given GPIO port to 0 in an atomic operation. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use logical OR '|' to separate them. +*/ void gpio_clear(u32 gpioport, u16 gpios) { GPIO_BRR(gpioport) = gpios; } +/*-----------------------------------------------------------------------------*/ +/** @brief Read a Group of Pins. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be read, use logical OR '|' to separate them. +@return Unsigned int16 value of the pin values. The bit position of the pin value + returned corresponds to the pin number. +*/ u16 gpio_get(u32 gpioport, u16 gpios) { return gpio_port_read(gpioport) & gpios; } -/** - * Toggle one or more pins of the given GPIO port. - * - * @param gpioport The GPIO port to use (GPIOA - GPIOG). - * @param gpios The GPIO pin(s) to toggle (GPIO0 - GPIO15, or GPIO_ALL). - * If multiple pins shall be toggled, use '|' to separate them. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Toggle a Group of Pins + +Toggle one or more pins of the given GPIO port. This is not an atomic operation. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use logical OR '|' to separate them. +*/ void gpio_toggle(u32 gpioport, u16 gpios) { GPIO_ODR(gpioport) ^= gpios; } -/** - * Read the current value of the given GPIO port. - * - * @param gpioport The GPIO port to read (GPIOA - GPIOG). - * @return The value of the current GPIO port. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Read from a Port + +Read the current value of the given GPIO port. Only the lower 16 bits contain +valid pin data. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@return Unsigned int16. The value held in the specified GPIO port. +*/ u16 gpio_port_read(u32 gpioport) { return (u16)GPIO_IDR(gpioport); } -/** - * Write to the given GPIO port. - * - * @param gpioport The GPIO port to write to (GPIOA - GPIOG). - * @param data The data to write to the specified GPIO port. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Write to a Port + +Write a value to the given GPIO port. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] data Unsigned int16. The value to be written to the GPIO port. +*/ void gpio_port_write(u32 gpioport, u16 data) { GPIO_ODR(gpioport) = data; } +/*-----------------------------------------------------------------------------*/ +/** @brief Lock the Configuration of a Group of Pins + +The configuration of one or more pins of the given GPIO port is locked. There is +no mechanism to unlock these via software. Unlocking occurs at the next reset. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be locked, use logical OR '|' to separate them. +*/ void gpio_port_config_lock(u32 gpioport, u16 gpios) { u32 reg32; @@ -147,5 +249,69 @@ void gpio_port_config_lock(u32 gpioport, u16 gpios) 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. */ } + +/*-----------------------------------------------------------------------------*/ +/** @brief Map the EVENTOUT signal + +Enable the EVENTOUT signal and select the port and pin to be used. + +@param[in] evoutport Unsigned int8. Port for EVENTOUT signal @ref afio_evcr_port +@param[in] evoutpin Unsigned int8. Pin for EVENTOUT signal @ref afio_evcr_pin +*/ +void gpio_set_eventout(u8 evoutport, u8 evoutpin) +{ + AFIO_EVCR = AFIO_EVCR_EVOE | evoutport | evoutpin; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Map Alternate Function Port Bits (Main Set) + +A number of alternate function ports can be remapped to defined alternative +port bits to avoid clashes in cases where multiple alternate functions are present. +Refer to the datasheets for the particular mapping desired. This provides the main +set of remap functionality. See @ref gpio_secondary_remap for a number of lesser used +remaps. + +The AFIO remapping feature is used only with the STM32F10x series. + +@note The Serial Wire JTAG disable controls allow certain GPIO ports to become available +in place of some of the SWJ signals. Full SWJ capability is obtained by setting this to +zero. The value of this must be specified for every call to this function as its current +value cannot be ascertained from the hardware. + +@param[in] swjdisable Unsigned int8. Disable parts of the SWJ capability @ref afio_swj_disable. +@param[in] maps Unsigned int32. Logical OR of map enable controls from @ref afio_remap, + @ref afio_remap_can1, @ref afio_remap_tim3, @ref afio_remap_tim2, @ref afio_remap_tim1, + @ref afio_remap_usart3. For connectivity line devices only @ref afio_remap_cld are + also available. +*/ +void gpio_primary_remap(u8 swjdisable, u32 maps) +{ + AFIO_MAPR = swjdisable | (maps & 0x1FFFFF); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Map Alternate Function Port Bits (Secondary Set) + +A number of alternate function ports can be remapped to defined alternative +port bits to avoid clashes in cases where multiple alternate functions are present. +Refer to the datasheets for the particular mapping desired. This provides the second +smaller and less used set of remap functionality. See @ref gpio_primary_remap for +the main set of remaps. + +The AFIO remapping feature is used only with the STM32F10x series. + +@param[in] maps Unsigned int32. Logical OR of map enable controls from @ref afio_remap2 +*/ +void gpio_secondary_remap(u32 maps) +{ + AFIO_MAPR2 = maps; +} + +/**@}*/ + diff --git a/lib/stm32/f1/libopencm3_stm32f1.ld b/lib/stm32/f1/libopencm3_stm32f1.ld index a64a1f77..9d165f68 100644 --- a/lib/stm32/f1/libopencm3_stm32f1.ld +++ b/lib/stm32/f1/libopencm3_stm32f1.ld @@ -30,21 +30,18 @@ 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 /* - * Another section used by C++ stuff, appears when using newlib with - * 64bit (long long) printf support - */ + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ .ARM.extab : { *(.ARM.extab*) } >rom @@ -54,21 +51,23 @@ SECTIONS __exidx_end = .; } >rom - . = ORIGIN(ram); + . = ALIGN(4); + _etext = .; - .data : AT (__exidx_end) { + .data : { _data = .; *(.data*) /* Read-write initialized data */ . = ALIGN(4); _edata = .; - } >ram + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); .bss : { *(.bss*) /* Read-write zero initialized data */ *(COMMON) . = ALIGN(4); _ebss = .; - } >ram AT >rom + } >ram /* * The .eh_frame section appears to be used for C++ exception handling. diff --git a/lib/stm32/f1/pwr.c b/lib/stm32/f1/pwr.c new file mode 100644 index 00000000..83c3dba5 --- /dev/null +++ b/lib/stm32/f1/pwr.c @@ -0,0 +1,217 @@ +/** @defgroup STM32F1xx-pwr-file PWR + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Power Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +This library supports the power control system for the +STM32F1 series of ARM Cortex Microcontrollers by ST Microelectronics. + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * 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 . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Backup Domain Write Protection. + +This allows backup domain registers to be changed. These registers are write +protected after a reset. +*/ + +void pwr_disable_backup_domain_write_protect(void) +{ + PWR_CR |= PWR_CR_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Re-enable Backup Domain Write Protection. + +This protects backup domain registers from inadvertent change. +*/ + +void pwr_enable_backup_domain_write_protect(void) +{ + PWR_CR &= ~PWR_CR_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Power Voltage Detector. + +This provides voltage level threshold detection. The result of detection is +provided in the power voltage detector output flag (see @ref pwr_voltage_high) +or by setting the EXTI16 interrupt (see datasheet for configuration details). + +@param[in] pvd_level u32. Taken from @ref pwr_pls. +*/ + +void pwr_enable_power_voltage_detect(u32 pvd_level) +{ + PWR_CR &= ~PWR_CR_PLS_MASK; + PWR_CR |= (PWR_CR_PVDE | pvd_level); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Power Voltage Detector. + +*/ + +void pwr_disable_power_voltage_detect(void) +{ + PWR_CR &= ~PWR_CR_PVDE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Standby Flag. + +This is set when the processor returns from a standby mode. +*/ + +void pwr_clear_standby_flag(void) +{ + PWR_CR |= PWR_CR_CSBF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Wakeup Flag. + +This is set when the processor receives a wakeup signal. +*/ + +void pwr_clear_wakeup_flag(void) +{ + PWR_CR |= PWR_CR_CWUF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Standby Mode in Deep Sleep. + +*/ + +void pwr_set_standby_mode(void) +{ + PWR_CR |= PWR_CR_PDDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Stop Mode in Deep Sleep. + +*/ + +void pwr_set_stop_mode(void) +{ + PWR_CR &= ~PWR_CR_PDDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Voltage Regulator On in Stop Mode. + +*/ + +void pwr_voltage_regulator_on_in_stop(void) +{ + PWR_CR &= ~PWR_CR_LPDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Voltage Regulator Low Power in Stop Mode. + +*/ + +void pwr_voltage_regulator_low_power_in_stop(void) +{ + PWR_CR |= PWR_CR_LPDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Wakeup Pin. + +The wakeup pin is used for waking the processor from standby mode. +*/ + +void pwr_enable_wakeup_pin(void) +{ + PWR_CSR |= PWR_CR_EWUP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Release Wakeup Pin. + +The wakeup pin is used for general purpose I/O. +*/ + +void pwr_disable_wakeup_pin(void) +{ + PWR_CSR &= ~PWR_CR_EWUP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Voltage Detector Output. + +The voltage detector threshold must be set when the power voltage detector is +enabled, see @ref pwr_enable_power_voltage_detect. + +@returns boolean: TRUE if the power voltage is above the preset voltage +threshold. +*/ + +bool pwr_voltage_high(void) +{ + return (PWR_CSR & PWR_CR_PVDO); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Standby Flag. + +The standby flag is set when the processor returns from a standby state. It is +cleared by software (see @ref pwr_clear_standby_flag). + +@returns boolean: TRUE if the processor was in standby state. +*/ + +bool pwr_get_standby_flag(void) +{ + return (PWR_CSR & PWR_CR_SBF); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Wakeup Flag. + +The wakeup flag is set when a wakeup event has been received. It is +cleared by software (see @ref pwr_clear_wakeup_flag). + +@returns boolean: TRUE if a wakeup event was received. +*/ + +bool pwr_get_wakeup_flag(void) +{ + return (PWR_CSR & PWR_CR_WUF); +} +/**@}*/ + diff --git a/lib/stm32/f1/rcc.c b/lib/stm32/f1/rcc.c index 8945e80a..5fd9c62f 100644 --- a/lib/stm32/f1/rcc.c +++ b/lib/stm32/f1/rcc.c @@ -1,3 +1,30 @@ +/** @defgroup STM32F1xx-rcc-file RCC + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Reset and Clock Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Federico Ruiz-Ugalde \ +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +This library supports the Reset and Clock Control System in the STM32F1xx +series of ARM Cortex Microcontrollers by ST Microelectronics. + +@note Full support for connection line devices is not yet provided. + +Clock settings and resets for many peripherals are given here rather than in the +corresponding peripheral library. + +The library also provides a number of common configurations for the processor +system clock. Not all possible configurations are included. + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -19,13 +46,24 @@ * along with this library. If not, see . */ +/**@{*/ + #include #include -/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset. */ +/** Default ppre1 peripheral clock frequency after reset. */ u32 rcc_ppre1_frequency = 8000000; +/** Default ppre2 peripheral clock frequency after reset. */ u32 rcc_ppre2_frequency = 8000000; +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Clear the Oscillator Ready Interrupt Flag + +Clear the interrupt flag that was set when a clock oscillator became ready to use. + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_ready_int_clear(osc_t osc) { switch (osc) { @@ -47,6 +85,12 @@ void rcc_osc_ready_int_clear(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Enable the Oscillator Ready Interrupt + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_ready_int_enable(osc_t osc) { switch (osc) { @@ -68,6 +112,12 @@ void rcc_osc_ready_int_enable(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Disable the Oscillator Ready Interrupt + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_ready_int_disable(osc_t osc) { switch (osc) { @@ -89,6 +139,13 @@ void rcc_osc_ready_int_disable(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Read the Oscillator Ready Interrupt Flag + +@param[in] osc enum ::osc_t. Oscillator ID +@returns int. Boolean value for flag set. +*/ + int rcc_osc_ready_int_flag(osc_t osc) { switch (osc) { @@ -113,16 +170,33 @@ int rcc_osc_ready_int_flag(osc_t osc) return -1; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Clear the Clock Security System Interrupt Flag + +*/ + void rcc_css_int_clear(void) { RCC_CIR |= RCC_CIR_CSSC; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Read the Clock Security System Interrupt Flag + +@returns int. Boolean value for flag set. +*/ + int rcc_css_int_flag(void) { return ((RCC_CIR & RCC_CIR_CSSF) != 0); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Wait for Oscillator Ready. + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_wait_for_osc_ready(osc_t osc) { switch (osc) { @@ -144,6 +218,20 @@ void rcc_wait_for_osc_ready(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Turn on an Oscillator. + +Enable an oscillator and power on. Each oscillator requires an amount of time to +settle to a usable state. Refer to datasheets for time delay information. A status +flag is available to indicate when the oscillator becomes ready (see +@ref rcc_osc_ready_int_flag and @ref rcc_wait_for_osc_ready). + +@note The LSE clock is in the backup domain and cannot be enabled until the +backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect). + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_on(osc_t osc) { switch (osc) { @@ -165,6 +253,20 @@ void rcc_osc_on(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Turn off an Oscillator. + +Disable an oscillator and power off. + +@note An oscillator cannot be turned off if it is selected as the system clock. +@note The LSE clock is in the backup domain and cannot be disabled until the +backup domain write protection has been removed (see +@ref pwr_disable_backup_domain_write_protect) or the backup domain has been +(see reset @ref rcc_backupdomain_reset). + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_off(osc_t osc) { switch (osc) { @@ -186,16 +288,39 @@ void rcc_osc_off(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Enable the Clock Security System. + +*/ + void rcc_css_enable(void) { RCC_CR |= RCC_CR_CSSON; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Disable the Clock Security System. + +*/ + void rcc_css_disable(void) { RCC_CR &= ~RCC_CR_CSSON; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Enable Bypass. + +Enable an external clock to bypass the internal clock (high speed and low speed +clocks only). The external clock must be enabled (see @ref rcc_osc_on) +and the internal clock must be disabled (see @ref rcc_osc_off) for this to have effect. + +@note The LSE clock is in the backup domain and cannot be bypassed until the +backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect). + +@param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect. +*/ + void rcc_osc_bypass_enable(osc_t osc) { switch (osc) { @@ -213,6 +338,19 @@ void rcc_osc_bypass_enable(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Disable Bypass. + +Re-enable the internal clock (high speed and low speed clocks only). The internal +clock must be disabled (see @ref rcc_osc_off) for this to have effect. + +@note The LSE clock is in the backup domain and cannot have bypass removed until the +backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect) +or the backup domain has been reset (see @ref rcc_backupdomain_reset). + +@param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect. +*/ + void rcc_osc_bypass_disable(osc_t osc) { switch (osc) { @@ -230,26 +368,96 @@ void rcc_osc_bypass_disable(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Enable Peripheral Clocks. + +Enable the clock on particular peripherals. There are three registers +involved, each one controlling the enabling of clocks associated with the AHB, +APB1 and APB2 respectively. Several peripherals could be +enabled simultaneously only if they are controlled by the same register. + +@param[in] *reg Unsigned int32. Pointer to a Clock Enable Register + (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) +@param[in] en Unsigned int32. Logical OR of all enables to be set +@li If register is RCC_AHBER, from @ref rcc_ahbenr_en +@li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en +@li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en +*/ + void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en) { *reg |= en; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Disable Peripheral Clocks. + +Enable the clock on particular peripherals. There are three registers +involved, each one controlling the enabling of clocks associated with the AHB, +APB1 and APB2 respectively. Several peripherals could be +disabled simultaneously only if they are controlled by the same register. + +@param[in] *reg Unsigned int32. Pointer to a Clock Enable Register + (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) +@param[in] en Unsigned int32. Logical OR of all enables to be used for disabling. +@li If register is RCC_AHBER, from @ref rcc_ahbenr_en +@li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en +@li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en +*/ + void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en) { *reg &= ~en; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Reset Peripherals. + +Reset particular peripherals. There are three registers +involved, each one controlling reset of peripherals associated with the AHB, +APB1 and APB2 respectively. Several peripherals could be reset simultaneously +only if they are controlled by the same register. + +@param[in] *reg Unsigned int32. Pointer to a Reset Register + (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) +@param[in] reset Unsigned int32. Logical OR of all resets. +@li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst +@li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst +@li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst +*/ + void rcc_peripheral_reset(volatile u32 *reg, u32 reset) { *reg |= reset; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Remove Reset on Peripherals. + +Remove the reset on particular peripherals. There are three registers +involved, each one controlling reset of peripherals associated with the AHB, +APB1 and APB2 respectively. Several peripherals could have the reset removed +simultaneously only if they are controlled by the same register. + +@param[in] *reg Unsigned int32. Pointer to a Reset Register + (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) +@param[in] clear_reset Unsigned int32. Logical OR of all resets to be removed: +@li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst +@li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst +@li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst +*/ + void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset) { *reg &= ~clear_reset; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the System Clock. + +@param[in] clk Unsigned int32. System Clock Selection @ref rcc_cfgr_scs +*/ + void rcc_set_sysclk_source(u32 clk) { u32 reg32; @@ -259,6 +467,14 @@ void rcc_set_sysclk_source(u32 clk) RCC_CFGR = (reg32 | clk); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Multiplication Factor. + +@note This only has effect when the PLL is disabled. + +@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf +*/ + void rcc_set_pll_multiplication_factor(u32 mul) { u32 reg32; @@ -268,6 +484,14 @@ void rcc_set_pll_multiplication_factor(u32 mul) RCC_CFGR = (reg32 | (mul << 18)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Clock Source. + +@note This only has effect when the PLL is disabled. + +@param[in] pllsrc Unsigned int32. PLL clock source @ref rcc_cfgr_pcs +*/ + void rcc_set_pll_source(u32 pllsrc) { u32 reg32; @@ -277,6 +501,14 @@ void rcc_set_pll_source(u32 pllsrc) RCC_CFGR = (reg32 | (pllsrc << 16)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the HSE Frequency Divider used as PLL Clock Source. + +@note This only has effect when the PLL is disabled. + +@param[in] pllxtpre Unsigned int32. HSE division factor @ref rcc_cfgr_hsepre +*/ + void rcc_set_pllxtpre(u32 pllxtpre) { u32 reg32; @@ -286,6 +518,14 @@ void rcc_set_pllxtpre(u32 pllxtpre) RCC_CFGR = (reg32 | (pllxtpre << 17)); } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Setup the A/D Clock + +The ADC's have a common clock prescale setting. + +@param[in] adcpre u32. Prescale divider taken from @ref rcc_cfgr_adcpre +*/ + void rcc_set_adcpre(u32 adcpre) { u32 reg32; @@ -295,6 +535,12 @@ void rcc_set_adcpre(u32 adcpre) RCC_CFGR = (reg32 | (adcpre << 14)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the APB2 Prescale Factor. + +@param[in] ppre2 Unsigned int32. APB2 prescale factor @ref rcc_cfgr_apb2pre +*/ + void rcc_set_ppre2(u32 ppre2) { u32 reg32; @@ -304,6 +550,14 @@ void rcc_set_ppre2(u32 ppre2) RCC_CFGR = (reg32 | (ppre2 << 11)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the APB1 Prescale Factor. + +@note The APB1 clock frequency must not exceed 36MHz. + +@param[in] ppre1 Unsigned int32. APB1 prescale factor @ref rcc_cfgr_apb1pre +*/ + void rcc_set_ppre1(u32 ppre1) { u32 reg32; @@ -313,6 +567,12 @@ void rcc_set_ppre1(u32 ppre1) RCC_CFGR = (reg32 | (ppre1 << 8)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the AHB Prescale Factor. + +@param[in] hpre Unsigned int32. AHB prescale factor @ref rcc_cfgr_ahbpre +*/ + void rcc_set_hpre(u32 hpre) { u32 reg32; @@ -322,6 +582,17 @@ void rcc_set_hpre(u32 hpre) RCC_CFGR = (reg32 | (hpre << 4)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the USB Prescale Factor. + +The prescale factor can be set to 1 (no prescale) for use when the PLL clock is +48MHz, or 1.5 to generate the 48MHz USB clock from a 64MHz PLL clock. + +@note This bit cannot be reset while the USB clock is enabled. + +@param[in] usbpre Unsigned int32. USB prescale factor @ref rcc_cfgr_usbpre +*/ + void rcc_set_usbpre(u32 usbpre) { u32 reg32; @@ -331,16 +602,31 @@ void rcc_set_usbpre(u32 usbpre) RCC_CFGR = (reg32 | (usbpre << 22)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Get the System Clock Source. + +@returns Unsigned int32. System clock source: +@li 00 indicates HSE +@li 01 indicates LSE +@li 02 indicates PLL +*/ + u32 rcc_system_clock_source(void) { /* Return the clock source which is used as system clock. */ return ((RCC_CFGR & 0x000c) >> 2); } +/*-----------------------------------------------------------------------------*/ /* * These functions are setting up the whole clock system for the most common * input clock and output clock configurations. */ +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 64MHz from HSI + +*/ + void rcc_clock_setup_in_hsi_out_64mhz(void) { /* Enable internal high-speed oscillator. */ @@ -388,6 +674,11 @@ void rcc_clock_setup_in_hsi_out_64mhz(void) rcc_ppre2_frequency = 64000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 48MHz from HSI + +*/ + void rcc_clock_setup_in_hsi_out_48mhz(void) { /* Enable internal high-speed oscillator. */ @@ -436,6 +727,62 @@ void rcc_clock_setup_in_hsi_out_48mhz(void) rcc_ppre2_frequency = 48000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSI + +*/ + +void rcc_clock_setup_in_hsi_out_24mhz(void) { + /* Enable internal high-speed oscillator. */ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 12MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + + /* + * Sysclk is (will be) running with 24MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_0WS); + + /* + * Set the PLL multiplication factor to 6. + * 8MHz (internal) * 6 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 24MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL6); + + /* Select HSI/2 as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ppre1_frequency = 24000000; + rcc_ppre2_frequency = 24000000; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSE at 8MHz + +*/ + void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) { /* Enable internal high-speed oscillator. */ @@ -494,6 +841,11 @@ void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) rcc_ppre2_frequency = 24000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 72MHz from HSE at 8MHz + +*/ + void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) { /* Enable internal high-speed oscillator. */ @@ -552,6 +904,11 @@ void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) rcc_ppre2_frequency = 72000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSE at 12MHz + +*/ + void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) { /* Enable internal high-speed oscillator. */ @@ -610,6 +967,11 @@ void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) rcc_ppre2_frequency = 72000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSE at 16MHz + +*/ + void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) { /* Enable internal high-speed oscillator. */ @@ -668,6 +1030,12 @@ void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) rcc_ppre2_frequency = 72000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Reset the backup domain + +The backup domain register is reset to disable all controls. +*/ + void rcc_backupdomain_reset(void) { /* Set the backup domain software reset. */ @@ -676,3 +1044,5 @@ void rcc_backupdomain_reset(void) /* Clear the backup domain software reset. */ RCC_BDCR &= ~RCC_BDCR_BDRST; } +/**@}*/ + diff --git a/lib/stm32/f1/stm32f100x4.ld b/lib/stm32/f1/stm32f100x4.ld new file mode 100644 index 00000000..4c86aee8 --- /dev/null +++ b/lib/stm32/f1/stm32f100x4.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/lib/stm32/f1/stm32f100x6.ld b/lib/stm32/f1/stm32f100x6.ld new file mode 100644 index 00000000..23f77f3f --- /dev/null +++ b/lib/stm32/f1/stm32f100x6.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +/* Linker script for STM32F100x6, 32K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/lib/stm32/f1/stm32f100x8.ld b/lib/stm32/f1/stm32f100x8.ld new file mode 100644 index 00000000..e0aa041f --- /dev/null +++ b/lib/stm32/f1/stm32f100x8.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +/* Linker script for STM32F100x8, 64K flash, 8K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/lib/stm32/f1/stm32f100xb.ld b/lib/stm32/f1/stm32f100xb.ld new file mode 100644 index 00000000..83d64fdd --- /dev/null +++ b/lib/stm32/f1/stm32f100xb.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * 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 . + */ + +/* Linker script for STM32F100xB, 128K flash, 8K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/lib/stm32/f1/stm32f100xc.ld b/lib/stm32/f1/stm32f100xc.ld new file mode 100644 index 00000000..30a894af --- /dev/null +++ b/lib/stm32/f1/stm32f100xc.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +/* Linker script for STM32F100xC, 256K flash, 24K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 24K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/lib/stm32/f1/stm32f100xd.ld b/lib/stm32/f1/stm32f100xd.ld new file mode 100644 index 00000000..b5074358 --- /dev/null +++ b/lib/stm32/f1/stm32f100xd.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +/* Linker script for STM32F100xD, 384K flash, 32K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/lib/stm32/f1/stm32f100xe.ld b/lib/stm32/f1/stm32f100xe.ld new file mode 100644 index 00000000..a12d1ff7 --- /dev/null +++ b/lib/stm32/f1/stm32f100xe.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 . + */ + +/* Linker script for STM32F100xE, 512K flash, 32K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/lib/stm32/f1/timer.c b/lib/stm32/f1/timer.c index cf5b4113..c5ea921f 100644 --- a/lib/stm32/f1/timer.c +++ b/lib/stm32/f1/timer.c @@ -1,3 +1,71 @@ +/** @defgroup STM32F1xx-timer-file Timers + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Timers + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Edward Cheeseman + +@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 STM32F1xx 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). + +@todo Add timer DMA burst settings + +@section tim_api_ex Basic TIMER handling API. + +Enable the timer clock first. The timer mode sets the clock division ratio, +the count alignment (edge or centred) and count direction. Finally enable the timer. + +The timer output compare block produces a signal that can be configured for +output to a pin or passed to other peripherals for use as a trigger. In all cases +the output compare mode must be set to define how the output responds to a compare +match, and the output must be enabled. If output to a pin is required, enable the +appropriate GPIO clock and set the pin to alternate output mode. + +Example: Timer 2 with 2x clock divide, edge aligned and up counting. +@code + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM2EN); + timer_reset(TIM2); + timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT_MUL_2, + TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + ... + timer_set_period(TIM2, 1000); + timer_enable_counter(TIM2); +@endcode +Example: Timer 1 with PWM output, no clock divide and centre alignment. Set the +Output Compare mode to PWM and enable the output of channel 1. Note that for the +advanced timers the break functionality must be enabled before the signal will +appear at the output, even though break is not being used. This is in addition to +the normal output enable. Enable the alternate function clock (APB2 only) and port A +clock. Set ports A8 and A9 (timer 1 channel 1 compare outputs) to alternate function +push-pull outputs where the PWM output will appear. + +@code + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8 | GPIO9); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN); + timer_reset(TIM1); + timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_CENTER_1, TIM_CR1_DIR_UP); + timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM2); + timer_enable_oc_output(TIM1, TIM_OC1); + timer_enable_break_main_output(TIM1); + timer_set_oc_value(TIM1, TIM_OC1, 200); + timer_set_period(TIM1, 1000); + timer_enable_counter(TIM1); +@endcode + +@todo input capture example + +*/ /* * This file is part of the libopencm3 project. * @@ -25,9 +93,22 @@ * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP); */ +/**@{*/ + #include #include +/*---------------------------------------------------------------------------*/ +/** @brief Reset a Timer. + +The counter and all its associated configuration registers +are placed in the reset condition. The reset is effected via the RCC peripheral reset +system. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base + (TIM9 .. TIM14 not yet supported here). +*/ + void timer_reset(u32 timer_peripheral) { switch (timer_peripheral) { @@ -93,31 +174,84 @@ void timer_reset(u32 timer_peripheral) } } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Interrupts for a Timer + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt enable bits to be set +*/ + void timer_enable_irq(u32 timer_peripheral, u32 irq) { TIM_DIER(timer_peripheral) |= irq; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Interrupts for a Timer. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt enable bits to be cleared +*/ + void timer_disable_irq(u32 timer_peripheral, u32 irq) { TIM_DIER(timer_peripheral) &= ~irq; } +/*---------------------------------------------------------------------------*/ +/** @brief Read a Status Flag. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] flag Unsigned int32. Status register flag @ref tim_sr_values. +@returns boolean: flag set. +*/ + bool timer_get_flag(u32 timer_peripheral, u32 flag) { - if (((TIM_SR(timer_peripheral) & flag) != 0) && - ((TIM_DIER(timer_peripheral) & flag) != 0)) { + if ((TIM_SR(timer_peripheral) & flag) != 0) { return true; } return false; } +/*---------------------------------------------------------------------------*/ +/** @brief Clear a Status Flag. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] flag Unsigned int32. @ref tim_sr_values. Status register flag. +*/ + void timer_clear_flag(u32 timer_peripheral, u32 flag) { TIM_SR(timer_peripheral) &= ~flag; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer Mode. + +The modes are: + +@li Clock divider ratio (to form the sampling clock for the input filters, +and the dead-time clock in the advanced timers 1 and 8) +@li Edge/centre alignment +@li Count direction + +The alignment and count direction are effective only for timers 1 to 5 and 8 +while the clock divider ratio is effective for all timers except 6,7 +The remaining timers are limited hardware timers which do not support these mode +settings. + +@note: When center alignment mode is selected, count direction is controlled by +hardware and cannot be written. The count direction setting has no effect +in this case. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base (TIM1, TIM2 ... TIM5, TIM8) +@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref tim_x_cr1_cdr +@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms +@param[in] direction Unsigned int32. Count direction in bit 4,: @ref tim_x_cr1_dir +*/ + void timer_set_mode(u32 timer_peripheral, u32 clock_div, u32 alignment, u32 direction) { @@ -132,6 +266,16 @@ void timer_set_mode(u32 timer_peripheral, u32 clock_div, TIM_CR1(timer_peripheral) = cr1; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Filter and Dead-time Clock Divider Ratio. + +This forms the sampling clock for the input filters and the dead-time clock +in the advanced timers 1 and 8, by division from the timer clock. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref tim_x_cr1_cdr +*/ + void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) { clock_div &= TIM_CR1_CKD_CK_INT_MASK; @@ -139,16 +283,44 @@ void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) TIM_CR1(timer_peripheral) |= clock_div; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Auto-Reload Buffering. + +During counter operation this causes the counter to be loaded from its +auto-reload register only at the next update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_preload(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Auto-Reload Buffering. + +This causes the counter to be loaded immediately with a new count value when the +auto-reload register is written, so that the new value becomes effective for the +current count cycle rather than for the cycle following an update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_preload(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE; } +/*---------------------------------------------------------------------------*/ +/** @brief Specify the counter alignment mode. + +The mode can be edge aligned or centered. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms +*/ + void timer_set_alignment(u32 timer_peripheral, u32 alignment) { alignment &= TIM_CR1_CMS_MASK; @@ -156,128 +328,369 @@ void timer_set_alignment(u32 timer_peripheral, u32 alignment) TIM_CR1(timer_peripheral) |= alignment; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Count Up. + +This has no effect if the timer is set to center aligned. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_direction_up(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Count Down. + +This has no effect if the timer is set to center aligned. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_direction_down(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Timer for One Cycle and Stop. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_one_shot_mode(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_OPM; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Timer to Run Continuously. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_continuous_mode(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Generate Update IRQ or DMA on any Event. + +The events which will generate an interrupt or DMA request can be +@li a counter underflow/overflow, +@li a forced update, +@li an event from the slave mode controller. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_update_on_any(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Generate Update IRQ or DMA only from Under/Overflow Events. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_update_on_overflow(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_URS; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Update Events. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_update_event(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Update Events. + +Update events are not generated and the shadow registers keep their values. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_update_event(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable the timer to start counting. + +This should be called after the timer initial configuration has been completed. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_counter(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_CEN; } +/*---------------------------------------------------------------------------*/ +/** @brief Stop the timer from counting. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_counter(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer Output Idle States High. + +This determines the value of the timer output compare when it enters idle state. + +@sa @ref timer_set_oc_idle_state_set + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref tim_x_cr2_ois. +If several settings are to be made, use the logical OR of the output control values. +*/ + void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs) { - TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer Output Idle States Low. + +This determines the value of the timer output compare when it enters idle state. + +@sa @ref timer_set_oc_idle_state_unset + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref tim_x_cr2_ois +*/ + void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs) { - TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer 1 Input to XOR of Three Channels. + +The first timer capture input is formed from the XOR of the first three timer input +channels 1, 2, 3. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_set_ti1_ch123_xor(u32 timer_peripheral) { TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer 1 Input to Channel 1. + +The first timer capture input is taken from the timer input channel 1 only. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_set_ti1_ch1(u32 timer_peripheral) { TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Master Mode + +This sets the Trigger Output TRGO for synchronizing with slave timers or passing as +an internal trigger to the ADC or DAC. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] mode Unsigned int32. Master Mode @ref tim_mastermode +*/ + void timer_set_master_mode(u32 timer_peripheral, u32 mode) { TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK; TIM_CR2(timer_peripheral) |= mode; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer DMA Requests on Capture/Compare Events. + +Capture/compare events will cause DMA requests to be generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_set_dma_on_compare_event(u32 timer_peripheral) { TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer DMA Requests on Update Events. + +Update events will cause DMA requests to be generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_set_dma_on_update_event(u32 timer_peripheral) { TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Capture/Compare Control Update with Trigger. + +If the capture/compare control bits CCxE, CCxNE and OCxM are set to be +preloaded, they are updated by software generating the COMG event (@ref +timer_generate_event) or when a rising edge occurs on the trigger input TRGI. + +@note This setting is only valid for the advanced timer channels with complementary +outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral) { - TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Capture/Compare Control Update with Trigger. + +If the capture/compare control bits CCxE, CCxNE and OCxM are set to be +preloaded, they are updated by software generating the COMG event (@ref +timer_generate_event). + +@note This setting is only valid for the advanced timer channels with complementary +outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral) { - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Capture/Compare Control Preload. + +The capture/compare control bits CCxE, CCxNE and OCxM are set to be preloaded +when a COM event occurs. + +@note This setting is only valid for the advanced timer channels with complementary +outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral) { - TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Capture/Compare Control Preload. + +The capture/compare control bits CCxE, CCxNE and OCxM preload is disabled. + +@note This setting is only valid for the advanced timer channels with complementary +outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral) { - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Value for the Timer Prescaler. + +The timer clock is prescaled by the 16 bit scale value plus 1. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] value Unsigned int32. Prescaler values 0...0xFFFF. +*/ + void timer_set_prescaler(u32 timer_peripheral, u32 value) { TIM_PSC(timer_peripheral) = value; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Value for the Timer Repetition Counter. + +A timer update event is generated only after the specified number of repeat +count cycles have been completed. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] value Unsigned int32. Repetition values 0...0xFF. +*/ + void timer_set_repetition_counter(u32 timer_peripheral, u32 value) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_RCR(timer_peripheral) = value; } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Period + +Specify the timer period in the auto-reload register. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] period Unsigned int32. Period in counter clock ticks. +*/ + void timer_set_period(u32 timer_peripheral, u32 period) { TIM_ARR(timer_peripheral) = period; } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Clear Function + +When this is enabled, the output compare signal is cleared when a high is detected +on the external trigger input. This works in the output compare and PWM modes only +(not forced mode). +The output compare signal remains off until the next update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -296,11 +709,19 @@ void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) case TIM_OC1N: case TIM_OC2N: case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ + /* Ignoring as oc clear enable only applies to the whole channel. */ break; } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare Clear Function + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -319,11 +740,24 @@ void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) case TIM_OC1N: case TIM_OC2N: case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ + /* Ignoring as oc clear enable only applies to the whole channel. */ break; } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Fast Mode + +When this is enabled, the output compare signal is forced to the compare state +by a trigger input, independently of the compare match. This speeds up the +setting of the output compare to 3 clock cycles as opposed to at least 5 in the +slow mode. This works in the PWM1 and PWM2 modes only. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -347,6 +781,17 @@ void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Slow Mode + +This disables the fast compare mode and the output compare depends on the +counter and compare register values. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -370,6 +815,29 @@ void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Mode + +Specifies how the comparator output will respond to a compare match. The mode can be: +@li Frozen - the output does not respond to a match. +@li Active - the output assumes the active state on the first match. +@li Inactive - the output assumes the inactive state on the first match. +@li Toggle - The output switches between active and inactive states on each match. +@li Force inactive. The output is forced low regardless of the compare state. +@li Force active. The output is forced high regardless of the compare state. +@li PWM1 - The output is active when the counter is less than the compare register contents +and inactive otherwise. +@li PWM2 - The output is inactive when the counter is less than the compare register contents +and active otherwise. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +@param[in] oc_mode enum ::tim_oc_mode. OC mode designators. + TIM_OCM_FROZEN, TIM_OCM_ACTIVE, TIM_OCM_INACTIVE, TIM_OCM_TOGGLE, + TIM_OCM_FORCE_LOW, TIM_OCM_FORCE_HIGH, TIM_OCM_PWM1, TIM_OCM_PWM2 +*/ + void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, enum tim_oc_mode oc_mode) { @@ -510,6 +978,14 @@ void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Preload Register + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -533,6 +1009,14 @@ void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare Preload Register + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action) +*/ + void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -556,6 +1040,16 @@ void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set the Output Polarity High + +The polarity of the channel output is set active high. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -601,6 +1095,16 @@ void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set the Output Polarity Low + +The polarity of the channel output is set active low. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -646,6 +1150,16 @@ void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare + +The channel output compare functionality is enabled. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -691,6 +1205,16 @@ void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare + +The channel output compare functionality is disabled. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -736,6 +1260,19 @@ void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer set Output Compare Idle State High + +@sa Similar function suitable for multiple OC idle state settings +@ref timer_set_output_idle_state + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) { /* Acting for TIM1 and TIM8 only. */ @@ -767,6 +1304,19 @@ void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Idle State Low + +@sa Similar function suitable for multiple OC idle state settings +@ref timer_reset_output_idle_state + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) { /* Acting for TIM1 and TIM8 only. */ @@ -798,6 +1348,19 @@ void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Value + +This is a convenience function to set the OC preload register value for loading +to the compare register. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base + (TIM9 .. TIM14 not yet supported here). +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +@param[in] value Unsigned int32. Compare value. +*/ + void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) { switch (oc_id) { @@ -821,145 +1384,382 @@ void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) } } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Output in Break + +Enables the output in the Break feature of an advanced timer. This does not +enable the break functionality itself but only sets the Master Output Enable in +the Break and Deadtime Register. + +@note This setting is only valid for the advanced timers. + +@note It is necessary to call this function to enable the output on an advanced +timer even if break or deadtime features are not being used. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_enable_break_main_output(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Output in Break + +Disables the output in the Break feature of an advanced timer. This clears +the Master Output Enable in the Break and Deadtime Register. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_disable_break_main_output(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Automatic Output in Break + +Enables the automatic output feature of the Break function of an advanced +timer so that the output is re-enabled at the next update event following a +break event. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_enable_break_automatic_output(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Automatic Output in Break + +Disables the automatic output feature of the Break function of an advanced +timer so that the output is re-enabled at the next update event following a +break event. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_disable_break_automatic_output(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE; } +/*---------------------------------------------------------------------------*/ +/** @brief Activate Break when Input High + +Sets the break function to activate when the break input becomes high. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_set_break_polarity_high(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP; } +/*---------------------------------------------------------------------------*/ +/** @brief Activate Break when Input Low + +Sets the break function to activate when the break input becomes low. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_set_break_polarity_low(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Break + +Enables the break function of an advanced timer. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_enable_break(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Break + +Disables the break function of an advanced timer. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_disable_break(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Off-State in Run Mode + +Enables the off-state in run mode for the break function of an advanced +timer in which the complementary outputs have been configured. It has no effect +if no complementary output is present. When the capture-compare output is +disabled while the complementary output is enabled, the output is set to its +inactive level as defined by the output polarity. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + 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; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Off-State in Run Mode + +Disables the off-state in run mode for the break function of an advanced +timer in which the complementary outputs have been configured. It has no effect +if no complementary output is present. When the capture-compare output is +disabled, the output is also disabled. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + 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; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Off-State in Idle Mode + +Enables the off-state in idle mode for the break function of an advanced +timer. When the master output is disabled the output is set to its +inactive level as defined by the output polarity. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + 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; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Off-State in Idle Mode + +Disables the off-state in idle mode for the break function of an advanced +timer. When the master output is disabled the output is also disabled. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + 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; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Lock Bits + +Set the lock bits for an advanced timer. Three levels of lock providing +protection against software errors. Once written they cannot be changed until a +timer reset has occurred. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +@param[in] lock Unsigned int32. Lock specification @ref tim_lock +*/ + void timer_set_break_lock(u32 timer_peripheral, u32 lock) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= lock; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Deadtime + +The deadtime and sampling clock (DTSC) is set in the clock division ratio part of the +timer mode settings. The deadtime count is an 8 bit value defined in terms of the +number of DTSC cycles: + +@li Bit 7 = 0, deadtime = bits(6:0) +@li Bits 7:6 = 10, deadtime = 2x(64+bits(5:0)) +@li Bits 7:5 = 110, deadtime = 8x(32+bits(5:0)) +@li Bits 7:5 = 111, deadtime = 16x(32+bits(5:0)) + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +@param[in] deadtime Unsigned int32. Deadtime count specification as defined above. +*/ + void timer_set_deadtime(u32 timer_peripheral, u32 deadtime) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= deadtime; } +/*---------------------------------------------------------------------------*/ +/** @brief Force generate a timer event. + +The event specification consists of 8 possible events that can be forced on the +timer. The forced events are automatically cleared by hardware. The UG event is +useful to cause shadow registers to be preloaded before the timer is started to +avoid uncertainties in the first cycle in case an update event may never be +generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] event Unsigned int32. Event specification @ref tim_event_gen +*/ + void timer_generate_event(u32 timer_peripheral, u32 event) { TIM_EGR(timer_peripheral) |= event; } +/*---------------------------------------------------------------------------*/ +/** @brief Read Counter + +Read back the value of a timer's counter register contents + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@returns Unsigned int32. Counter value. +*/ + u32 timer_get_counter(u32 timer_peripheral) { return TIM_CNT(timer_peripheral); } -void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt) +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Capture Filter Parameters + +Set the input filter parameters for an input channel, specifying: +@li the frequency of sampling from the Deadtime and Sampling clock +(@see @ref timer_set_clock_division) +@li the number of events that must occur before a transition is considered valid. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] flt ::tim_ic_filter. Input Capture Filter identifier. +*/ + +void timer_ic_set_filter(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_filter flt) { switch (ic) { case TIM_IC1: - TIM_CCMR1(timer) &= ~TIM_CCMR1_IC1F_MASK; - TIM_CCMR1(timer) |= flt << 4; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1F_MASK; + TIM_CCMR1(timer_peripheral) |= flt << 4; break; case TIM_IC2: - TIM_CCMR1(timer) &= ~TIM_CCMR1_IC2F_MASK; - TIM_CCMR1(timer) |= flt << 12; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2F_MASK; + TIM_CCMR1(timer_peripheral) |= flt << 12; break; case TIM_IC3: - TIM_CCMR2(timer) &= ~TIM_CCMR2_IC3F_MASK; - TIM_CCMR2(timer) |= flt << 4; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3F_MASK; + TIM_CCMR2(timer_peripheral) |= flt << 4; break; case TIM_IC4: - TIM_CCMR2(timer) &= ~TIM_CCMR2_IC4F_MASK; - TIM_CCMR2(timer) |= flt << 12; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4F_MASK; + TIM_CCMR2(timer_peripheral) |= flt << 12; break; } } -void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc) +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Capture Prescaler + +Set the number of events between each capture. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler. +*/ + +void timer_ic_set_prescaler(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_psc psc) { switch (ic) { case TIM_IC1: - TIM_CCMR1(timer) &= ~TIM_CCMR1_IC1PSC_MASK; - TIM_CCMR1(timer) |= psc << 2; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1PSC_MASK; + TIM_CCMR1(timer_peripheral) |= psc << 2; break; case TIM_IC2: - TIM_CCMR1(timer) &= ~TIM_CCMR1_IC2PSC_MASK; - TIM_CCMR1(timer) |= psc << 10; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2PSC_MASK; + TIM_CCMR1(timer_peripheral) |= psc << 10; break; case TIM_IC3: - TIM_CCMR2(timer) &= ~TIM_CCMR2_IC3PSC_MASK; - TIM_CCMR2(timer) |= psc << 4; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3PSC_MASK; + TIM_CCMR2(timer_peripheral) |= psc << 4; break; case TIM_IC4: - TIM_CCMR2(timer) &= ~TIM_CCMR2_IC4PSC_MASK; - TIM_CCMR2(timer) |= psc << 10; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4PSC_MASK; + TIM_CCMR2(timer_peripheral) |= psc << 10; break; } } -void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in) +/*---------------------------------------------------------------------------*/ +/** @brief Set Capture/Compare Channel Direction/Input + +The Capture/Compare channel is defined as output (compare) or input with the input +mapping specified: + +@li channel is configured as output +@li channel is configured as input and mapped on corresponding input +@li channel is configured as input and mapped on alternate input +(TI2 for channel 1, TI1 for channel 2, TI4 for channel 3, TI3 for channel 4) +@li channel is configured as input and is mapped on TRC (requires an +internal trigger input selected through TS bit + +@note not all combinations of the input and channel are valid, see datasheets. +@note these parameters are writable only when the channel is off. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] in ::tim_ic_input. Input Capture channel direction and source input. +*/ + +void timer_ic_set_input(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_input in) { in &= 3; @@ -971,71 +1771,139 @@ void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in) switch (ic) { case TIM_IC1: - TIM_CCMR1(timer) &= ~TIM_CCMR1_CC1S_MASK; - TIM_CCMR1(timer) |= in; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; + TIM_CCMR1(timer_peripheral) |= in; break; case TIM_IC2: - TIM_CCMR1(timer) &= ~TIM_CCMR1_CC2S_MASK; - TIM_CCMR1(timer) |= in << 8; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; + TIM_CCMR1(timer_peripheral) |= in << 8; break; case TIM_IC3: - TIM_CCMR2(timer) &= ~TIM_CCMR2_CC3S_MASK; - TIM_CCMR2(timer) |= in; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; + TIM_CCMR2(timer_peripheral) |= in; break; case TIM_IC4: - TIM_CCMR2(timer) &= ~TIM_CCMR2_CC4S_MASK; - TIM_CCMR2(timer) |= in << 8; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; + TIM_CCMR2(timer_peripheral) |= in << 8; break; } } -void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol) +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Polarity + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] pol ::tim_ic_pol. Input Capture polarity. +*/ + +void timer_ic_set_polarity(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_pol pol) { if (pol) - TIM_CCER(timer) |= (0x2 << (ic * 4)); + TIM_CCER(timer_peripheral) |= (0x2 << (ic * 4)); else - TIM_CCER(timer) &= ~(0x2 << (ic * 4)); + TIM_CCER(timer_peripheral) &= ~(0x2 << (ic * 4)); } -void timer_ic_enable(u32 timer, enum tim_ic_id ic) +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Input Capture + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +*/ + +void timer_ic_enable(u32 timer_peripheral, enum tim_ic_id ic) { - TIM_CCER(timer) |= (0x1 << (ic * 4)); + TIM_CCER(timer_peripheral) |= (0x1 << (ic * 4)); } -void timer_ic_disable(u32 timer, enum tim_ic_id ic) +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Input Capture + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +*/ + +void timer_ic_disable(u32 timer_peripheral, enum tim_ic_id ic) { - TIM_CCER(timer) &= ~(0x1 << (ic * 4)); + TIM_CCER(timer_peripheral) &= ~(0x1 << (ic * 4)); } -void timer_slave_set_filter(u32 timer, enum tim_ic_filter flt) +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Filter Parameters for Slave + +Set the input filter parameters for the external trigger, specifying: +@li the frequency of sampling from the Deadtime and Sampling clock +(@see @ref timer_set_clock_division) +@li the number of events that must occur before a transition is considered valid. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] flt ::tim_ic_filter. Input Capture Filter identifier. +*/ + +void timer_slave_set_filter(u32 timer_peripheral, enum tim_ic_filter flt) { - TIM_SMCR(timer) &= ~TIM_SMCR_ETF_MASK; - TIM_SMCR(timer) |= flt << 8; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETF_MASK; + TIM_SMCR(timer_peripheral) |= flt << 8; } -void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc) +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Prescaler for Slave + +Set the external trigger frequency division ratio. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler. +*/ + +void timer_slave_set_prescaler(u32 timer_peripheral, enum tim_ic_psc psc) { - TIM_SMCR(timer) &= ~TIM_SMCR_ETPS_MASK; - TIM_SMCR(timer) |= psc << 12; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETPS_MASK; + TIM_SMCR(timer_peripheral) |= psc << 12; } -void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol) +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Polarity for Slave + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] pol ::tim_ic_pol. Input Capture polarity. +*/ + +void timer_slave_set_polarity(u32 timer_peripheral, enum tim_ic_pol pol) { if (pol) - TIM_SMCR(timer) |= TIM_SMCR_ETP; + TIM_SMCR(timer_peripheral) |= TIM_SMCR_ETP; else - TIM_SMCR(timer) &= ~TIM_SMCR_ETP; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETP; } -void timer_slave_set_mode(u32 timer, u8 mode) +/*---------------------------------------------------------------------------*/ +/** @brief Set Slave Mode + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] mode Unsigned int8. Slave mode @ref tim_sms +*/ + +void timer_slave_set_mode(u32 timer_peripheral, u8 mode) { - TIM_SMCR(timer) &= ~TIM_SMCR_SMS_MASK; - TIM_SMCR(timer) |= mode; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_SMS_MASK; + TIM_SMCR(timer_peripheral) |= mode; } -void timer_slave_set_trigger(u32 timer, u8 trigger) +/*---------------------------------------------------------------------------*/ +/** @brief Set Slave Trigger Source + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] trigger Unsigned int8. Slave trigger source @ref tim_ts +*/ + +void timer_slave_set_trigger(u32 timer_peripheral, u8 trigger) { - TIM_SMCR(timer) &= ~TIM_SMCR_TS_MASK; - TIM_SMCR(timer) |= trigger; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_TS_MASK; + TIM_SMCR(timer_peripheral) |= trigger; } +/* TODO Timer DMA burst */ + +/**@}*/ + diff --git a/lib/stm32/f1/vector.c b/lib/stm32/f1/vector.c index 119ce309..f496ae4b 100644 --- a/lib/stm32/f1/vector.c +++ b/lib/stm32/f1/vector.c @@ -19,8 +19,8 @@ #define WEAK __attribute__ ((weak)) -/* Symbols exported by the linker script(s). */ -extern unsigned __exidx_end, _data, _edata, _ebss, _stack; +/* Symbols exported by the linker script(s): */ +extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; void main(void); void reset_handler(void); @@ -197,7 +197,7 @@ void reset_handler(void) __asm__("MSR msp, %0" : : "r"(&_stack)); - for (src = &__exidx_end, dest = &_data; dest < &_edata; src++, dest++) + for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) *dest = *src; while (dest < &_ebss) diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile index e0f8d95a..bd6f2758 100644 --- a/lib/stm32/f2/Makefile +++ b/lib/stm32/f2/Makefile @@ -33,27 +33,4 @@ OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \ VPATH += ../../usb:../ -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -endif - -all: $(LIBNAME).a - -$(LIBNAME).a: $(OBJS) - @printf " AR $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(AR) $(ARFLAGS) $@ $^ - -%.o: %.c - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -clean: - @printf " CLEAN lib/stm32/f2\n" - $(Q)rm -f *.o *.d - $(Q)rm -f $(LIBNAME).a - -.PHONY: clean - --include $(OBJS:.o=.d) - +include ../../Makefile.include diff --git a/lib/stm32/f2/gpio.c b/lib/stm32/f2/gpio.c index 7a381204..984cddb1 100644 --- a/lib/stm32/f2/gpio.c +++ b/lib/stm32/f2/gpio.c @@ -111,7 +111,7 @@ u16 gpio_get(u32 gpioport, u16 gpios) void gpio_toggle(u32 gpioport, u16 gpios) { - GPIO_ODR(gpioport) = GPIO_IDR(gpioport) ^ gpios; + GPIO_ODR(gpioport) ^= gpios; } u16 gpio_port_read(u32 gpioport) @@ -135,5 +135,8 @@ void gpio_port_config_lock(u32 gpioport, u16 gpios) 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/f2/libopencm3_stm32f2.ld b/lib/stm32/f2/libopencm3_stm32f2.ld index a64a1f77..9d165f68 100644 --- a/lib/stm32/f2/libopencm3_stm32f2.ld +++ b/lib/stm32/f2/libopencm3_stm32f2.ld @@ -30,21 +30,18 @@ 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 /* - * Another section used by C++ stuff, appears when using newlib with - * 64bit (long long) printf support - */ + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ .ARM.extab : { *(.ARM.extab*) } >rom @@ -54,21 +51,23 @@ SECTIONS __exidx_end = .; } >rom - . = ORIGIN(ram); + . = ALIGN(4); + _etext = .; - .data : AT (__exidx_end) { + .data : { _data = .; *(.data*) /* Read-write initialized data */ . = ALIGN(4); _edata = .; - } >ram + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); .bss : { *(.bss*) /* Read-write zero initialized data */ *(COMMON) . = ALIGN(4); _ebss = .; - } >ram AT >rom + } >ram /* * The .eh_frame section appears to be used for C++ exception handling. diff --git a/lib/stm32/f2/vector.c b/lib/stm32/f2/vector.c index 64d2426b..3429bfb0 100644 --- a/lib/stm32/f2/vector.c +++ b/lib/stm32/f2/vector.c @@ -21,7 +21,7 @@ #define WEAK __attribute__ ((weak)) /* Symbols exported by the linker script(s): */ -extern unsigned __exidx_end, _data, _edata, _ebss, _stack; +extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; void main(void); void reset_handler(void); @@ -224,7 +224,7 @@ void reset_handler(void) __asm__("MSR msp, %0" : : "r"(&_stack)); - for (src = &__exidx_end, dest = &_data; dest < &_edata; src++, dest++) + for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) *dest = *src; while (dest < &_ebss) diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index f8b4dd28..5760d29b 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -34,27 +34,4 @@ OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \ VPATH += ../../usb:../ -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -endif - -all: $(LIBNAME).a - -$(LIBNAME).a: $(OBJS) - @printf " AR $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(AR) $(ARFLAGS) $@ $^ - -%.o: %.c - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -clean: - @printf " CLEAN lib/stm32/f4\n" - $(Q)rm -f *.o *.d - $(Q)rm -f $(LIBNAME).a - -.PHONY: clean - --include $(OBJS:.o=.d) - +include ../../Makefile.include diff --git a/lib/stm32/f4/gpio.c b/lib/stm32/f4/gpio.c index dea37208..1d7739dd 100644 --- a/lib/stm32/f4/gpio.c +++ b/lib/stm32/f4/gpio.c @@ -111,7 +111,7 @@ u16 gpio_get(u32 gpioport, u16 gpios) void gpio_toggle(u32 gpioport, u16 gpios) { - GPIO_ODR(gpioport) = GPIO_IDR(gpioport) ^ gpios; + GPIO_ODR(gpioport) ^= gpios; } u16 gpio_port_read(u32 gpioport) @@ -135,5 +135,8 @@ void gpio_port_config_lock(u32 gpioport, u16 gpios) 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/libopencm3_stm32f4.ld b/lib/stm32/f4/libopencm3_stm32f4.ld index 0624b96d..9d165f68 100644 --- a/lib/stm32/f4/libopencm3_stm32f4.ld +++ b/lib/stm32/f4/libopencm3_stm32f4.ld @@ -30,8 +30,6 @@ ENTRY(reset_handler) /* Define sections. */ SECTIONS { - . = ORIGIN(rom); - .text : { *(.vectors) /* Vector table */ *(.text*) /* Program code */ @@ -40,14 +38,20 @@ SECTIONS . = ALIGN(4); } >rom - /* exception index - required due to libgcc.a issuing /0 exceptions */ - __exidx_start = .; + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom .ARM.exidx : { - *(.ARM.exidx*) - } > rom - __exidx_end = .; - + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + . = ALIGN(4); _etext = .; .data : { @@ -56,6 +60,7 @@ SECTIONS . = ALIGN(4); _edata = .; } >ram AT >rom + _data_loadaddr = LOADADDR(.data); .bss : { *(.bss*) /* Read-write zero initialized data */ @@ -64,10 +69,11 @@ SECTIONS _ebss = .; } >ram - /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ - .ARM.extab : { - *(.ARM.extab*) - } >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 = .; diff --git a/lib/stm32/f4/vector.c b/lib/stm32/f4/vector.c index 1c901da7..3429bfb0 100644 --- a/lib/stm32/f4/vector.c +++ b/lib/stm32/f4/vector.c @@ -21,7 +21,7 @@ #define WEAK __attribute__ ((weak)) /* Symbols exported by the linker script(s): */ -extern unsigned _etext, _data, _edata, _ebss, _stack; +extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; void main(void); void reset_handler(void); @@ -224,7 +224,7 @@ void reset_handler(void) __asm__("MSR msp, %0" : : "r"(&_stack)); - for (src = &_etext, dest = &_data; dest < &_edata; src++, dest++) + for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) *dest = *src; while (dest < &_ebss) diff --git a/lib/stm32/iwdg.c b/lib/stm32/iwdg.c new file mode 100644 index 00000000..251bec1e --- /dev/null +++ b/lib/stm32/iwdg.c @@ -0,0 +1,144 @@ +/** @defgroup STM32F_iwdg_file IWDG + +@ingroup STM32F_files + +@brief libopencm3 STM32F1xx Independent Watchdog Timer + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +@date 18 August 2012 + +This library supports the Independent Watchdog Timer System in the STM32F1xx +series of ARM Cortex Microcontrollers by ST Microelectronics. + +The watchdog timer uses the LSI (low speed internal) clock which is low power +and continues to operate during stop and standby modes. Its frequency is +nominally 32kHz (40kHz for the STM32F1xx series) but can vary from as low +as 17kHz up to 60kHz (refer to datasheet electrical characteristics). + +Note that the User Configuration option byte provides a means of automatically +enabling the IWDG timer at power on (with counter value 0xFFF). If the +relevant bit is not set, the IWDG timer must be enabled by software. + +@note: Tested: CPU STM32F103RET6, Board ET-ARM Stamp STM32 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * 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 . + */ + +/**@{*/ + +#include + +#define LSI_FREQUENCY 32000 +#define COUNT_LENGTH 12 +#define COUNT_MASK ((1 << COUNT_LENGTH)-1) + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Enable Watchdog Timer + +The watchdog timer is started. The timeout period defaults to 512 milliseconds +unless it has been previously defined. + +*/ + +void iwdg_start(void) +{ + IWDG_KR = IWDG_KR_START; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Set Period in Milliseconds + +The countdown period is converted into count and prescale values. The maximum +period is 32.76 seconds; values above this are truncated. Periods less than 1ms +are not supported by this library. + +A delay of up to 5 clock cycles of the LSI clock (about 156 microseconds) +can occasionally occur if the prescale or preload registers are currently busy +loading a previous value. + +@param[in] period u32 Period in milliseconds (< 32760) from a watchdog reset until +a system reset is issued. +*/ + +void iwdg_set_period_ms(u32 period) +{ +u32 count, prescale, reload, exponent; +/* Set the count to represent ticks of the 32kHz LSI clock */ + count = (period << 5); +/* Strip off the first 12 bits to get the prescale value required */ + prescale = (count >> 12); + if (prescale > 256) {exponent = IWDG_PR_DIV256; reload = COUNT_MASK;} + else if (prescale > 128) {exponent = IWDG_PR_DIV256; reload = (count >> 8);} + else if (prescale > 64) {exponent = IWDG_PR_DIV128; reload = (count >> 7);} + else if (prescale > 32) {exponent = IWDG_PR_DIV64; reload = (count >> 6);} + else if (prescale > 16) {exponent = IWDG_PR_DIV32; reload = (count >> 5);} + else if (prescale > 8) {exponent = IWDG_PR_DIV16; reload = (count >> 4);} + else if (prescale > 4) {exponent = IWDG_PR_DIV8; reload = (count >> 3);} + else {exponent = IWDG_PR_DIV4; reload = (count >> 2);} +/* Avoid the undefined situation of a zero count */ + if (count == 0) count = 1; + + while (iwdg_prescaler_busy()); + IWDG_KR = IWDG_KR_UNLOCK; + IWDG_PR = exponent; + while (iwdg_reload_busy()); + IWDG_KR = IWDG_KR_UNLOCK; + IWDG_RLR = (reload & COUNT_MASK); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Get Reload Register Status + +@returns boolean: TRUE if the reload register is busy and unavailable for loading +a new count value. +*/ + +bool iwdg_reload_busy(void) +{ + return (IWDG_SR & IWDG_SR_RVU); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Get Prescaler Register Status + +@returns boolean: TRUE if the prescaler register is busy and unavailable for loading +a new period value. +*/ + +bool iwdg_prescaler_busy(void) +{ + return (IWDG_SR & IWDG_SR_PVU); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG reset Watchdog Timer + +The watchdog timer is reset. The counter restarts from the value in the reload +register. +*/ + +void iwdg_reset(void) +{ + IWDG_KR = IWDG_KR_RESET; +} +/**@}*/ + diff --git a/lib/stm32/nvic.c b/lib/stm32/nvic.c index cd823e11..84fa6749 100644 --- a/lib/stm32/nvic.c +++ b/lib/stm32/nvic.c @@ -1,3 +1,26 @@ +/** @defgroup STM32F_nvic_file NVIC + +@ingroup STM32F_files + +@brief libopencm3 STM32F Nested Vectored Interrupt Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto +@author @htmlonly © @endhtmlonly 2012 Fergus Noble + +@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. * @@ -18,50 +41,134 @@ * along with this library. If not, see . */ +/**@{*/ + #include +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Enable Interrupt + +Enables a user interrupt. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +*/ + void nvic_enable_irq(u8 irqn) { NVIC_ISER(irqn / 32) = (1 << (irqn % 32)); } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Disable Interrupt + +Disables a user interrupt. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +*/ + void nvic_disable_irq(u8 irqn) { NVIC_ICER(irqn / 32) = (1 << (irqn % 32)); } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Return Pending Interrupt + +True if the interrupt has occurred and is waiting for service. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +@return Boolean. Interrupt pending. +*/ + u8 nvic_get_pending_irq(u8 irqn) { return NVIC_ISPR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Set Pending Interrupt + +Force a user interrupt to a pending state. This has no effect if the interrupt +is already pending. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +*/ + void nvic_set_pending_irq(u8 irqn) { NVIC_ISPR(irqn / 32) = (1 << (irqn % 32)); } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Clear Pending Interrupt + +Force remove a user interrupt from a pending state. This has no effect if the +interrupt is actively being serviced. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +*/ + void nvic_clear_pending_irq(u8 irqn) { NVIC_ICPR(irqn / 32) = (1 << (irqn % 32)); } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Return Active Interrupt + +Interrupt has occurred and is currently being serviced. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +@return Boolean. Interrupt active. +*/ + u8 nvic_get_active_irq(u8 irqn) { return NVIC_IABR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Return Enabled Interrupt + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +@return Boolean. Interrupt enabled. +*/ + u8 nvic_get_irq_enabled(u8 irqn) { return NVIC_ISER(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Set Interrupt Priority + +There are 16 priority levels only, given by the upper four bits of the priority +byte, as required by ARM standards. The priority levels are interpreted according +to the pre-emptive priority grouping set in the SCB Application Interrupt and Reset +Control Register (SCB_AIRCR), as done in @ref scb_set_priority_grouping. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +@param[in] priority Unsigned int8. Interrupt priority (0 ... 255 in steps of 16) +*/ + void nvic_set_priority(u8 irqn, u8 priority) { - NVIC_IPR(irqn / 4) |= (priority << ((irqn % 4) * 8)); + NVIC_IPR(irqn) = priority; } -void nvic_generate_software_interrupt(u8 irqn) +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Software Trigger Interrupt + +Generate an interrupt from software. This has no effect for unprivileged access +unless the privilege level has been elevated through the System Control Registers. + +@param[in] irqn Unsigned int16. Interrupt number (0 ... 239) +*/ + +void nvic_generate_software_interrupt(u16 irqn) { if (irqn <= 239) NVIC_STIR |= irqn; } +/**@}*/ + diff --git a/lib/stm32/systick.c b/lib/stm32/systick.c index c49d11dc..36077cc9 100644 --- a/lib/stm32/systick.c +++ b/lib/stm32/systick.c @@ -1,3 +1,23 @@ +/** @defgroup STM32F_systick_file SysTick + +@ingroup STM32F_files + +@brief libopencm3 STM32Fxx System Tick Timer + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@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. * @@ -17,44 +37,97 @@ * along with this library. If not, see . */ +/**@{*/ #include +/*-----------------------------------------------------------------------------*/ +/** @brief SysTick Set the Automatic Reload Value. + +The counter is set to the reload value when the counter starts and after it +reaches zero. + +@param[in] value u32. 24 bit reload value. +*/ + void systick_set_reload(u32 value) { STK_LOAD = (value & 0x00FFFFFF); } +/*-----------------------------------------------------------------------------*/ +/** @brief SysTick Read the Automatic Reload Value. + +@returns 24 bit reload value as u32. +*/ + u32 systick_get_value(void) { return STK_VAL; } +/*-----------------------------------------------------------------------------*/ +/** @brief Set the SysTick Clock Source. + +The clock source can be either the AHB clock or the same clock divided by 8. + +@param[in] clocksource u8. Clock source from @ref systick_clksource. +*/ + void systick_set_clocksource(u8 clocksource) { if (clocksource < 2) STK_CTRL |= (clocksource << STK_CTRL_CLKSOURCE_LSB); } +/*-----------------------------------------------------------------------------*/ +/** @brief Enable SysTick Interrupt. + +*/ + void systick_interrupt_enable(void) { STK_CTRL |= STK_CTRL_TICKINT; } +/*-----------------------------------------------------------------------------*/ +/** @brief Disable SysTick Interrupt. + +*/ + void systick_interrupt_disable(void) { STK_CTRL &= ~STK_CTRL_TICKINT; } +/*-----------------------------------------------------------------------------*/ +/** @brief Enable SysTick Counter. + +*/ + void systick_counter_enable(void) { STK_CTRL |= STK_CTRL_ENABLE; } +/*-----------------------------------------------------------------------------*/ +/** @brief Disable SysTick Counter. + +*/ + void systick_counter_disable(void) { STK_CTRL &= ~STK_CTRL_ENABLE; } +/*-----------------------------------------------------------------------------*/ +/** @brief SysTick Read the Counter Flag. + +The count flag is set when the timer count becomes zero, and is cleared when the +flag is read. + +@returns Boolean if flag set. +*/ + u8 systick_get_countflag(void) { if (STK_CTRL & STK_CTRL_COUNTFLAG) @@ -62,3 +135,5 @@ u8 systick_get_countflag(void) else return 0; } +/**@}*/ + diff --git a/scripts/lpcvtcksum b/scripts/lpcvtcksum new file mode 100755 index 00000000..27dc8a77 --- /dev/null +++ b/scripts/lpcvtcksum @@ -0,0 +1,51 @@ +#!/usr/bin/python +# +# Compute and insert the vector table checksum required for booting the +# LPC43xx and some other NXP ARM microcontrollers. +# +# usage: lpcvtcksum firmware.bin +# +# This file is part of the libopencm3 project. +# +# Copyright (C) 2012 Michael Ossmann +# +# 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 . + +import sys, struct + +binfile = open(sys.argv[1], 'r+b') +rawvectors = binfile.read(32) +vectors = list(struct.unpack('