diff options
author | Jeff Ciesielski <jeff.ciesielski@convergeddevices.net> | 2012-11-14 01:27:36 +0400 |
---|---|---|
committer | Jeff Ciesielski <jeff.ciesielski@convergeddevices.net> | 2012-11-14 01:27:36 +0400 |
commit | 88d4f020816c018e31ba48cdd975a9738ba56eed (patch) | |
tree | c213211778736d5ce2f06b4cf186a6900f522b20 | |
parent | ffe392c11bdc7c45f61c652ecabd79fecbe1938a (diff) | |
parent | db35fbb7ba97a8a6d7481edf07cb82cae06aa834 (diff) |
Merge pull request #3 from Jeff-Ciesielski/master
Integrate ICDs changes into the upstream opencm3 repository
191 files changed, 10045 insertions, 6304 deletions
@@ -16,4 +16,14 @@ lib/*.ld html/ latex/ *.pdf - +# These are generated +include/libopencm3/**/nvic.h +include/libopencm3/**/**/nvic.h +lib/**/vector_nvic.c +lib/**/**/vector_nvic.c +include/libopencmsis/efm32/ +include/libopencmsis/lm3s/ +include/libopencmsis/lpc13xx/ +include/libopencmsis/lpc17xx/ +include/libopencmsis/lpc43xx/ +include/libopencmsis/stm32/ @@ -19,14 +19,20 @@ PREFIX ?= arm-none-eabi #PREFIX ?= arm-elf + +ifeq ($(DETECT_TOOLCHAIN),) DESTDIR ?= /usr/local +else +DESTDIR ?= $(shell dirname $(shell readlink -f $(shell which $(PREFIX)-gcc)))/.. +endif + INCDIR = $(DESTDIR)/$(PREFIX)/include LIBDIR = $(DESTDIR)/$(PREFIX)/lib SHAREDIR = $(DESTDIR)/$(PREFIX)/share/libopencm3/scripts INSTALL = install SRCLIBDIR = $(shell pwd)/lib -TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lpc17xx lpc43xx lm3s +TARGETS = stm32/f1 stm32/f2 stm32/f4 stm32/l1 lpc13xx lpc17xx lpc43xx lm3s efm32/efm32tg efm32/efm32g efm32/efm32lg efm32/efm32gg # Be silent per default, but 'make V=1' will show all compiler calls. ifneq ($(V),1) @@ -39,41 +45,57 @@ all: build build: lib examples -lib: - $(Q)for i in $(addprefix $@/,$(TARGETS)); do \ - if [ -d $$i ]; then \ - printf " BUILD $$i\n"; \ - $(MAKE) -C $$i SRCLIBDIR=$(SRCLIBDIR) || exit $?; \ - fi; \ +generatedheaders: + @printf " UPDATING HEADERS\n" + $(Q)for yamlfile in `find . -name 'irq.yaml'`; do \ + ./scripts/irq2nvic_h $$yamlfile ; \ done -examples: lib - $(Q)for i in $(addsuffix /*/*,$(addprefix $@/,$(TARGETS))); do \ - if [ -d $$i ]; then \ - printf " BUILD $$i\n"; \ - $(MAKE) -C $$i || exit $?; \ - fi; \ +cleanheaders: + @printf " CLEANING HEADERS\n" + $(Q)for yamlfile in `find . -name 'irq.yaml'`; do \ + ./scripts/irq2nvic_h --remove $$yamlfile ; \ done +LIB_DIRS:=$(wildcard $(addprefix lib/,$(TARGETS))) +$(LIB_DIRS): generatedheaders + @printf " BUILD $@\n"; + $(Q)$(MAKE) --directory=$@ SRCLIBDIR=$(SRCLIBDIR) + +lib: $(LIB_DIRS) + $(Q)true + +EXAMPLE_DIRS:=$(sort $(dir $(wildcard $(addsuffix /*/*/Makefile,$(addprefix examples/,$(TARGETS)))))) +$(EXAMPLE_DIRS): lib + @printf " BUILD $@\n"; + $(Q)$(MAKE) --directory=$@ + +examples: $(EXAMPLE_DIRS) + $(Q)true + install: lib @printf " INSTALL headers\n" $(Q)$(INSTALL) -d $(INCDIR)/libopencm3 + $(Q)$(INSTALL) -d $(INCDIR)/libopencmsis $(Q)$(INSTALL) -d $(LIBDIR) $(Q)$(INSTALL) -d $(SHAREDIR) $(Q)cp -r include/libopencm3/* $(INCDIR)/libopencm3 + $(Q)cp -r include/libopencmsis/* $(INCDIR)/libopencmsis @printf " INSTALL libs\n" $(Q)$(INSTALL) -m 0644 lib/*.a $(LIBDIR) @printf " INSTALL ldscripts\n" $(Q)$(INSTALL) -m 0644 lib/*.ld $(LIBDIR) + $(Q)$(INSTALL) -m 0644 lib/efm32/*/*.ld $(LIBDIR) @printf " INSTALL scripts\n" $(Q)$(INSTALL) -m 0644 scripts/* $(SHAREDIR) doc: $(Q)$(MAKE) -C doc doc -clean: - $(Q)for i in $(addprefix lib/,$(TARGETS)) \ - $(addsuffix /*/*,$(addprefix examples/,$(TARGETS))); do \ +# Bleh http://www.makelinux.net/make3/make3-CHP-6-SECT-1#make3-CHP-6-SECT-1 +clean: cleanheaders + $(Q)for i in $(LIB_DIRS) \ + $(EXAMPLE_DIRS); do \ if [ -d $$i ]; then \ printf " CLEAN $$i\n"; \ $(MAKE) -C $$i clean SRCLIBDIR=$(SRCLIBDIR) || exit $?; \ @@ -82,5 +104,5 @@ clean: @printf " CLEAN doxygen\n" $(Q)$(MAKE) -C doc clean -.PHONY: build lib examples install doc clean +.PHONY: build lib $(LIB_DIRS) examples $(EXAMPLE_DIRS) install doc clean generatedheaders cleanheaders @@ -48,7 +48,8 @@ Example projects The library ships with a few small example projects which illustrate how individual subsystems of the microcontrollers can be configured and used with -libopencm3. +libopencm3. The makefiles are generally useable for your own projects with +only minimal changes for the libopencm3 install path (See Installation) For flashing the 'miniblink' example (after you built libopencm3 and the examples by typing 'make' at the top-level directory) onto the Olimex @@ -79,16 +80,23 @@ Installation $ make install -This will install the library in /usr/local. If you want to install it -elsewhere, use the following syntax: +This will install the library into /usr/local. (permissions permitting) - $ DESTDIR=/opt make install +If you want to install it elsewhere, use the following syntax: -The recommended location is to install into your toolchain directory, e.g. -/home/someuser/sat for a toolchain built using the summon-arm-toolchain -script from https://github.com/esden/summon-arm-toolchain. + $ make DESTDIR=/opt/libopencm3 install - $ DESTDIR=~/sat make install +If you want to attempt to install into your toolchain, use this: + + $ make DETECT_TOOLCHAIN=1 install + +Note: If you install this into your toolchain, you don't need to pass +any extra -L or -I flags into your projects. However, this also means +you must NOT pass any -L or -I flags that point into the toolchain. This +_will_ confuse the linker. (ie, for summon-arm-toolchain, do NOT pass +-L/home/user/sat/lib) Common symptoms of confusing +the linker are hard faults caused by branches into arm code. +You can use objdump to check for this in your final elf. Coding style and development guidelines diff --git a/doc/Doxyfile_common b/doc/Doxyfile_common index a0e9bf83..8182f1fd 100644 --- a/doc/Doxyfile_common +++ b/doc/Doxyfile_common @@ -1491,13 +1491,13 @@ ENABLE_PREPROCESSING = YES # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. @@ -1525,7 +1525,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = __attribute__(x)= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/examples/lm3s/Makefile.include b/examples/lm3s/Makefile.include index f5190638..c9bd33ca 100644 --- a/examples/lm3s/Makefile.include +++ b/examples/lm3s/Makefile.include @@ -37,7 +37,7 @@ endif endif CFLAGS += -O0 -g3 -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ - -mcpu=cortex-m3 -mthumb -MD + -mcpu=cortex-m3 -mthumb -MD -DLM3S LDSCRIPT ?= $(BINARY).ld LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections diff --git a/examples/lpc13xx/Makefile.include b/examples/lpc13xx/Makefile.include index d8aeff09..0b220638 100644 --- a/examples/lpc13xx/Makefile.include +++ b/examples/lpc13xx/Makefile.include @@ -37,7 +37,7 @@ endif endif CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ - -mcpu=cortex-m3 -mthumb -MD + -mcpu=cortex-m3 -mthumb -MD -DLPC13XX LDSCRIPT ?= $(BINARY).ld LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections diff --git a/examples/lpc17xx/Makefile.include b/examples/lpc17xx/Makefile.include index 6d7bbfe5..9c38a68d 100644 --- a/examples/lpc17xx/Makefile.include +++ b/examples/lpc17xx/Makefile.include @@ -37,7 +37,7 @@ endif endif CFLAGS += -O0 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ - -mcpu=cortex-m3 -mthumb -MD + -mcpu=cortex-m3 -mthumb -MD -DLPC17XX LDSCRIPT ?= $(BINARY).ld LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections diff --git a/examples/lpc43xx/Makefile.include b/examples/lpc43xx/Makefile.include index 15e523b4..cf78538f 100644 --- a/examples/lpc43xx/Makefile.include +++ b/examples/lpc43xx/Makefile.include @@ -41,7 +41,7 @@ endif CFLAGS += -O2 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ -mcpu=cortex-m4 -mthumb -MD \ - -mfloat-abi=hard -mfpu=fpv4-sp-d16 + -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX LDSCRIPT ?= $(BINARY).ld LDFLAGS += -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections -Xlinker -Map=$(BINARY).map diff --git a/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c b/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c index 66c8e068..d38b0bcd 100644 --- a/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c +++ b/examples/lpc43xx/hackrf-jellybean/systick/systickdemo.c @@ -20,8 +20,8 @@ #include <libopencm3/lpc43xx/gpio.h> #include <libopencm3/lpc43xx/scu.h> #include <libopencm3/lpc43xx/cgu.h> -#include <libopencm3/lpc43xx/nvic.h> -#include <libopencm3/lpc43xx/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> #include <libopencm3/cm3/scs.h> #include "../jellybean_conf.h" diff --git a/examples/stm32/f1/Makefile.include b/examples/stm32/f1/Makefile.include index 6b87b982..2ae9e27e 100644 --- a/examples/stm32/f1/Makefile.include +++ b/examples/stm32/f1/Makefile.include @@ -45,6 +45,15 @@ LDFLAGS += --static -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group \ -L$(TOOLCHAIN_DIR)/lib \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \ $(ARCH_FLAGS) -mfix-cortex-m3-ldrd + +ifneq ($(OPENCM3_DIR),) +CFLAGS += -I$(OPENCM3_DIR)/include +LDFLAGS += -L$(OPENCM3_DIR)/lib -L$(OPENCM3_DIR)/lib/stm32/f1 +SCRIPT_DIR = $(OPENCM3_DIR)/share +else +SCRIPT_DIR = $(shell dirname $(shell readlink -f $(shell which $(PREFIX)-gcc)))/../$(PREFIX)/share +endif + OBJS += $(BINARY).o OOCD ?= openocd @@ -53,6 +62,9 @@ OOCD_BOARD ?= olimex_stm32_h103 # Black magic probe specific variables # Set the BMP_PORT to a serial port and then BMP is used for flashing BMP_PORT ?= +# texane/stlink can be used by uncommenting this... +# or defining it in your own makefiles +#STLINK_PORT ?= :4242 # Be silent per default, but 'make V=1' will show all compiler calls. ifneq ($(V),1) @@ -107,6 +119,7 @@ clean: $(Q)rm -f *.srec $(Q)rm -f *.list +ifeq ($(STLINK_PORT),) ifeq ($(BMP_PORT),) ifeq ($(OOCD_SERIAL),) %.flash: %.hex @@ -140,6 +153,14 @@ else -x $(TOOLCHAIN_DIR)/scripts/black_magic_probe_flash.scr \ $(*).elf endif +else +%.flash: %.elf + @echo " GDB $(*).elf (flash)" + $(Q)$(GDB) --batch \ + -ex 'target extended-remote $(STLINK_PORT)' \ + -x $(SCRIPT_DIR)/libopencm3/scripts/stlink_flash.scr \ + $(*).elf +endif .PHONY: images clean diff --git a/examples/stm32/f1/lisa-m-1/can/README b/examples/stm32/f1/lisa-m-1/can/README new file mode 100644 index 00000000..3a14e3b1 --- /dev/null +++ b/examples/stm32/f1/lisa-m-1/can/README @@ -0,0 +1,4 @@ +This test sets up the CAN interface on Lisa/M and transmits 8 bites every +100ms. The first byte is being incremented in each cycle. The demo also +receives messages and is displaing the first 4 bits of the first byte on the +board LEDs. diff --git a/examples/stm32/f1/lisa-m-1/can/can.c b/examples/stm32/f1/lisa-m-1/can/can.c index 26309058..463d7fcd 100644 --- a/examples/stm32/f1/lisa-m-1/can/can.c +++ b/examples/stm32/f1/lisa-m-1/can/can.c @@ -21,8 +21,8 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/flash.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/nvic.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> #include <libopencm3/stm32/can.h> struct can_tx_msg { @@ -106,15 +106,15 @@ void can_setup(void) rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CANEN); - AFIO_MAPR = AFIO_MAPR_CAN1_REMAP_PORTB; + AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB; /* Configure CAN pin: RX (input pull-up). */ - gpio_set_mode(GPIOB, GPIO_MODE_INPUT, + gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX); gpio_set(GPIOB, GPIO_CAN1_PB_RX); /* Configure CAN pin: TX. */ - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, + gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX); /* NVIC setup. */ @@ -167,8 +167,10 @@ void sys_tick_handler(void) static int temp32 = 0; static u8 data[8] = {0, 1, 2, 0, 0, 0, 0, 0}; - /* We call this handler every 1ms so 1000ms = 1s on/off. */ - if (++temp32 != 1000) + /* We call this handler every 1ms so 100ms = 1s + * Resulting in 100Hz message frequency. + */ + if (++temp32 != 100) return; temp32 = 0; diff --git a/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c b/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c index 7ef9b621..08efa466 100644 --- a/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c +++ b/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c @@ -164,11 +164,12 @@ static const char *usb_strings[] = { "DEMO", }; -static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; (void)buf; + (void)usbd_dev; switch (req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -200,15 +201,15 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, return 0; } -static void cdcacm_data_rx_cb(u8 ep) +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep) { (void)ep; char buf[64]; - int len = usbd_ep_read_packet(0x01, buf, 64); + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { - while (usbd_ep_write_packet(0x82, buf, len) == 0) + while (usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0) ; buf[len] = 0; } @@ -216,15 +217,16 @@ static void cdcacm_data_rx_cb(u8 ep) gpio_toggle(GPIOC, GPIO5); } -static void cdcacm_set_config(u16 wValue) +static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; - usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, cdcacm_control_request); @@ -234,6 +236,8 @@ int main(void) { int i; + usbd_device *usbd_dev; + rcc_clock_setup_in_hsi_out_48mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); @@ -246,13 +250,13 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO5); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(cdcacm_set_config); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, cdcacm_set_config); for (i = 0; i < 0x800000; i++) __asm__("nop"); gpio_clear(GPIOC, GPIO2); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c b/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c index 4ffc0a14..137bebad 100644 --- a/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c +++ b/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c @@ -21,7 +21,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/f1/flash.h> -#include <libopencm3/stm32/f1/scb.h> +#include <libopencm3/cm3/scb.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/dfu.h> @@ -130,10 +130,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -static void usbdfu_getstatus_complete(struct usb_setup_data *req) +static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { int i; (void)req; + (void)usbd_dev; switch (usbdfu_state) { case STATE_DFU_DNBUSY: @@ -166,9 +167,11 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req) } } -static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { + (void)usbd_dev; + if ((req->bmRequestType & 0x7F) != 0x21) return 0; /* Only accept class request. */ @@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if (!gpio_get(GPIOA, GPIO10)) { @@ -245,9 +250,10 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); - usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer)); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, usbdfu_control_request); @@ -255,5 +261,5 @@ int main(void) gpio_clear(GPIOC, GPIO2); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c b/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c index 8d83896d..28636742 100644 --- a/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c +++ b/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c @@ -21,7 +21,7 @@ #include <stdlib.h> #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/systick.h> #include <libopencm3/stm32/spi.h> #include <libopencm3/stm32/otg_fs.h> #include <libopencm3/usb/usbd.h> @@ -32,10 +32,12 @@ #define INCLUDE_DFU_INTERFACE #ifdef INCLUDE_DFU_INTERFACE -#include <libopencm3/stm32/f1/scb.h> +#include <libopencm3/cm3/scb.h> #include <libopencm3/usb/dfu.h> #endif +static usbd_device *usbd_dev; + const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, @@ -173,10 +175,11 @@ static const char *usb_strings[] = { "DEMO", }; -static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; + (void)usbd_dev; if((req->bmRequestType != 0x81) || (req->bRequest != USB_REQ_GET_DESCRIPTOR) || @@ -191,9 +194,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #ifdef INCLUDE_DFU_INTERFACE -static void dfu_detach_complete(struct usb_setup_data *req) +static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { (void)req; + (void)usbd_dev; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, @@ -202,11 +206,12 @@ static void dfu_detach_complete(struct usb_setup_data *req) scb_reset_core(); } -static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)buf; (void)len; + (void)usbd_dev; if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH)) return 0; /* Only accept class request. */ @@ -217,18 +222,20 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #endif -static void hid_set_config(u16 wValue) +static void hid_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; - usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, hid_control_request); #ifdef INCLUDE_DFU_INTERFACE usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, dfu_control_request); @@ -329,8 +336,8 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(hid_set_config); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, hid_set_config); /* Delay some seconds to show that pull-up switch works. */ for (i = 0; i < 0x800000; i++) @@ -345,7 +352,7 @@ int main(void) // OTG_FS_GCCFG &= ~OTG_FS_GCCFG_VBUSBSEN; while (1) - usbd_poll(); + usbd_poll(usbd_dev); } void sys_tick_handler(void) @@ -357,5 +364,5 @@ void sys_tick_handler(void) buf[1] = x >> 9; buf[2] = y >> 9; - usbd_ep_write_packet(0x81, buf, 4); + usbd_ep_write_packet(usbd_dev, 0x81, buf, 4); } diff --git a/examples/stm32/f1/lisa-m-2/adc_injec/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec/Makefile index e50737bf..666c393b 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_injec/Makefile @@ -18,6 +18,7 @@ ## BINARY = adc_injec + # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile index af2e9e65..72eab49e 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile @@ -18,6 +18,7 @@ ## BINARY = adc_injec_timtrig + # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile index c88152e2..8ad47e2d 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile @@ -18,6 +18,7 @@ ## BINARY = adc_injec_timtrig_irq + # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c index bda1d9dc..674343d0 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c @@ -25,7 +25,7 @@ #include <libopencm3/stm32/f1/adc.h> #include <libopencm3/stm32/usart.h> #include <libopencm3/stm32/timer.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> volatile u16 temperature = 0; diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile index d9a74a28..a3cccece 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile @@ -18,6 +18,7 @@ ## BINARY = adc_injec_timtrig_irq_4ch + # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c index 13341841..cbff97dc 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c @@ -25,7 +25,7 @@ #include <libopencm3/stm32/f1/adc.h> #include <libopencm3/stm32/usart.h> #include <libopencm3/stm32/timer.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> volatile u16 temperature = 0; volatile u16 v_refint = 0; diff --git a/examples/stm32/f1/lisa-m-2/adc_regular/Makefile b/examples/stm32/f1/lisa-m-2/adc_regular/Makefile index 20355ceb..b61587f5 100644 --- a/examples/stm32/f1/lisa-m-2/adc_regular/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_regular/Makefile @@ -18,6 +18,7 @@ ## BINARY = adc + # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 diff --git a/examples/stm32/f1/lisa-m-2/can/Makefile b/examples/stm32/f1/lisa-m-2/can/Makefile new file mode 100644 index 00000000..71a787ab --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/can/Makefile @@ -0,0 +1,28 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +BINARY = can + +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 +LDSCRIPT = ../lisa-m.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/lisa-m-2/can/README b/examples/stm32/f1/lisa-m-2/can/README new file mode 100644 index 00000000..3a14e3b1 --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/can/README @@ -0,0 +1,4 @@ +This test sets up the CAN interface on Lisa/M and transmits 8 bites every +100ms. The first byte is being incremented in each cycle. The demo also +receives messages and is displaing the first 4 bits of the first byte on the +board LEDs. diff --git a/examples/stm32/f1/lisa-m-2/can/can.c b/examples/stm32/f1/lisa-m-2/can/can.c new file mode 100644 index 00000000..dd673ba8 --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/can/can.c @@ -0,0 +1,234 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> + * Copyright (C) 2010-2011 Piotr Esden-Tempski <piotr@esden.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/f1/rcc.h> +#include <libopencm3/stm32/f1/flash.h> +#include <libopencm3/stm32/f1/gpio.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> +#include <libopencm3/stm32/can.h> + +struct can_tx_msg { + u32 std_id; + u32 ext_id; + u8 ide; + u8 rtr; + u8 dlc; + u8 data[8]; +}; + +struct can_rx_msg { + u32 std_id; + u32 ext_id; + u8 ide; + u8 rtr; + u8 dlc; + u8 data[8]; + u8 fmi; +}; + +struct can_tx_msg can_tx_msg; +struct can_rx_msg can_rx_msg; + +void gpio_setup(void) +{ + /* Enable Alternate Function clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + + /* Enable GPIOA clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + + /* Enable GPIOB clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); + + /* Enable GPIOC clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + + /* Preconfigure LEDs. */ + gpio_set(GPIOA, GPIO8); /* LED1 off */ + gpio_set(GPIOB, GPIO4); /* LED2 off */ + gpio_set(GPIOC, GPIO2); /* LED3 off */ + gpio_set(GPIOC, GPIO5); /* LED4 off */ + gpio_set(GPIOC, GPIO15); /* LED5 off */ + + /* Configure LED GPIOOs. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO4); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO5); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); + + /* Configure PB4 as GPIO. */ + AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST; + +} + +void systick_setup(void) +{ + /* 72MHz / 8 => 9000000 counts per second */ + systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8); + + /* 9000000/9000 = 1000 overflows per second - every 1ms one interrupt */ + systick_set_reload(9000); + + systick_interrupt_enable(); + + /* Start counting. */ + systick_counter_enable(); +} + +void can_setup(void) +{ + /* Enable peripheral clocks. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CAN1EN); + + AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB; + + /* Configure CAN pin: RX (input pull-up). */ + gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX); + gpio_set(GPIO_BANK_CAN1_PB_RX, GPIO_CAN1_PB_RX); + + /* Configure CAN pin: TX. */ + gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX); + + /* NVIC setup. */ + nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); + nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1); + + /* Reset CAN. */ + can_reset(CAN1); + + /* CAN cell init. */ + if (can_init(CAN1, + false, /* TTCM: Time triggered comm mode? */ + true, /* ABOM: Automatic bus-off management? */ + false, /* AWUM: Automatic wakeup mode? */ + false, /* NART: No automatic retransmission? */ + false, /* RFLM: Receive FIFO locked mode? */ + false, /* TXFP: Transmit FIFO priority? */ + CAN_BTR_SJW_1TQ, + CAN_BTR_TS1_3TQ, + CAN_BTR_TS2_4TQ, + 12)) /* BRP+1: Baud rate prescaler */ + { + gpio_set(GPIOA, GPIO8); /* LED1 off */ + gpio_set(GPIOB, GPIO4); /* LED2 off */ + gpio_set(GPIOC, GPIO2); /* LED3 off */ + gpio_clear(GPIOC, GPIO5); /* LED4 on */ + gpio_set(GPIOC, GPIO15); /* LED5 off */ + + /* Die because we failed to initialize. */ + while (1) + __asm__("nop"); + } + + /* CAN filter 0 init. */ + can_filter_id_mask_32bit_init(CAN1, + 0, /* Filter ID */ + 0, /* CAN ID */ + 0, /* CAN ID mask */ + 0, /* FIFO assignment (here: FIFO0) */ + true); /* Enable the filter. */ + + /* Enable CAN RX interrupt. */ + can_enable_irq(CAN1, CAN_IER_FMPIE0); +} + +void sys_tick_handler(void) +{ + static int temp32 = 0; + static u8 data[8] = {0, 1, 2, 0, 0, 0, 0, 0}; + + /* We call this handler every 1ms so every 100ms = 0.1s + * resulting in 100Hz message rate. + */ + if (++temp32 != 100) + return; + + temp32 = 0; + + /* Transmit CAN frame. */ + data[0]++; + if (can_transmit(CAN1, + 0, /* (EX/ST)ID: CAN ID */ + false, /* IDE: CAN ID extended? */ + false, /* RTR: Request transmit? */ + 8, /* DLC: Data length */ + data) == -1) + { + gpio_set(GPIOA, GPIO8); /* LED1 off */ + gpio_set(GPIOB, GPIO4); /* LED2 off */ + gpio_set(GPIOC, GPIO2); /* LED3 off */ + gpio_set(GPIOC, GPIO5); /* LED4 off */ + gpio_clear(GPIOC, GPIO15); /* LED5 on */ + } +} + +void usb_lp_can_rx0_isr(void) +{ + u32 id, fmi; + bool ext, rtr; + u8 length, data[8]; + + can_receive(CAN1, 0, false, &id, &ext, &rtr, &fmi, &length, data); + + if (data[0] & 1) + gpio_clear(GPIOA, GPIO8); + else + gpio_set(GPIOA, GPIO8); + + if (data[0] & 2) + gpio_clear(GPIOB, GPIO4); + else + gpio_set(GPIOB, GPIO4); + + if (data[0] & 4) + gpio_clear(GPIOC, GPIO2); + else + gpio_set(GPIOC, GPIO2); + + if (data[0] & 8) + gpio_clear(GPIOC, GPIO5); + else + gpio_set(GPIOC, GPIO5); + + can_fifo_release(CAN1, 0); +} + +int main(void) +{ + rcc_clock_setup_in_hse_12mhz_out_72mhz(); + gpio_setup(); + can_setup(); + systick_setup(); + + while (1); /* Halt. */ + + return 0; +} diff --git a/examples/stm32/f1/lisa-m-2/fancyblink/Makefile b/examples/stm32/f1/lisa-m-2/fancyblink/Makefile index e453f843..90ce834e 100644 --- a/examples/stm32/f1/lisa-m-2/fancyblink/Makefile +++ b/examples/stm32/f1/lisa-m-2/fancyblink/Makefile @@ -19,6 +19,9 @@ BINARY = fancyblink +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 LDSCRIPT = ../lisa-m.ld include ../../Makefile.include diff --git a/examples/stm32/f1/lisa-m-2/usart/Makefile b/examples/stm32/f1/lisa-m-2/usart/Makefile index 4ba7e9e5..498cd83f 100644 --- a/examples/stm32/f1/lisa-m-2/usart/Makefile +++ b/examples/stm32/f1/lisa-m-2/usart/Makefile @@ -19,6 +19,9 @@ BINARY = usart +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 LDSCRIPT = ../lisa-m.ld include ../../Makefile.include diff --git a/examples/stm32/f1/lisa-m-2/usart_dma/Makefile b/examples/stm32/f1/lisa-m-2/usart_dma/Makefile index 813cda90..5fa5c519 100644 --- a/examples/stm32/f1/lisa-m-2/usart_dma/Makefile +++ b/examples/stm32/f1/lisa-m-2/usart_dma/Makefile @@ -19,6 +19,9 @@ BINARY = usart_dma +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 LDSCRIPT = ../lisa-m.ld include ../../Makefile.include diff --git a/examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c b/examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c index ac3bb3ca..369c5390 100644 --- a/examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c +++ b/examples/stm32/f1/lisa-m-2/usart_dma/usart_dma.c @@ -21,7 +21,7 @@ #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> #include <libopencm3/stm32/f1/dma.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> void clock_setup(void) { diff --git a/examples/stm32/f1/lisa-m-2/usart_irq/Makefile b/examples/stm32/f1/lisa-m-2/usart_irq/Makefile index 7baa2fed..dbab248d 100644 --- a/examples/stm32/f1/lisa-m-2/usart_irq/Makefile +++ b/examples/stm32/f1/lisa-m-2/usart_irq/Makefile @@ -19,6 +19,9 @@ BINARY = usart_irq +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 LDSCRIPT = ../lisa-m.ld include ../../Makefile.include diff --git a/examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c b/examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c index dbe9140a..e5d9e686 100644 --- a/examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c +++ b/examples/stm32/f1/lisa-m-2/usart_irq/usart_irq.c @@ -20,7 +20,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> void clock_setup(void) { diff --git a/examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile b/examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile index 0b6fd3eb..1cc2ed1b 100644 --- a/examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile +++ b/examples/stm32/f1/lisa-m-2/usart_irq_printf/Makefile @@ -19,6 +19,9 @@ BINARY = usart_irq_printf +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 LDSCRIPT = ../lisa-m.ld include ../../Makefile.include diff --git a/examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c b/examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c index 6b1096ed..dd2e2217 100644 --- a/examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c +++ b/examples/stm32/f1/lisa-m-2/usart_irq_printf/usart_irq_printf.c @@ -21,8 +21,8 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> #include <stdio.h> #include <errno.h> diff --git a/examples/stm32/f1/lisa-m-2/usart_printf/Makefile b/examples/stm32/f1/lisa-m-2/usart_printf/Makefile index 80ac0330..6eaf0051 100644 --- a/examples/stm32/f1/lisa-m-2/usart_printf/Makefile +++ b/examples/stm32/f1/lisa-m-2/usart_printf/Makefile @@ -19,6 +19,9 @@ BINARY = usart_printf +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 LDSCRIPT = ../lisa-m.ld include ../../Makefile.include diff --git a/examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c b/examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c index a66bcbc6..bd245ffa 100644 --- a/examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c +++ b/examples/stm32/f1/lisa-m-2/usart_printf/usart_printf.c @@ -21,7 +21,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <stdio.h> #include <errno.h> diff --git a/examples/stm32/f1/obldc-strip/can/Makefile b/examples/stm32/f1/obldc-strip/can/Makefile new file mode 100644 index 00000000..ae148417 --- /dev/null +++ b/examples/stm32/f1/obldc-strip/can/Makefile @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +BINARY = can + +LDSCRIPT = ../obldc-strip.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/obldc-strip/can/README b/examples/stm32/f1/obldc-strip/can/README new file mode 100644 index 00000000..3a14e3b1 --- /dev/null +++ b/examples/stm32/f1/obldc-strip/can/README @@ -0,0 +1,4 @@ +This test sets up the CAN interface on Lisa/M and transmits 8 bites every +100ms. The first byte is being incremented in each cycle. The demo also +receives messages and is displaing the first 4 bits of the first byte on the +board LEDs. diff --git a/examples/stm32/f1/obldc-strip/can/can.c b/examples/stm32/f1/obldc-strip/can/can.c new file mode 100644 index 00000000..82473e1c --- /dev/null +++ b/examples/stm32/f1/obldc-strip/can/can.c @@ -0,0 +1,202 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/f1/rcc.h> +#include <libopencm3/stm32/f1/flash.h> +#include <libopencm3/stm32/f1/gpio.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> +#include <libopencm3/stm32/can.h> + +struct can_tx_msg { + u32 std_id; + u32 ext_id; + u8 ide; + u8 rtr; + u8 dlc; + u8 data[8]; +}; + +struct can_rx_msg { + u32 std_id; + u32 ext_id; + u8 ide; + u8 rtr; + u8 dlc; + u8 data[8]; + u8 fmi; +}; + +struct can_tx_msg can_tx_msg; +struct can_rx_msg can_rx_msg; + +void gpio_setup(void) +{ + /* Enable Alternate Function clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + + /* Enable GPIOB clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); + + /* Preconfigure LEDs. */ + gpio_set(GPIOB, GPIO4); /* LED green off */ + gpio_set(GPIOB, GPIO5); /* LED red off */ + + /* Configure LED GPIOs. */ + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO4); + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO5); + + /* Configure PB4 as GPIO. */ + AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST; + +} + +void systick_setup(void) +{ + /* 64MHz / 8 => 8000000 counts per second */ + systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8); + + /* 8000000/8000 = 1000 overflows per second - every 1ms one interrupt */ + systick_set_reload(8000); + + systick_interrupt_enable(); + + /* Start counting. */ + systick_counter_enable(); +} + +void can_setup(void) +{ + /* Enable peripheral clocks. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CAN1EN); + + AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB; + + /* Configure CAN pin: RX (input pull-up). */ + gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX); + gpio_set(GPIO_BANK_CAN1_PB_RX, GPIO_CAN1_PB_RX); + + /* Configure CAN pin: TX. */ + gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX); + + /* NVIC setup. */ + nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); + nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1); + + /* Reset CAN. */ + can_reset(CAN1); + + /* CAN cell init. + * Setting the bitrate to 1MBit. APB1 = 32MHz, + * prescaler = 2 -> 16MHz time quanta frequency. + * 1tq sync + 9tq bit segment1 (TS1) + 6tq bit segment2 (TS2) = + * 16time quanto per bit period, therefor 16MHz/16 = 1MHz + */ + if (can_init(CAN1, + false, /* TTCM: Time triggered comm mode? */ + true, /* ABOM: Automatic bus-off management? */ + false, /* AWUM: Automatic wakeup mode? */ + false, /* NART: No automatic retransmission? */ + false, /* RFLM: Receive FIFO locked mode? */ + false, /* TXFP: Transmit FIFO priority? */ + CAN_BTR_SJW_1TQ, + CAN_BTR_TS1_9TQ, + CAN_BTR_TS2_6TQ, + 2)) /* BRP+1: Baud rate prescaler */ + { + gpio_clear(GPIOB, GPIO4); /* LED green on */ + gpio_set(GPIOB, GPIO5); /* LED red off */ + + /* Die because we failed to initialize. */ + while (1) + __asm__("nop"); + } + + /* CAN filter 0 init. */ + can_filter_id_mask_32bit_init(CAN1, + 0, /* Filter ID */ + 0, /* CAN ID */ + 0, /* CAN ID mask */ + 0, /* FIFO assignment (here: FIFO0) */ + true); /* Enable the filter. */ + + /* Enable CAN RX interrupt. */ + can_enable_irq(CAN1, CAN_IER_FMPIE0); +} + +void sys_tick_handler(void) +{ + static u8 data[8] = {0, 1, 2, 0, 0, 0, 0, 0}; + + /* We call this handler every 1ms so every 1ms = 0.001s + * resulting in 1000Hz message rate. + */ + + /* Transmit CAN frame. */ + data[0]++; + if (can_transmit(CAN1, + 0, /* (EX/ST)ID: CAN ID */ + false, /* IDE: CAN ID extended? */ + false, /* RTR: Request transmit? */ + 8, /* DLC: Data length */ + data) == -1) + { + gpio_set(GPIOB, GPIO4); /* LED green off */ + gpio_clear(GPIOB, GPIO5); /* LED red on */ + } +} + +void usb_lp_can_rx0_isr(void) +{ + u32 id, fmi; + bool ext, rtr; + u8 length, data[8]; + + can_receive(CAN1, 0, false, &id, &ext, &rtr, &fmi, &length, data); + + if (data[0] & 0x40) + gpio_clear(GPIOB, GPIO4); + else + gpio_set(GPIOB, GPIO4); + + if (data[0] & 0x80) + gpio_clear(GPIOB, GPIO5); + else + gpio_set(GPIOB, GPIO5); + + can_fifo_release(CAN1, 0); +} + +int main(void) +{ + rcc_clock_setup_in_hsi_out_64mhz(); + gpio_setup(); + can_setup(); + systick_setup(); + + while (1); /* Halt. */ + + return 0; +} diff --git a/examples/stm32/f1/obldc-strip/led/Makefile b/examples/stm32/f1/obldc-strip/led/Makefile new file mode 100644 index 00000000..f8ff5405 --- /dev/null +++ b/examples/stm32/f1/obldc-strip/led/Makefile @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +BINARY = led + +LDSCRIPT = ../obldc-strip.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/obldc-strip/led/led.c b/examples/stm32/f1/obldc-strip/led/led.c new file mode 100644 index 00000000..e9fb92fc --- /dev/null +++ b/examples/stm32/f1/obldc-strip/led/led.c @@ -0,0 +1,65 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/f1/rcc.h> +#include <libopencm3/stm32/f1/gpio.h> + +void clock_setup(void) +{ + /* Set STM32 to 64 MHz. */ + rcc_clock_setup_in_hsi_out_64mhz(); + + /* Enable alternate function peripheral clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + + /* Enable GPIOB clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); +} + +void gpio_setup(void) +{ + + /* Configure PB4 as GPIO. */ + AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST; + + /* Set GPIO4 and 5 (in GPIO port B) to 'output push-pull'. */ + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO4 | GPIO5); + +} + +int main(void) +{ + int i; + + clock_setup(); + gpio_setup(); + + /* Blink the LEDs on the board. */ + while (1) { + gpio_toggle(GPIOB, GPIO4); /* LED on/off */ + for (i = 0; i < 8000000; i++) /* Wait a bit. */ + __asm__("nop"); + gpio_toggle(GPIOB, GPIO5); /* LED on/off */ + for (i = 0; i < 8000000; i++) /* Wait a bit. */ + __asm__("nop"); + } + + return 0; +} diff --git a/lib/stm32/f2/scb.c b/examples/stm32/f1/obldc-strip/obldc-strip.ld index abb7b446..9778070f 100644 --- a/lib/stm32/f2/scb.c +++ b/examples/stm32/f1/obldc-strip/obldc-strip.ld @@ -1,7 +1,7 @@ /* * This file is part of the libopencm3 project. * - * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz> + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -17,19 +17,15 @@ * along with this library. If not, see <http://www.gnu.org/licenses/>. */ -#include <libopencm3/stm32/f2/scb.h> +/* Linker script for Open-BLDC (STM32F103CBT6, 128K flash, 20K RAM). */ -void scb_reset_core(void) +/* Define memory regions. */ +MEMORY { - SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_VECTRESET; + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K } -void scb_reset_system(void) -{ - SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ; -} +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld -void scb_set_priority_grouping(u32 prigroup) -{ - SCB_AIRCR = SCB_AIRCR_VECTKEY | prigroup; -} diff --git a/examples/stm32/f1/obldc-strip/systick/Makefile b/examples/stm32/f1/obldc-strip/systick/Makefile new file mode 100644 index 00000000..d89dd3e2 --- /dev/null +++ b/examples/stm32/f1/obldc-strip/systick/Makefile @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +BINARY = systick + +LDSCRIPT = ../obldc-strip.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/obldc-strip/systick/systick.c b/examples/stm32/f1/obldc-strip/systick/systick.c new file mode 100644 index 00000000..8b949013 --- /dev/null +++ b/examples/stm32/f1/obldc-strip/systick/systick.c @@ -0,0 +1,81 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/f1/rcc.h> +#include <libopencm3/stm32/f1/flash.h> +#include <libopencm3/stm32/f1/gpio.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> + +u32 temp32; + +void gpio_setup(void) +{ + /* Enable alternate function peripheral clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + + /* Enable GPIOB clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); + + gpio_clear(GPIOB, GPIO4); /* LED green on */ + gpio_set(GPIOB, GPIO5); /* LED red off */ + + /* Set GPIO4/5 (in GPIO port B) to 'output push-pull' for the LEDs. */ + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO4); + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO5); + + AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST; +} + +void sys_tick_handler(void) +{ + temp32++; + + /* We call this handler every 1ms so 1000ms = 1s on/off. */ + if (temp32 == 1000) { + gpio_toggle(GPIOB, GPIO4); /* LED green on/off */ + gpio_toggle(GPIOB, GPIO5); /* LED red on/off */ + temp32 = 0; + } +} + +int main(void) +{ + rcc_clock_setup_in_hsi_out_64mhz(); + gpio_setup(); + + temp32 = 0; + + /* 64MHz / 8 => 8000000 counts per second */ + systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8); + + /* 8000000/8000 = 1000 overflows per second - every 1ms one interrupt */ + systick_set_reload(8000); + + systick_interrupt_enable(); + + /* Start counting. */ + systick_counter_enable(); + + while (1); /* Halt. */ + + return 0; +} diff --git a/examples/stm32/f1/obldc/can/can.c b/examples/stm32/f1/obldc/can/can.c index d26be508..281ab1d3 100644 --- a/examples/stm32/f1/obldc/can/can.c +++ b/examples/stm32/f1/obldc/can/can.c @@ -21,8 +21,8 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/flash.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/nvic.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> #include <libopencm3/stm32/can.h> struct can_tx_msg { diff --git a/examples/stm32/f1/obldc/systick/systick.c b/examples/stm32/f1/obldc/systick/systick.c index e854f85d..14267934 100644 --- a/examples/stm32/f1/obldc/systick/systick.c +++ b/examples/stm32/f1/obldc/systick/systick.c @@ -21,8 +21,8 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/flash.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/nvic.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> u32 temp32; diff --git a/examples/stm32/f1/obldc/usart_irq/usart_irq.c b/examples/stm32/f1/obldc/usart_irq/usart_irq.c index 3925565f..e13dd812 100644 --- a/examples/stm32/f1/obldc/usart_irq/usart_irq.c +++ b/examples/stm32/f1/obldc/usart_irq/usart_irq.c @@ -20,7 +20,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> void clock_setup(void) { diff --git a/examples/stm32/f1/other/dogm128/main.c b/examples/stm32/f1/other/dogm128/main.c index 5838af42..7889794a 100644 --- a/examples/stm32/f1/other/dogm128/main.c +++ b/examples/stm32/f1/other/dogm128/main.c @@ -22,7 +22,7 @@ #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> #include <libopencm3/stm32/timer.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <libopencm3/stm32/spi.h> #include "./dogm128.h" diff --git a/examples/stm32/f1/other/rtc/rtc.c b/examples/stm32/f1/other/rtc/rtc.c index ee2a4272..41c5d89f 100644 --- a/examples/stm32/f1/other/rtc/rtc.c +++ b/examples/stm32/f1/other/rtc/rtc.c @@ -22,7 +22,7 @@ #include <libopencm3/stm32/f1/rtc.h> #include <libopencm3/stm32/usart.h> #include <libopencm3/stm32/pwr.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> void clock_setup(void) { diff --git a/examples/stm32/f1/other/systick/systick.c b/examples/stm32/f1/other/systick/systick.c index b2df1710..c04704d0 100644 --- a/examples/stm32/f1/other/systick/systick.c +++ b/examples/stm32/f1/other/systick/systick.c @@ -20,8 +20,8 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/flash.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/nvic.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> u32 temp32; diff --git a/examples/stm32/f1/other/timer_interrupt/timer.c b/examples/stm32/f1/other/timer_interrupt/timer.c index 21a0caa4..94505488 100644 --- a/examples/stm32/f1/other/timer_interrupt/timer.c +++ b/examples/stm32/f1/other/timer_interrupt/timer.c @@ -21,7 +21,7 @@ #include <libopencm3/stm32/f1/flash.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/timer.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> void gpio_setup(void) { diff --git a/examples/stm32/f1/other/usb_cdcacm/cdcacm.c b/examples/stm32/f1/other/usb_cdcacm/cdcacm.c index 2038664d..81250b5b 100644 --- a/examples/stm32/f1/other/usb_cdcacm/cdcacm.c +++ b/examples/stm32/f1/other/usb_cdcacm/cdcacm.c @@ -164,11 +164,12 @@ static const char *usb_strings[] = { "DEMO", }; -static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; (void)buf; + (void)usbd_dev; switch(req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -200,28 +201,29 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, return 0; } -static void cdcacm_data_rx_cb(u8 ep) +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep) { (void)ep; char buf[64]; - int len = usbd_ep_read_packet(0x01, buf, 64); + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { - usbd_ep_write_packet(0x82, buf, len); + usbd_ep_write_packet(usbd_dev, 0x82, buf, len); buf[len] = 0; } } -static void cdcacm_set_config(u16 wValue) +static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; - usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, cdcacm_control_request); @@ -229,6 +231,8 @@ static void cdcacm_set_config(u16 wValue) int main(void) { + usbd_device *usbd_dev; + rcc_clock_setup_in_hsi_out_48mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); @@ -238,13 +242,13 @@ int main(void) gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(cdcacm_set_config); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, cdcacm_set_config); gpio_set(GPIOA, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/other/usb_dfu/usbdfu.c b/examples/stm32/f1/other/usb_dfu/usbdfu.c index 0211a47e..44dde169 100644 --- a/examples/stm32/f1/other/usb_dfu/usbdfu.c +++ b/examples/stm32/f1/other/usb_dfu/usbdfu.c @@ -21,7 +21,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/f1/flash.h> -#include <libopencm3/stm32/f1/scb.h> +#include <libopencm3/cm3/scb.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/dfu.h> @@ -130,10 +130,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -static void usbdfu_getstatus_complete(struct usb_setup_data *req) +static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { int i; (void)req; + (void)usbd_dev; switch (usbdfu_state) { case STATE_DFU_DNBUSY: @@ -166,9 +167,11 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req) } } -static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { + (void)usbd_dev; + if ((req->bmRequestType & 0x7F) != 0x21) return 0; /* Only accept class request. */ @@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if (!gpio_get(GPIOA, GPIO10)) { @@ -244,9 +249,12 @@ int main(void) AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); - usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN); + + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer)); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, usbdfu_control_request); @@ -256,5 +264,5 @@ int main(void) GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/other/usb_hid/usbhid.c b/examples/stm32/f1/other/usb_hid/usbhid.c index dd3c57a8..7db0d8fd 100644 --- a/examples/stm32/f1/other/usb_hid/usbhid.c +++ b/examples/stm32/f1/other/usb_hid/usbhid.c @@ -20,7 +20,7 @@ #include <stdlib.h> #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/systick.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/hid.h> @@ -28,10 +28,12 @@ #define INCLUDE_DFU_INTERFACE #ifdef INCLUDE_DFU_INTERFACE -#include <libopencm3/stm32/f1/scb.h> +#include <libopencm3/cm3/scb.h> #include <libopencm3/usb/dfu.h> #endif +static usbd_device *usbd_dev; + const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, @@ -169,10 +171,11 @@ static const char *usb_strings[] = { "DEMO", }; -static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; + (void)usbd_dev; if((req->bmRequestType != 0x81) || (req->bRequest != USB_REQ_GET_DESCRIPTOR) || @@ -187,9 +190,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #ifdef INCLUDE_DFU_INTERFACE -static void dfu_detach_complete(struct usb_setup_data *req) +static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { (void)req; + (void)usbd_dev; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, @@ -198,11 +202,12 @@ static void dfu_detach_complete(struct usb_setup_data *req) scb_reset_core(); } -static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)buf; (void)len; + (void)usbd_dev; if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH)) return 0; /* Only accept class request. */ @@ -213,18 +218,21 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #endif -static void hid_set_config(u16 wValue) +static void hid_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; + (void)usbd_dev; - usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, hid_control_request); #ifdef INCLUDE_DFU_INTERFACE usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, dfu_control_request); @@ -246,15 +254,15 @@ int main(void) AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(hid_set_config); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, hid_set_config); gpio_set(GPIOA, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } void sys_tick_handler(void) @@ -270,5 +278,5 @@ void sys_tick_handler(void) if (x < -30) dir = -dir; - usbd_ep_write_packet(0x81, buf, 4); + usbd_ep_write_packet(usbd_dev, 0x81, buf, 4); } diff --git a/examples/stm32/f1/stm32-h103/button/button.c b/examples/stm32/f1/stm32-h103/button/button.c index 814fbfbe..9d9a5e9a 100644 --- a/examples/stm32/f1/stm32-h103/button/button.c +++ b/examples/stm32/f1/stm32-h103/button/button.c @@ -20,7 +20,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <libopencm3/stm32/exti.h> u16 exti_line_state; diff --git a/examples/stm32/f1/stm32-h103/exti_both/exti_both.c b/examples/stm32/f1/stm32-h103/exti_both/exti_both.c index 3bafcc92..c871c357 100644 --- a/examples/stm32/f1/stm32-h103/exti_both/exti_both.c +++ b/examples/stm32/f1/stm32-h103/exti_both/exti_both.c @@ -20,7 +20,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <libopencm3/stm32/exti.h> u16 exti_line_state; diff --git a/examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c b/examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c index c5dfe3ba..f847847e 100644 --- a/examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c +++ b/examples/stm32/f1/stm32-h103/exti_rising_falling/exti_rising_falling.c @@ -20,7 +20,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <libopencm3/stm32/exti.h> #define FALLING 0 diff --git a/examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c b/examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c index 65854ace..deb0ff0e 100644 --- a/examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c +++ b/examples/stm32/f1/stm32-h103/pwm_6step/pwm_6step.c @@ -20,7 +20,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/timer.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <libopencm3/stm32/exti.h> #define FALLING 0 diff --git a/examples/stm32/f1/stm32-h103/timer/timer.c b/examples/stm32/f1/stm32-h103/timer/timer.c index 07f668b6..210e5921 100644 --- a/examples/stm32/f1/stm32-h103/timer/timer.c +++ b/examples/stm32/f1/stm32-h103/timer/timer.c @@ -20,7 +20,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/timer.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <libopencm3/stm32/exti.h> u16 frequency_sequence[18] = { diff --git a/examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c b/examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c index 009c6d77..ae95df8c 100644 --- a/examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c +++ b/examples/stm32/f1/stm32-h103/usart_irq/usart_irq.c @@ -20,7 +20,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> void clock_setup(void) { diff --git a/examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c b/examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c index 2143461b..b052dc3f 100644 --- a/examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c +++ b/examples/stm32/f1/stm32-h103/usart_irq_printf/usart_irq_printf.c @@ -21,8 +21,8 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/systick.h> #include <stdio.h> #include <errno.h> diff --git a/examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c b/examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c index bc9fbd3c..a275d83a 100644 --- a/examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c +++ b/examples/stm32/f1/stm32-h103/usart_printf/usart_printf.c @@ -21,7 +21,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <stdio.h> #include <errno.h> diff --git a/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c b/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c index 779f6595..3d25c296 100644 --- a/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c +++ b/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c @@ -41,7 +41,7 @@ static const struct usb_device_descriptor dev = { }; /* - * This notification endpoint isn't implemented. According to CDC spec its + * This notification endpoint isn't implemented. According to CDC spec its * optional, but its absence causes a NULL pointer dereference in Linux * cdc_acm driver. */ @@ -83,7 +83,7 @@ static const struct { .bcdCDC = 0x0110, }, .call_mgmt = { - .bFunctionLength = + .bFunctionLength = sizeof(struct usb_cdc_call_management_descriptor), .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, @@ -101,7 +101,7 @@ static const struct { .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_UNION, .bControlInterface = 0, - .bSubordinateInterface0 = 1, + .bSubordinateInterface0 = 1, }, }; @@ -164,11 +164,12 @@ static const char *usb_strings[] = { "DEMO", }; -static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; (void)buf; + (void)usbd_dev; switch (req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -199,28 +200,31 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, return 0; } -static void cdcacm_data_rx_cb(u8 ep) +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep) { (void)ep; + (void)usbd_dev; char buf[64]; - int len = usbd_ep_read_packet(0x01, buf, 64); + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { - usbd_ep_write_packet(0x82, buf, len); + usbd_ep_write_packet(usbd_dev, 0x82, buf, len); buf[len] = 0; } } -static void cdcacm_set_config(u16 wValue) +static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; + (void)usbd_dev; - usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, cdcacm_control_request); @@ -230,6 +234,8 @@ int main(void) { int i; + usbd_device *usbd_dev; + rcc_clock_setup_in_hsi_out_48mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); @@ -238,13 +244,13 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(cdcacm_set_config); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, cdcacm_set_config); for (i = 0; i < 0x800000; i++) __asm__("nop"); gpio_clear(GPIOC, GPIO11); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c b/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c index 49f265b9..80c9b5b2 100644 --- a/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c +++ b/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c @@ -21,7 +21,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/f1/flash.h> -#include <libopencm3/stm32/f1/scb.h> +#include <libopencm3/cm3/scb.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/dfu.h> @@ -114,8 +114,10 @@ static const char *usb_strings[] = { "@Internal Flash /0x08000000/8*001Ka,56*001Kg", }; -static u8 usbdfu_getstatus(u32 *bwPollTimeout) +static u8 usbdfu_getstatus(usbd_device *usbd_dev, u32 *bwPollTimeout) { + (void)usbd_dev; + switch (usbdfu_state) { case STATE_DFU_DNLOAD_SYNC: usbdfu_state = STATE_DFU_DNBUSY; @@ -130,10 +132,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -static void usbdfu_getstatus_complete(struct usb_setup_data *req) +static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { int i; (void)req; + (void)usbd_dev; switch (usbdfu_state) { case STATE_DFU_DNBUSY: @@ -166,8 +169,8 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req) } } -static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { if ((req->bmRequestType & 0x7F) != 0x21) return 0; /* Only accept class request. */ @@ -199,7 +202,7 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, return 0; case DFU_GETSTATUS: { u32 bwPollTimeout = 0; /* 24-bit integer in DFU class spec */ - (*buf)[0] = usbdfu_getstatus(&bwPollTimeout); + (*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout); (*buf)[1] = bwPollTimeout & 0xFF; (*buf)[2] = (bwPollTimeout >> 8) & 0xFF; (*buf)[3] = (bwPollTimeout >> 16) & 0xFF; @@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if (!gpio_get(GPIOA, GPIO10)) { @@ -244,9 +249,10 @@ int main(void) GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); gpio_set(GPIOC, GPIO11); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer)); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, usbdfu_control_request); @@ -254,5 +260,5 @@ int main(void) gpio_clear(GPIOC, GPIO11); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c b/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c index 9ed40d13..a4a93148 100644 --- a/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c +++ b/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c @@ -20,7 +20,7 @@ #include <stdlib.h> #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/systick.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/hid.h> @@ -28,7 +28,7 @@ #define INCLUDE_DFU_INTERFACE #ifdef INCLUDE_DFU_INTERFACE -#include <libopencm3/stm32/f1/scb.h> +#include <libopencm3/cm3/scb.h> #include <libopencm3/usb/dfu.h> #endif @@ -169,10 +169,11 @@ static const char *usb_strings[] = { "DEMO", }; -static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; + (void)usbd_dev; if ((req->bmRequestType != 0x81) || (req->bRequest != USB_REQ_GET_DESCRIPTOR) || @@ -187,9 +188,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #ifdef INCLUDE_DFU_INTERFACE -static void dfu_detach_complete(struct usb_setup_data *req) +static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { (void)req; + (void)usbd_dev; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, @@ -198,11 +200,12 @@ static void dfu_detach_complete(struct usb_setup_data *req) scb_reset_core(); } -static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)buf; (void)len; + (void)usbd_dev; if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH)) return 0; /* Only accept class request. */ @@ -213,18 +216,21 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #endif -static void hid_set_config(u16 wValue) +static void hid_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; + (void)usbd_dev; - usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, hid_control_request); #ifdef INCLUDE_DFU_INTERFACE usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, dfu_control_request); @@ -240,6 +246,8 @@ int main(void) { int i; + usbd_device *usbd_dev; + rcc_clock_setup_in_hsi_out_48mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); @@ -248,8 +256,8 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(hid_set_config); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, hid_set_config); for (i = 0; i < 0x80000; i++) __asm__("nop"); @@ -257,9 +265,10 @@ int main(void) gpio_clear(GPIOC, GPIO11); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } +#if 0 /* is this used? */ void sys_tick_handler(void) { static int x = 0; @@ -273,5 +282,6 @@ void sys_tick_handler(void) if (x < -30) dir = -dir; - usbd_ep_write_packet(0x81, buf, 4); + usbd_ep_write_packet(usbd_dev, 0x81, buf, 4); } +#endif diff --git a/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c b/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c index c5cc8ba0..72fc0fb6 100644 --- a/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c +++ b/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c @@ -21,7 +21,7 @@ #include <libopencm3/stm32/f1/rcc.h> #include <libopencm3/stm32/f1/gpio.h> #include <libopencm3/stm32/f1/flash.h> -#include <libopencm3/stm32/f1/scb.h> +#include <libopencm3/cm3/scb.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/dfu.h> @@ -114,8 +114,10 @@ static const char *usb_strings[] = { "@Internal Flash /0x08000000/8*001Ka,56*001Kg", }; -static u8 usbdfu_getstatus(u32 *bwPollTimeout) +static u8 usbdfu_getstatus(usbd_device *usbd_dev, u32 *bwPollTimeout) { + (void)usbd_dev; + switch (usbdfu_state) { case STATE_DFU_DNLOAD_SYNC: usbdfu_state = STATE_DFU_DNBUSY; @@ -130,10 +132,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -static void usbdfu_getstatus_complete(struct usb_setup_data *req) +static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { int i; (void)req; + (void)usbd_dev; switch (usbdfu_state) { case STATE_DFU_DNBUSY: @@ -166,8 +169,8 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req) } } -static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { if ((req->bmRequestType & 0x7F) != 0x21) return 0; /* Only accept class request. */ @@ -199,7 +202,7 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, return 0; case DFU_GETSTATUS: { u32 bwPollTimeout = 0; /* 24-bit integer in DFU class spec */ - (*buf)[0] = usbdfu_getstatus(&bwPollTimeout); + (*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout); (*buf)[1] = bwPollTimeout & 0xFF; (*buf)[2] = (bwPollTimeout >> 8) & 0xFF; (*buf)[3] = (bwPollTimeout >> 16) & 0xFF; @@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if (!gpio_get(GPIOA, GPIO10)) { @@ -244,9 +249,10 @@ int main(void) AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer)); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, usbdfu_control_request); @@ -256,5 +262,5 @@ int main(void) GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c b/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c index e9a52b23..fc0aecd8 100644 --- a/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c +++ b/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c @@ -75,16 +75,17 @@ const char *usb_strings[] = { "1001", }; -static int simple_control_callback(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int simple_control_callback(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)buf; (void)len; (void)complete; + (void)usbd_dev; if (req->bmRequestType != 0x40) return 0; /* Only accept vendor request. */ - + if (req->wValue & 1) gpio_set(GPIOC, GPIO6); else @@ -95,6 +96,8 @@ static int simple_control_callback(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_clock_setup_in_hse_8mhz_out_72mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); @@ -105,13 +108,14 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO6); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_VENDOR, USB_REQ_TYPE_TYPE, simple_control_callback); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c b/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c index d447e9b7..b3c698bc 100644 --- a/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c +++ b/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c @@ -23,7 +23,7 @@ #include <libopencm3/stm32/f1/rtc.h> #include <libopencm3/stm32/usart.h> #include <libopencm3/stm32/pwr.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> void clock_setup(void) { diff --git a/examples/stm32/f2/jobygps/spi_test/spi_test.c b/examples/stm32/f2/jobygps/spi_test/spi_test.c index 8775db8e..95ba0216 100644 --- a/examples/stm32/f2/jobygps/spi_test/spi_test.c +++ b/examples/stm32/f2/jobygps/spi_test/spi_test.c @@ -22,7 +22,7 @@ #include <errno.h> #include <libopencm3/stm32/spi.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <libopencm3/stm32/f2/gpio.h> #include <libopencm3/stm32/f2/rcc.h> diff --git a/examples/stm32/f2/jobygps/usart_printf/usart_printf.c b/examples/stm32/f2/jobygps/usart_printf/usart_printf.c index 67a7d7f6..d490e397 100644 --- a/examples/stm32/f2/jobygps/usart_printf/usart_printf.c +++ b/examples/stm32/f2/jobygps/usart_printf/usart_printf.c @@ -22,7 +22,7 @@ #include <errno.h> #include <libopencm3/stm32/f2/gpio.h> #include <libopencm3/stm32/usart.h> -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> #include <libopencm3/stm32/f2/rcc.h> void clock_setup(void) diff --git a/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c b/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c index 4af10393..836bdfb1 100644 --- a/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c +++ b/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c @@ -22,6 +22,7 @@ #include <libopencm3/stm32/f4/gpio.h> #include <libopencm3/usb/usbd.h> #include <libopencm3/usb/cdc.h> +#include <libopencm3/cm3/scb.h> static const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, @@ -164,11 +165,12 @@ static const char *usb_strings[] = { "DEMO", }; -static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; (void)buf; + (void)usbd_dev; switch (req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -188,30 +190,31 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, return 0; } -static void cdcacm_data_rx_cb(u8 ep) +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep) { (void)ep; char buf[64]; - int len = usbd_ep_read_packet(0x01, buf, 64); + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { - while (usbd_ep_write_packet(0x82, buf, len) == 0) + while (usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0) ; } gpio_toggle(GPIOC, GPIO5); } -static void cdcacm_set_config(u16 wValue) +static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; - usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, cdcacm_control_request); @@ -219,19 +222,20 @@ static void cdcacm_set_config(u16 wValue) int main(void) { + usbd_device *usbd_dev; + rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_120MHZ]); rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN); - gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO11 | GPIO12); gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12); - usbd_init(&otgfs_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(cdcacm_set_config); + usbd_dev = usbd_init(&otgfs_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, cdcacm_set_config); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } - diff --git a/examples/stm32/l1/Makefile.include b/examples/stm32/l1/Makefile.include new file mode 100644 index 00000000..57b70303 --- /dev/null +++ b/examples/stm32/l1/Makefile.include @@ -0,0 +1,164 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +LD = $(PREFIX)-gcc +OBJCOPY = $(PREFIX)-objcopy +OBJDUMP = $(PREFIX)-objdump +GDB = $(PREFIX)-gdb + +TOOLCHAIN_DIR ?= ../../../../.. +ifeq ($(wildcard ../../../../../lib/libopencm3_stm32l1.a),) +ifneq ($(strip $(shell which $(CC))),) +TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +endif +else +ifeq ($(V),1) +$(info We seem to be building the example in the source directory. Using local library!) +endif +endif + +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 -msoft-float +CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ + -fno-common $(ARCH_FLAGS) -MD -DSTM32L1 +LDSCRIPT ?= $(BINARY).ld +LDFLAGS += --static -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group \ + -L$(TOOLCHAIN_DIR)/lib \ + -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \ + $(ARCH_FLAGS) -mfix-cortex-m3-ldrd + +CFLAGS += -I$(TOOLCHAIN_DIR)/include +LDFLAGS += -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/stm32/l1 +SCRIPT_DIR = $(TOOLCHAIN_DIR)/share + +OBJS += $(BINARY).o + +OOCD ?= openocd +OOCD_INTERFACE ?= flossjtag +OOCD_BOARD ?= olimex_stm32_h103 +# Black magic probe specific variables +# Set the BMP_PORT to a serial port and then BMP is used for flashing +BMP_PORT ?= +# texane/stlink can be used by uncommenting this... +# or defining it in your own makefiles +#STLINK_PORT ?= :4242 + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +NULL := 2>/dev/null +else +LDFLAGS += -Wl,--print-gc-sections +endif + +.SUFFIXES: .elf .bin .hex .srec .list .images +.SECONDEXPANSION: +.SECONDARY: + +all: images + +images: $(BINARY).images +flash: $(BINARY).flash + +%.images: %.bin %.hex %.srec %.list + @#echo "*** $* images generated ***" + +%.bin: %.elf + @#printf " OBJCOPY $(*).bin\n" + $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin + +%.hex: %.elf + @#printf " OBJCOPY $(*).hex\n" + $(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex + +%.srec: %.elf + @#printf " OBJCOPY $(*).srec\n" + $(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec + +%.list: %.elf + @#printf " OBJDUMP $(*).list\n" + $(Q)$(OBJDUMP) -S $(*).elf > $(*).list + +%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32l1.a + @#printf " LD $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32l1 $(LDFLAGS) + +%.o: %.c Makefile + @#printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) -o $@ -c $< + +clean: + $(Q)rm -f *.o + $(Q)rm -f *.d + $(Q)rm -f *.elf + $(Q)rm -f *.bin + $(Q)rm -f *.hex + $(Q)rm -f *.srec + $(Q)rm -f *.list + +ifeq ($(STLINK_PORT),) +ifeq ($(BMP_PORT),) +ifeq ($(OOCD_SERIAL),) +%.flash: %.hex + @printf " FLASH $<\n" + @# IMPORTANT: Don't use "resume", only "reset" will work correctly! + $(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ + -f board/$(OOCD_BOARD).cfg \ + -c "init" -c "reset init" \ + -c "stm32l1x mass_erase 0" \ + -c "flash write_image $(*).hex" \ + -c "reset" \ + -c "shutdown" $(NULL) +else +%.flash: %.hex + @printf " FLASH $<\n" + @# IMPORTANT: Don't use "resume", only "reset" will work correctly! + $(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ + -f board/$(OOCD_BOARD).cfg \ + -c "ft2232_serial $(OOCD_SERIAL)" \ + -c "init" -c "reset init" \ + -c "stm32l1x mass_erase 0" \ + -c "flash write_image $(*).hex" \ + -c "reset" \ + -c "shutdown" $(NULL) +endif +else +%.flash: %.elf + @echo " GDB $(*).elf (flash)" + $(Q)$(GDB) --batch \ + -ex 'target extended-remote $(BMP_PORT)' \ + -x $(TOOLCHAIN_DIR)/scripts/black_magic_probe_flash.scr \ + $(*).elf +endif +else +%.flash: %.elf + @echo " GDB $(*).elf (flash)" + $(Q)$(GDB) --batch \ + -ex 'target extended-remote $(STLINK_PORT)' \ + -x $(SCRIPT_DIR)/libopencm3/scripts/stlink_flash.scr \ + $(*).elf +endif + +.PHONY: images clean + +-include $(OBJS:.o=.d) + diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile b/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile new file mode 100644 index 00000000..d57ea7a8 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +BINARY = main +LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld + +include ../../Makefile.include + diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/README b/examples/stm32/l1/stm32l-discovery/button-irq-printf/README new file mode 100644 index 00000000..63232ef6 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/README @@ -0,0 +1,3 @@ +* Prints to the screen when the button is pushed/released (irq driven) + 115200@8n1 console on PA2 (tx only) + diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c new file mode 100644 index 00000000..1830c4dd --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c @@ -0,0 +1,117 @@ +/* + * Karl Palsson, 2012 <karlp@tweak.net.au + */ + +#include <errno.h> +#include <stdio.h> +#include <unistd.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/stm32/l1/rcc.h> +#include <libopencm3/stm32/l1/gpio.h> +#include <libopencm3/stm32/exti.h> +#include <libopencm3/stm32/usart.h> + +#include "syscfg.h" + +static struct state_t state; + +void clock_setup(void) { + /* Lots of things on all ports... */ + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); + + /* Enable clocks for USART2. */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); +} + +void gpio_setup(void) { + gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN); + + /* Setup GPIO pins for USART2 transmit. */ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); + + /* Setup USART2 TX pin as alternate function. */ + gpio_set_af(GPIOA, GPIO_AF7, GPIO2); +} + +void usart_setup(void) { + usart_set_baudrate(USART_CONSOLE, 115200); + usart_set_databits(USART_CONSOLE, 8); + usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1); + usart_set_mode(USART_CONSOLE, USART_MODE_TX); + usart_set_parity(USART_CONSOLE, USART_PARITY_NONE); + usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART_CONSOLE); +} + +/** + * Use USART_CONSOLE as a console. + * @param file + * @param ptr + * @param len + * @return + */ +int _write(int file, char *ptr, int len) { + int i; + + if (file == STDOUT_FILENO || file == STDERR_FILENO) { + for (i = 0; i < len; i++) { + if (ptr[i] == '\n') { + usart_send_blocking(USART_CONSOLE, '\r'); + } + usart_send_blocking(USART_CONSOLE, ptr[i]); + } + return i; + } + errno = EIO; + return -1; +} + +void BUTTON_DISCO_USER_isr(void) { + exti_reset_request(BUTTON_DISCO_USER_EXTI); + if (state.falling) { + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + // ILOG("fell: %d\n", TIM_CNT(TIM7)); + puts("fell!\n"); + } else { + puts("Rose!\n"); + // TIM_CNT(TIM7) = 0; + state.falling = true; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING); + } +} + +void setup_buttons(void) { + /* Enable EXTI0 interrupt. */ + nvic_enable_irq(BUTTON_DISCO_USER_NVIC); + + gpio_mode_setup(BUTTON_DISCO_USER_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, BUTTON_DISCO_USER_PIN); + + /* Configure the EXTI subsystem. */ + exti_select_source(BUTTON_DISCO_USER_EXTI, BUTTON_DISCO_USER_PORT); + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + exti_enable_request(BUTTON_DISCO_USER_EXTI); +} + +int main(void) { + int i; + int j = 0; + clock_setup(); + gpio_setup(); + usart_setup(); + puts("hi guys!\n"); + setup_buttons(); + while (1) { + puts("tick:"); + putchar('a' + (j++ % 26)); + gpio_toggle(GPIOB, GPIO7); /* LED on/off */ + for (i = 0; i < 100000; i++) /* Wait a bit. */ + __asm__("NOP"); + } + + return 0; +} diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h new file mode 100644 index 00000000..32cf465a --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h @@ -0,0 +1,45 @@ +/* + * General configuration of the device + * + * Karl Palsson <karlp@tweak.net.au> 2012 + */ + +#ifndef SYSCFG_H +#define SYSCFG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libopencm3/stm32/l1/gpio.h> +#include <libopencm3/stm32/l1/nvic.h> +#include <libopencm3/stm32/exti.h> +#include <libopencm3/stm32/usart.h> + + +#define USART_CONSOLE USART2 +#define USE_NASTYLOG 1 + +#define LED_DISCO_GREEN_PORT GPIOB +#define LED_DISCO_GREEN_PIN GPIO7 +#define LED_DISCO_BLUE_PORT GPIOB +#define LED_DISCO_BLUE_PIN GPIO6 + +#define BUTTON_DISCO_USER_PORT GPIOA +#define BUTTON_DISCO_USER_PIN GPIO0 +#define BUTTON_DISCO_USER_EXTI EXTI0 +#define BUTTON_DISCO_USER_isr exti0_isr +#define BUTTON_DISCO_USER_NVIC NVIC_EXTI0_IRQ + + + struct state_t { + bool falling; + }; + + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_H */ + diff --git a/examples/stm32/l1/stm32l-discovery/miniblink/Makefile b/examples/stm32/l1/stm32l-discovery/miniblink/Makefile new file mode 100644 index 00000000..b0586e55 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/miniblink/Makefile @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +BINARY = miniblink + +LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld + +include ../../Makefile.include + diff --git a/examples/stm32/l1/stm32l-discovery/miniblink/README b/examples/stm32/l1/stm32l-discovery/miniblink/README new file mode 100644 index 00000000..8bdd3144 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/miniblink/README @@ -0,0 +1,9 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is the smallest-possible example program using libopencm3. + +It's intended for the ST STM32L-DISCOVERY eval board. It should blink +the blue LED on the board. + diff --git a/examples/stm32/l1/stm32l-discovery/miniblink/miniblink.c b/examples/stm32/l1/stm32l-discovery/miniblink/miniblink.c new file mode 100644 index 00000000..2f5c70f7 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/miniblink/miniblink.c @@ -0,0 +1,72 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/l1/rcc.h> +#include <libopencm3/stm32/l1/gpio.h> + +#define PORT_LED GPIOB +#define PIN_LED GPIO6 + +void gpio_setup(void) +{ + /* Enable GPIOB clock. */ + /* Manually: */ + //RCC_AHBENR |= RCC_AHBENR_GPIOBEN; + /* Using API functions: */ + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); + + /* Set GPIO6 (in GPIO port B) to 'output push-pull'. */ + /* Using API functions: */ + gpio_mode_setup(PORT_LED, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED); +} + +int main(void) +{ + int i; + + gpio_setup(); + + /* Blink the LED (PC8) on the board. */ + while (1) { + /* Manually: */ + // GPIOD_BSRR = GPIO12; /* LED off */ + // for (i = 0; i < 1000000; i++) /* Wait a bit. */ + // __asm__("nop"); + // GPIOD_BRR = GPIO12; /* LED on */ + // for (i = 0; i < 1000000; i++) /* Wait a bit. */ + // __asm__("nop"); + + /* Using API functions gpio_set()/gpio_clear(): */ + // gpio_set(GPIOD, GPIO12); /* LED off */ + // for (i = 0; i < 1000000; i++) /* Wait a bit. */ + // __asm__("nop"); + // gpio_clear(GPIOD, GPIO12); /* LED on */ + // for (i = 0; i < 1000000; i++) /* Wait a bit. */ + // __asm__("nop"); + + /* Using API function gpio_toggle(): */ + gpio_toggle(PORT_LED, PIN_LED); /* LED on/off */ + for (i = 0; i < 1000000; i++) /* Wait a bit. */ + __asm__("nop"); + } + + return 0; +} diff --git a/examples/stm32/l1/stm32l-discovery/usart/Makefile b/examples/stm32/l1/stm32l-discovery/usart/Makefile new file mode 100644 index 00000000..ac088fe9 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/usart/Makefile @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +BINARY = usart + +LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld + +include ../../Makefile.include + diff --git a/examples/stm32/l1/stm32l-discovery/usart/README b/examples/stm32/l1/stm32l-discovery/usart/README new file mode 100644 index 00000000..dcbc5d98 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/usart/README @@ -0,0 +1,12 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This example program sends some characters on USART2 on the +ST STM32L DISCOVERY eval board. (USART2 TX on PA2) + +The terminal settings for the receiving device/PC are 38400 8n1. + +The sending is done in a blocking way in the code, see the usart_irq example +for a more elaborate USART example. + diff --git a/examples/stm32/l1/stm32l-discovery/usart/usart.c b/examples/stm32/l1/stm32l-discovery/usart/usart.c new file mode 100644 index 00000000..3335ca8c --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/usart/usart.c @@ -0,0 +1,80 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/l1/rcc.h> +#include <libopencm3/stm32/l1/gpio.h> +#include <libopencm3/stm32/usart.h> + +void clock_setup(void) { + /* We are running on MSI after boot. */ + /* Enable GPIOD clock for LED & USARTs. */ + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); + + /* Enable clocks for USART2. */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); +} + +void usart_setup(void) { + /* Setup USART2 parameters. */ + usart_set_baudrate(USART2, 38400); + usart_set_databits(USART2, 8); + usart_set_stopbits(USART2, USART_STOPBITS_1); + usart_set_mode(USART2, USART_MODE_TX); + usart_set_parity(USART2, USART_PARITY_NONE); + usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART2); +} + +void gpio_setup(void) { + /* Setup GPIO pin GPIO7 on GPIO port B for Green LED. */ + gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO7); + + /* Setup GPIO pins for USART2 transmit. */ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); + + /* Setup USART2 TX pin as alternate function. */ + gpio_set_af(GPIOA, GPIO_AF7, GPIO2); +} + +int main(void) { + int i, j = 0, c = 0; + + clock_setup(); + gpio_setup(); + usart_setup(); + + /* Blink the LED (PD12) on the board with every transmitted byte. */ + while (1) { + gpio_toggle(GPIOB, GPIO7); /* LED on/off */ + usart_send_blocking(USART2, c + '0'); /* USART2: Send byte. */ + c = (c == 9) ? 0 : c + 1; /* Increment c. */ + if ((j++ % 80) == 0) { /* Newline after line full. */ + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + } + for (i = 0; i < 100000; i++) /* Wait a bit. */ + __asm__("NOP"); + } + + return 0; +} diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/cm3/nvic.h index 694fab88..3f832856 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/cm3/nvic.h @@ -1,21 +1,9 @@ -/** @defgroup STM32F_nvic_defines NVIC Defines - -@brief <b>libopencm3 STM32F Nested Vectored Interrupt Controller</b> - -@ingroup STM32F_defines - -@version 1.0.0 - -@author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski <piotr@esden.net> - -@date 18 August 2012 - -LGPL License Terms @ref lgpl_license - */ /* * This file is part of the libopencm3 project. * * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> + * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com> + * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com> * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -30,13 +18,27 @@ LGPL License Terms @ref lgpl_license * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ +/** @defgroup CM3_nvic_defines NVIC Defines + +@brief <b>libopencm3 Cortex Nested Vectored Interrupt Controller</b> + +@ingroup CM3_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski <piotr@esden.net> + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /**@{*/ #ifndef LIBOPENCM3_NVIC_H #define LIBOPENCM3_NVIC_H -#include <libopencm3/stm32/memorymap.h> #include <libopencm3/cm3/common.h> +#include <libopencm3/cm3/memorymap.h> /* --- NVIC Registers ------------------------------------------------------ */ @@ -79,9 +81,9 @@ LGPL License Terms @ref lgpl_license /* --- IRQ channel numbers-------------------------------------------------- */ -/* Cortex M3 System Interrupts */ -/** @defgroup nvic_sysint Cortex M3 System Interrupts -@ingroup STM32F_nvic_defines +/* Cortex M3 and M4 System Interrupts */ +/** @defgroup nvic_sysint Cortex M3/M4 System Interrupts +@ingroup CM3_nvic_defines IRQ numbers -3 and -6 to -9 are reserved @{*/ @@ -98,21 +100,11 @@ IRQ numbers -3 and -6 to -9 are reserved #define NVIC_SYSTICK_IRQ -1 /**@}*/ - /* Note: User interrupts are family specific and are defined in a family * specific header file in the corresponding subfolder. */ -#if defined(STM32F1) -# include <libopencm3/stm32/f1/nvic_f1.h> -#elif defined(STM32F2) -# include <libopencm3/stm32/f2/nvic_f2.h> -#elif defined(STM32F4) -# include <libopencm3/stm32/f4/nvic_f4.h> -#else -# error "stm32 family not defined." -#endif - +#include <libopencm3/dispatch/nvic.h> /* --- NVIC functions ------------------------------------------------------ */ @@ -131,5 +123,3 @@ void nvic_generate_software_interrupt(u16 irqn); END_DECLS #endif -/**@}*/ - diff --git a/include/libopencm3/stm32/f4/scb.h b/include/libopencm3/cm3/scb.h index 7187ca97..8e9c757d 100644 --- a/include/libopencm3/stm32/f4/scb.h +++ b/include/libopencm3/cm3/scb.h @@ -21,7 +21,7 @@ #ifndef LIBOPENCM3_SCB_H #define LIBOPENCM3_SCB_H -#include <libopencm3/stm32/memorymap.h> +#include <libopencm3/cm3/memorymap.h> #include <libopencm3/cm3/common.h> /* --- SCB: Registers ------------------------------------------------------ */ diff --git a/include/libopencm3/stm32/systick.h b/include/libopencm3/cm3/systick.h index e42c4e6f..5e7715b6 100644 --- a/include/libopencm3/stm32/systick.h +++ b/include/libopencm3/cm3/systick.h @@ -1,22 +1,8 @@ -/** @defgroup STM32F_systick_defines SysTick Defines - -@brief <b>libopencm3 Defined Constants and Types for the STM32F SysTick </b> - -@ingroup STM32F_defines - -@version 1.0.0 - -@author @htmlonly © @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org> - -@date 19 August 2012 - -LGPL License Terms @ref lgpl_license - */ - /* * This file is part of the libopencm3 project. * * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> + * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com> * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -31,13 +17,27 @@ LGPL License Terms @ref lgpl_license * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ +/** @defgroup CM3_systick_defines SysTick Defines + +@brief <b>libopencm3 Defined Constants and Types for the Cortex SysTick </b> + +@ingroup CM3_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org> + +@date 19 August 2012 + +LGPL License Terms @ref lgpl_license + */ /**@{*/ #ifndef LIBOPENCM3_SYSTICK_H #define LIBOPENCM3_SYSTICK_H -#include <libopencm3/stm32/memorymap.h> +#include <libopencm3/cm3/memorymap.h> #include <libopencm3/cm3/common.h> /* --- SYSTICK registers --------------------------------------------------- */ @@ -63,7 +63,7 @@ LGPL License Terms @ref lgpl_license #define STK_CTRL_CLKSOURCE (1 << 2) #define STK_CTRL_CLKSOURCE_LSB 2 /** @defgroup systick_clksource Clock source selection -@ingroup STM32F_systick_defines +@ingroup CM3_systick_defines @{*/ #define STK_CTRL_CLKSOURCE_AHB_DIV8 0 @@ -104,6 +104,8 @@ void systick_counter_enable(void); void systick_counter_disable(void); u8 systick_get_countflag(void); +u32 systick_get_calib(void); + END_DECLS #endif diff --git a/include/libopencm3/cm3/vector.h b/include/libopencm3/cm3/vector.h new file mode 100644 index 00000000..f78e9d84 --- /dev/null +++ b/include/libopencm3/cm3/vector.h @@ -0,0 +1,64 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn <chrysn@fsfe.org> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file + * + * Definitions for handling vector tables. + * + * This implements d0002_efm32_cortex-m3_reference_manual.pdf's figure 2.2 + * (from the EFM32 documentation at + * http://www.energymicro.com/downloads/datasheets), and was seen analogously + * in other ARM implementations' libopencm3 files. + * + * The structure of the vector table is implemented independently of the system + * vector table starting at memory position 0x0, as it can be relocated to + * other memory locations too. + * + * The exact size of a vector interrupt table depends on the number of + * interrupts IRQ_COUNT, which is defined per family. + */ + +#ifndef LIBOPENCM3_VECTOR_H +#define LIBOPENCM3_VECTOR_H + +#include <libopencm3/cm3/common.h> +#include <libopencm3/cm3/nvic.h> + +/** Type of an interrupt function. Only used to avoid hard-to-read function + * pointers in the efm32_vector_table_t struct. */ +typedef void (*vector_table_entry_t)(void); + +typedef struct { + unsigned int *initial_sp_value; /**< The value the stack pointer is set to initially */ + vector_table_entry_t reset; + vector_table_entry_t nmi; + vector_table_entry_t hard_fault; + vector_table_entry_t memory_manage_fault; + vector_table_entry_t bus_fault; + vector_table_entry_t usage_fault; + vector_table_entry_t reserved_x001c[4]; + vector_table_entry_t sv_call; + vector_table_entry_t debug_monitor; + vector_table_entry_t reserved_x0034; + vector_table_entry_t pend_sv; + vector_table_entry_t systick; + vector_table_entry_t irq[NVIC_IRQ_COUNT]; +} vector_table_t; + +#endif diff --git a/include/libopencm3/dispatch/nvic.h b/include/libopencm3/dispatch/nvic.h new file mode 100644 index 00000000..08074e31 --- /dev/null +++ b/include/libopencm3/dispatch/nvic.h @@ -0,0 +1,34 @@ +#if defined(STM32F1) +# include <libopencm3/stm32/f1/nvic.h> +#elif defined(STM32F2) +# include <libopencm3/stm32/f2/nvic.h> +#elif defined(STM32F4) +# include <libopencm3/stm32/f4/nvic.h> +#elif defined(STM32L1) +# include <libopencm3/stm32/l1/nvic.h> + +#elif defined(EFM32TG) +# include <libopencm3/efm32/efm32tg/nvic.h> +#elif defined(EFM32G) +# include <libopencm3/efm32/efm32g/nvic.h> +#elif defined(EFM32LG) +# include <libopencm3/efm32/efm32lg/nvic.h> +#elif defined(EFM32GG) +# include <libopencm3/efm32/efm32gg/nvic.h> + +#elif defined(LPC13XX) +# include <libopencm3/lpc13xx/nvic.h> +#elif defined(LPC17XX) +# include <libopencm3/lpc17xx/nvic.h> +#elif defined(LPC43XX) +# include <libopencm3/lpc43xx/nvic.h> + +#elif defined(LM3S) +# include <libopencm3/lm3s/nvic.h> + +#else +# warning"no interrupts defined for chipset; NVIC_IRQ_COUNT = 0" + +#define NVIC_IRQ_COUNT 0 + +#endif diff --git a/include/libopencm3/efm32/efm32g/irq.yaml b/include/libopencm3/efm32/efm32g/irq.yaml new file mode 100644 index 00000000..770f755f --- /dev/null +++ b/include/libopencm3/efm32/efm32g/irq.yaml @@ -0,0 +1,35 @@ +includeguard: LIBOPENCM3_EFM32G_NVIC_H +partname_humanreadable: EFM32 Gecko series +partname_doxygen: EFM32G +# The names and sequence are taken from d0001_efm32g_reference_manual.pdf table 4.1. +irqs: + - dma + - gpio_even + - timer0 + - usart0_rx + - usart0_tx + - acmp01 + - adc0 + - dac0 + - i2c0 + - gpio_odd + - timer1 + - timer2 + - usart1_rx + - usart1_tx + - usart2_rx + - usart2_tx + - uart0_rx + - uart0_tx + - leuart0 + - leuart1 + - letimer0 + - pcnt0 + - pcnt1 + - pcnt2 + - rtc + - cmu + - vcmp + - lcd + - msc + - aes diff --git a/include/libopencm3/efm32/efm32gg/irq.yaml b/include/libopencm3/efm32/efm32gg/irq.yaml new file mode 100644 index 00000000..1cb46018 --- /dev/null +++ b/include/libopencm3/efm32/efm32gg/irq.yaml @@ -0,0 +1,43 @@ +includeguard: LIBOPENCM3_EFM32GG_NVIC_H +partname_humanreadable: EFM32 Giant Gecko series +partname_doxygen: EFM32GG +# The names and sequence are taken from d0053_efm32gg_refreence_manual.pdf table 4.1. +irqs: + - dma + - gpio_even + - timer0 + - usart0_rx + - usart0_tx + - usb + - acmp01 + - adc0 + - dac0 + - i2c0 + - i2c1 + - gpio_odd + - timer1 + - timer2 + - timer3 + - usart1_rx + - usart1_tx + - lesense + - usart2_rx + - usart2_tx + - uart0_rx + - uart0_tx + - uart1_rx + - uart1_tx + - leuart0 + - leuart1 + - letimer0 + - pcnt0 + - pcnt1 + - pcnt2 + - rtc + - burtc + - cmu + - vcmp + - lcd + - msc + - aes + - ebi diff --git a/include/libopencm3/efm32/efm32lg/irq.yaml b/include/libopencm3/efm32/efm32lg/irq.yaml new file mode 100644 index 00000000..ec38bc15 --- /dev/null +++ b/include/libopencm3/efm32/efm32lg/irq.yaml @@ -0,0 +1,43 @@ +includeguard: LIBOPENCM3_EFM32LG_NVIC_H +partname_humanreadable: EFM32 Leopard Gecko series +partname_doxygen: EFM32LG +# The names and sequence are taken from d0183_efm32lg_reference_manual.pdf table 4.1. +irqs: + - dma + - gpio_even + - timer0 + - usart0_rx + - usart0_tx + - usb + - acmp01 + - adc0 + - dac0 + - i2c0 + - i2c1 + - gpio_odd + - timer1 + - timer2 + - timer3 + - usart1_rx + - usart1_tx + - lesense + - usart2_rx + - usart2_tx + - uart0_rx + - uart0_tx + - uart1_rx + - uart1_tx + - leuart0 + - leuart1 + - letimer0 + - pcnt0 + - pcnt1 + - pcnt2 + - rtc + - burtc + - cmu + - vcmp + - lcd + - msc + - aes + - ebi diff --git a/include/libopencm3/efm32/efm32tg/irq.yaml b/include/libopencm3/efm32/efm32tg/irq.yaml new file mode 100644 index 00000000..f4aaba33 --- /dev/null +++ b/include/libopencm3/efm32/efm32tg/irq.yaml @@ -0,0 +1,28 @@ +includeguard: LIBOPENCM3_EFM32TG_NVIC_H +partname_humanreadable: EFM32 Tiny Gecko series +partname_doxygen: EFM32TG +# The names and sequence are taken from d0034_efm32tg_reference_manual.pdf table 4.1. +irqs: + - dma + - gpio_even + - timer0 + - usart0_rx + - usart0_tx + - acmp01 + - adc0 + - dac0 + - i2c0 + - gpio_odd + - timer1 + - usart1_rx + - usart1_tx + - lesense + - leuart0 + - letimer0 + - pcnt0 + - rtc + - cmu + - vcmp + - lcd + - msc + - aes diff --git a/include/libopencm3/efm32/efm32tg/memorymap.h b/include/libopencm3/efm32/efm32tg/memorymap.h new file mode 100644 index 00000000..abf37cec --- /dev/null +++ b/include/libopencm3/efm32/efm32tg/memorymap.h @@ -0,0 +1,76 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn <chrysn@fsfe.org> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file + * + * Layout of the system address space of Tiny Gecko devices. + * + * This reflects d0034_efm32tg_reference_manual.pdf figure 5.2. + */ + +/* The common cortex-m3 definitions were verified from + * d0034_efm32tg_reference_manual.pdf figure 5.2. The CM3 ROM Table seems to be + * missing there. The details (everything based on SCS_BASE) was verified from + * d0002_efm32_cortex-m3_reference_manual.pdf table 4.1, and seems to fit, but + * there are discrepancies. */ +#include <libopencm3/cm3/memorymap.h> + +#define CODE_BASE 0x00000000 + +#define SRAM_BASE 0x20000000 +#define SRAM_BASE_BITBAND 0x22000000 + +#define PERIPH_BASE 0x40000000 +#define PERIPH_BASE_BITBAND 0x42000000 + +/* Details of the "Code" section */ + +#define FLASH_BASE (CODE_BASE + 0x00000000) +#define USERDATA_BASE (CODE_BASE + 0x0fe00000) +#define LOCKBITS_BASE (CODE_BASE + 0x0fe04000) +#define CHIPCONFIG_BASE (CODE_BASE + 0x0fe08000) +#define CODESPACESRAM_BASE (CODE_BASE + 0x10000000) + +/* Tiny Gecko peripherial definitions */ + +#define VCMP_BASE (PERIPH_BASE + 0x00000000) +#define ACMP0_BASE (PERIPH_BASE + 0x00001000) +#define ACMP1_BASE (PERIPH_BASE + 0x00001400) +#define ADC_BASE (PERIPH_BASE + 0x00002000) +#define DAC0_BASE (PERIPH_BASE + 0x00004000) +#define GPIO_BASE (PERIPH_BASE + 0x00006000) /**< @see gpio.h */ +#define I2C0_BASE (PERIPH_BASE + 0x0000a000) +#define USART0_BASE (PERIPH_BASE + 0x0000c000) +#define USART1_BASE (PERIPH_BASE + 0x0000c400) +#define TIMER0_BASE (PERIPH_BASE + 0x00010000) +#define TIMER1_BASE (PERIPH_BASE + 0x00010400) +#define RTC_BASE (PERIPH_BASE + 0x00080000) +#define LETIMER0_BASE (PERIPH_BASE + 0x00082000) +#define LEUART0_BASE (PERIPH_BASE + 0x00084000) +#define PCNT0_BASE (PERIPH_BASE + 0x00086000) +#define WDOG_BASE (PERIPH_BASE + 0x00088000) +#define LCD_BASE (PERIPH_BASE + 0x0008a000) +#define LESENSE_BASE (PERIPH_BASE + 0x0008c000) +#define MSC_BASE (PERIPH_BASE + 0x000c0000) +#define DMA_BASE (PERIPH_BASE + 0x000c2000) +#define EMU_BASE (PERIPH_BASE + 0x000c6000) +#define CMU_BASE (PERIPH_BASE + 0x000c8000) /**< @see cmu.h */ +#define RMU_BASE (PERIPH_BASE + 0x000ca000) +#define PRS_BASE (PERIPH_BASE + 0x000cc000) +#define AES_BASE (PERIPH_BASE + 0x000e0000) diff --git a/include/libopencm3/efm32/memorymap.h b/include/libopencm3/efm32/memorymap.h new file mode 100644 index 00000000..ff0e5444 --- /dev/null +++ b/include/libopencm3/efm32/memorymap.h @@ -0,0 +1,37 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn <chrysn@fsfe.org> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file + * + * Dispatcher for the base address definitions, depending on the particular + * Gecko family. + * + * @see tinygecko/memorymap.h + */ + +#ifndef LIBOPENCM3_EFM32_MEMORYMAP_H +#define LIBOPENCM3_EFM32_MEMORYMAP_H + +#ifdef TINYGECKO +# include <libopencm3/efm32/tinygecko/memorymap.h> +#else +# error "efm32 family not defined." +#endif + +#endif diff --git a/include/libopencm3/lm3s/irq.yaml b/include/libopencm3/lm3s/irq.yaml new file mode 100644 index 00000000..7d5ff3a5 --- /dev/null +++ b/include/libopencm3/lm3s/irq.yaml @@ -0,0 +1,120 @@ +includeguard: LIBOPENCM3_LM3S_NVIC_H +partname_humanreadable: LM3S series +partname_doxygen: LM3S +irqs: + 0: GPIOA + 1: GPIOB + 2: GPIOC + 3: GPIOD + 4: GPIOE + 5: UART0 + 6: UART1 + 7: SSI0 + 8: I2C0 + 9: PWM0_FAULT + 10: PWM0_0 + 11: PWM0_1 + 12: PWM0_2 + 13: QEI0 + 14: ADC0SS0 + 15: ADC0SS1 + 16: ADC0SS2 + 17: ADC0SS3 + 18: WATCHDOG + 19: TIMER0A + 20: TIMER0B + 21: TIMER1A + 22: TIMER1B + 23: TIMER2A + 24: TIMER2B + 25: COMP0 + 26: COMP1 + 27: COMP2 + 28: SYSCTL + 29: FLASH + 30: GPIOF + 31: GPIOG + 32: GPIOH + 33: UART2 + 34: SSI1 + 35: TIMER3A + 36: TIMER3B + 37: I2C1 + 38: QEI1 + 39: CAN0 + 40: CAN1 + 41: CAN2 + 42: ETH + 43: HIBERNATE + 44: USB0 + 45: PWM0_3 + 46: UDMA + 47: UDMAERR + 48: ADC1SS0 + 49: ADC1SS1 + 50: ADC1SS2 + 51: ADC1SS3 + 52: I2S0 + 53: EPI0 + 54: GPIOJ + 55: GPIOK + 56: GPIOL + 57: SSI2 + 58: SSI3 + 59: UART3 + 60: UART4 + 61: UART5 + 62: UART6 + 63: UART7 +# undefined: slot 64 - 67 + 68: I2C2 + 69: I2C3 + 70: TIMER4A + 71: TIMER4B +# undefined: slot 72 - 91 + 92: TIMER5A + 93: TIMER5B + 94: WTIMER0A + 95: WTIMER0B + 96: WTIMER1A + 97: WTIMER1B + 98: WTIMER2A + 99: WTIMER2B + 100: WTIMER3A + 101: WTIMER3B + 102: WTIMER4A + 103: WTIMER4B + 104: WTIMER5A + 105: WTIMER5B + 106: SYSEXC + 107: PECI0 + 108: LPC0 + 109: I2C4 + 110: I2C5 + 111: GPIOM + 112: GPION +# undefined: slot 113 + 114: FAN0 +# undefined: slot 115 + 116: GPIOP0 + 117: GPIOP1 + 118: GPIOP2 + 119: GPIOP3 + 120: GPIOP4 + 121: GPIOP5 + 122: GPIOP6 + 123: GPIOP7 + 124: GPIOQ0 + 125: GPIOQ1 + 126: GPIOQ2 + 127: GPIOQ3 + 128: GPIOQ4 + 129: GPIOQ5 + 130: GPIOQ6 + 131: GPIOQ7 +# undefined: slot 132 - 133 + 134: PWM1_0 + 135: PWM1_1 + 136: PWM1_2 + 137: PWM1_3 + 138: PWM1_FAULT diff --git a/include/libopencm3/lpc13xx/irq.yaml b/include/libopencm3/lpc13xx/irq.yaml new file mode 100644 index 00000000..5a372db5 --- /dev/null +++ b/include/libopencm3/lpc13xx/irq.yaml @@ -0,0 +1,62 @@ +includeguard: LIBOPENCM3_LPC13xx_NVIC_H +partname_humanreadable: LPC 13xx series +partname_doxygen: LPC13xx +irqs: + 0: pio0_0 + 1: pio0_1 + 2: pio0_2 + 3: pio0_3 + 4: pio0_4 + 5: pio0_5 + 6: pio0_6 + 7: pio0_7 + 8: pio0_8 + 9: pio0_9 + 10: pio0_10 + 11: pio0_11 + 12: pio1_0 + 13: pio1_1 + 14: pio1_2 + 15: pio1_3 + 16: pio1_4 + 17: pio1_5 + 18: pio1_6 + 19: pio1_7 + 20: pio1_8 + 21: pio1_9 + 22: pio1_10 + 23: pio1_11 + 24: pio2_0 + 25: pio2_1 + 26: pio2_2 + 27: pio2_3 + 28: pio2_4 + 29: pio2_5 + 30: pio2_6 + 31: pio2_7 + 32: pio2_8 + 33: pio2_9 + 34: pio2_10 + 35: pio2_11 + 36: pio3_0 + 37: pio3_1 + 38: pio3_2 + 39: pio3_3 + 40: i2c0 + 41: ct16b0 + 42: ct16b1 + 43: ct32b0 + 44: ct32b1 + 45: ssp0 + 46: uart + 47: usb + 48: usb_fiq + 49: adc + 50: wdt + 51: bod +# 52: reserved + 53: pio3 + 54: pio2 + 55: pio1 + 56: pio0 + 56: ssp1 diff --git a/include/libopencm3/lpc17xx/irq.yaml b/include/libopencm3/lpc17xx/irq.yaml new file mode 100644 index 00000000..faa140f7 --- /dev/null +++ b/include/libopencm3/lpc17xx/irq.yaml @@ -0,0 +1,39 @@ +includeguard: LIBOPENCM3_LPC17xx_NVIC_H +partname_humanreadable: LPC 17xx series +partname_doxygen: LPC17xx +irqs: + 0: wdt + 1: timer0 + 2: timer1 + 3: timer2 + 4: timer3 + 5: uart0 + 6: uart1 + 7: uart2 + 8: uart3 + 9: pwm + 10: i2c0 + 11: i2c1 + 12: i2c2 + 13: spi + 14: ssp0 + 15: ssp1 + 16: pll0 + 17: rtc + 18: eint0 + 19: eint1 + 20: eint2 + 21: eint3 + 22: adc + 23: bod + 24: usb + 25: can + 26: gpdma + 27: i2s + 28: ethernet + 29: rit + 30: motor_pwm + 31: qei + 32: pll1 + 33: usb_act + 34: can_act diff --git a/include/libopencm3/lpc43xx/irq.yaml b/include/libopencm3/lpc43xx/irq.yaml new file mode 100644 index 00000000..bc9536b0 --- /dev/null +++ b/include/libopencm3/lpc43xx/irq.yaml @@ -0,0 +1,55 @@ +includeguard: LIBOPENCM3_LPC43xx_NVIC_H +partname_humanreadable: LPC 43xx series +partname_doxygen: LPC43xx +irqs: + 0: dac + 1: m0core + 2: dma +# reserved: 3, 4 + 5: ethernet + 6: sdio + 7: lcd + 8: usb0 + 9: usb1 + 10: sct + 11: ritimer + 12: timer0 + 13: timer1 + 14: timer2 + 15: timer3 + 16: mcpwm + 17: adc0 + 18: i2c0 + 19: i2c1 + 20: spi + 21: adc1 + 22: ssp0 + 23: ssp1 + 24: usart0 + 25: uart1 + 26: usart2 + 27: usart3 + 28: i2s0 + 29: i2s1 + 30: spifi + 31: sgpio + 32: pin_int0 + 33: pin_int1 + 34: pin_int2 + 35: pin_int3 + 36: pin_int4 + 37: pin_int5 + 38: pin_int6 + 39: pin_int7 + 40: gint0 + 41: gint1 + 42: eventrouter + 43: c_can1 +# reserved: 44, 45 + 46: atimer + 47: rtc +# reserved: 48 + 49: wwdt +# reserved: 50 + 51: c_can0 + 52: qei diff --git a/include/libopencm3/lpc43xx/nvic.h b/include/libopencm3/lpc43xx/nvic.h deleted file mode 100644 index cdbf0702..00000000 --- a/include/libopencm3/lpc43xx/nvic.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> - * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com> - * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LPC43XX_NVIC_H -#define LPC43XX_NVIC_H - -#include <libopencm3/cm3/common.h> -#include <libopencm3/cm3/memorymap.h> -#include <libopencm3/lpc43xx/memorymap.h> - -/* --- NVIC Registers ------------------------------------------------------ */ - -/* ISER: Interrupt Set Enable Registers */ -/* Note: 8 32bit Registers */ -#define NVIC_ISER(iser_id) MMIO32(NVIC_BASE + 0x00 + (iser_id * 4)) - -/* NVIC_BASE + 0x020 (0xE000 E120 - 0xE000 E17F): Reserved */ - -/* ICER: Interrupt Clear Enable Registers */ -/* Note: 8 32bit Registers */ -#define NVIC_ICER(icer_id) MMIO32(NVIC_BASE + 0x80 + (icer_id * 4)) - -/* NVIC_BASE + 0x0A0 (0xE000 E1A0 - 0xE000 E1FF): Reserved */ - -/* ISPR: Interrupt Set Pending Registers */ -/* Note: 8 32bit Registers */ -#define NVIC_ISPR(ispr_id) MMIO32(NVIC_BASE + 0x100 + (ispr_id * 4)) - -/* NVIC_BASE + 0x120 (0xE000 E220 - 0xE000 E27F): Reserved */ - -/* ICPR: Interrupt Clear Pending Registers */ -/* Note: 8 32bit Registers */ -#define NVIC_ICPR(icpr_id) MMIO32(NVIC_BASE + 0x180 + (icpr_id * 4)) - -/* NVIC_BASE + 0x1A0 (0xE000 E2A0 - 0xE00 E2FF): Reserved */ - -/* IABR: Interrupt Active Bit Register */ -/* Note: 8 32bit Registers */ -#define NVIC_IABR(iabr_id) MMIO32(NVIC_BASE + 0x200 + (iabr_id * 4)) - -/* NVIC_BASE + 0x220 (0xE000 E320 - 0xE000 E3FF): Reserved */ - -/* IPR: Interrupt Priority Registers */ -/* Note: 240 8bit Registers */ -#define NVIC_IPR(ipr_id) MMIO8(NVIC_BASE + 0x300 + ipr_id) - -/* STIR: Software Trigger Interrupt Register */ -#define NVIC_STIR MMIO32(STIR_BASE) - -/* --- IRQ channel numbers-------------------------------------------------- */ - -/* Cortex M4 System Interrupts */ -#define NVIC_NMI_IRQ -14 -#define NVIC_HARD_FAULT_IRQ -13 -#define NVIC_MEM_MANAGE_IRQ -12 -#define NVIC_BUS_FAULT_IRQ -11 -#define NVIC_USAGE_FAULT_IRQ -10 -/* irq numbers -6 to -9 are reserved */ -#define NVIC_SV_CALL_IRQ -5 -#define DEBUG_MONITOR_IRQ -4 -/* irq number -3 reserved */ -#define NVIC_PENDSV_IRQ -2 -#define NVIC_SYSTICK_IRQ -1 - -/* LPC43xx M4 specific user interrupts */ -#define NVIC_M4_DAC_IRQ 0 -#define NVIC_M4_M0CORE_IRQ 1 -#define NVIC_M4_DMA_IRQ 2 -#define NVIC_M4_ETHERNET_IRQ 5 -#define NVIC_M4_SDIO_IRQ 6 -#define NVIC_M4_LCD_IRQ 7 -#define NVIC_M4_USB0_IRQ 8 -#define NVIC_M4_USB1_IRQ 9 -#define NVIC_M4_SCT_IRQ 10 -#define NVIC_M4_RITIMER_IRQ 11 -#define NVIC_M4_TIMER0_IRQ 12 -#define NVIC_M4_TIMER1_IRQ 13 -#define NVIC_M4_TIMER2_IRQ 14 -#define NVIC_M4_TIMER3_IRQ 15 -#define NVIC_M4_MCPWM_IRQ 16 -#define NVIC_M4_ADC0_IRQ 17 -#define NVIC_M4_I2C0_IRQ 18 -#define NVIC_M4_I2C1_IRQ 19 -#define NVIC_M4_SPI_IRQ 20 -#define NVIC_M4_ADC1_IRQ 21 -#define NVIC_M4_SSP0_IRQ 22 -#define NVIC_M4_SSP1_IRQ 23 -#define NVIC_M4_USART0_IRQ 24 -#define NVIC_M4_UART1_IRQ 25 -#define NVIC_M4_USART2_IRQ 26 -#define NVIC_M4_USART3_IRQ 27 -#define NVIC_M4_I2S0_IRQ 28 -#define NVIC_M4_I2S1_IRQ 29 -#define NVIC_M4_SPIFI_IRQ 30 -#define NVIC_M4_SGPIO_IRQ 31 -#define NVIC_M4_PIN_INT0_IRQ 32 -#define NVIC_M4_PIN_INT1_IRQ 33 -#define NVIC_M4_PIN_INT2_IRQ 34 -#define NVIC_M4_PIN_INT3_IRQ 35 -#define NVIC_M4_PIN_INT4_IRQ 36 -#define NVIC_M4_PIN_INT5_IRQ 37 -#define NVIC_M4_PIN_INT6_IRQ 38 -#define NVIC_M4_PIN_INT7_IRQ 39 -#define NVIC_M4_GINT0_IRQ 40 -#define NVIC_M4_GINT1_IRQ 41 -#define NVIC_M4_EVENTROUTER_IRQ 42 -#define NVIC_M4_C_CAN1_IRQ 43 -#define NVIC_M4_ATIMER_IRQ 46 -#define NVIC_M4_RTC_IRQ 47 -#define NVIC_M4_WWDT_IRQ 49 -#define NVIC_M4_C_CAN0_IRQ 51 -#define NVIC_M4_QEI_IRQ 52 - -/* LPC43xx M0 specific user interrupts */ -//TODO - -/* --- NVIC functions ------------------------------------------------------ */ - -BEGIN_DECLS - -void nvic_enable_irq(u8 irqn); -void nvic_disable_irq(u8 irqn); -u8 nvic_get_pending_irq(u8 irqn); -void nvic_set_pending_irq(u8 irqn); -void nvic_clear_pending_irq(u8 irqn); -u8 nvic_get_active_irq(u8 irqn); -u8 nvic_get_irq_enabled(u8 irqn); -void nvic_set_priority(u8 irqn, u8 priority); -void nvic_generate_software_interrupt(u8 irqn); - -END_DECLS - -#endif diff --git a/include/libopencm3/lpc43xx/systick.h b/include/libopencm3/lpc43xx/systick.h deleted file mode 100644 index 2ae52c2b..00000000 --- a/include/libopencm3/lpc43xx/systick.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> - * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LIBOPENCM3_SYSTICK_H -#define LIBOPENCM3_SYSTICK_H - -#include <libopencm3/lpc43xx/memorymap.h> -#include <libopencm3/cm3/memorymap.h> -#include <libopencm3/cm3/common.h> - -/* --- SYSTICK registers --------------------------------------------------- */ -/* See also libopencm3\cm3\scs.h for details on SysTicks registers */ - -/* Control and status register (STK_CTRL) */ -#define STK_CTRL MMIO32(SYS_TICK_BASE + 0x00) - -/* reload value register (STK_LOAD) */ -#define STK_LOAD MMIO32(SYS_TICK_BASE + 0x04) - -/* current value register (STK_VAL) */ -#define STK_VAL MMIO32(SYS_TICK_BASE + 0x08) - -/* calibration value register (STK_CALIB) */ -#define STK_CALIB MMIO32(SYS_TICK_BASE + 0x0C) - -/* --- STK_CTRL values ----------------------------------------------------- */ -/* Bits [31:17] Reserved, must be kept cleared. */ -/* COUNTFLAG: */ -#define STK_CTRL_COUNTFLAG (1 << 16) -/* Bits [15:3] Reserved, must be kept cleared. */ -/* CLKSOURCE: Clock source selection */ -#define STK_CTRL_CLKSOURCE (1 << 2) -/* TICKINT: SysTick exception request enable */ -#define STK_CTRL_TICKINT (1 << 1) -/* ENABLE: Counter enable */ -#define STK_CTRL_ENABLE (1 << 0) - -/* --- STK_LOAD values ----------------------------------------------------- */ -/* Bits [31:24] Reserved, must be kept cleared. */ -/* RELOAD[23:0]: RELOAD value */ - -/* --- STK_VAL values ------------------------------------------------------ */ -/* Bits [31:24] Reserved, must be kept cleared. */ -/* CURRENT[23:0]: Current counter value */ - -/* --- STK_CALIB values ---------------------------------------------------- */ -/* NOREF: NOREF flag */ -#define STK_CALIB_NOREF (1 << 31) -/* SKEW: SKEW flag */ -#define STK_CALIB_SKEW (1 << 30) -/* Bits [29:24] Reserved, must be kept cleared. */ -/* TENMS[23:0]: Calibration value */ - -/* --- Function Prototypes ------------------------------------------------- */ - -BEGIN_DECLS - -void systick_set_reload(u32 value); -u32 systick_get_value(void); -void systick_set_clocksource(u8 clocksource); -void systick_interrupt_enable(void); -void systick_interrupt_disable(void); -void systick_counter_enable(void); -void systick_counter_disable(void); -u8 systick_get_countflag(void); - -u32 systick_get_calib(void); - -END_DECLS - -#endif diff --git a/include/libopencm3/stm32/can.h b/include/libopencm3/stm32/can.h index f787df76..c6c9d486 100644 --- a/include/libopencm3/stm32/can.h +++ b/include/libopencm3/stm32/can.h @@ -417,6 +417,7 @@ #define CAN_BTR_SJW_3TQ (0x2 << 24) #define CAN_BTR_SJW_4TQ (0x3 << 24) #define CAN_BTR_SJW_MASK (0x3 << 24) +#define CAN_BTR_SJW_SHIFT 24 /* 23 Reserved, forced by hardware to 0 */ @@ -430,6 +431,7 @@ #define CAN_BTR_TS2_7TQ (0x6 << 20) #define CAN_BTR_TS2_8TQ (0x7 << 20) #define CAN_BTR_TS2_MASK (0x7 << 20) +#define CAN_BTR_TS2_SHIFT 20 /* TS1[3:0]: Time segment 1 */ #define CAN_BTR_TS1_1TQ (0x0 << 16) @@ -449,6 +451,7 @@ #define CAN_BTR_TS1_15TQ (0xE << 16) #define CAN_BTR_TS1_16TQ (0xF << 16) #define CAN_BTR_TS1_MASK (0xF << 16) +#define CAN_BTR_TS1_SHIFT 16 /* 15:10 Reserved, forced by hardware to 0 */ @@ -458,7 +461,7 @@ /* --- CAN_TIxR values ------------------------------------------------------ */ /* STID[10:0]: Standard identifier */ -#define CAN_TIxR_STID_MASK (0x3FF << 21) +#define CAN_TIxR_STID_MASK (0x7FF << 21) #define CAN_TIxR_STID_SHIFT 21 /* EXID[15:0]: Extended identifier */ diff --git a/include/libopencm3/stm32/f1/desig.h b/include/libopencm3/stm32/desig.h index 74cfb353..6ceb6658 100644 --- a/include/libopencm3/stm32/f1/desig.h +++ b/include/libopencm3/stm32/desig.h @@ -51,6 +51,15 @@ u16 desig_get_flash_size(void); */ void desig_get_unique_id(u32 result[]); +/** + * Read the full 96 bit unique identifier and return it as a + * zero-terminated string + * @param string memory region to write the result to + 8 @param string_len the size of string in bytes + */ +void desig_get_unique_id_as_string(char *string, + unsigned int string_len); + END_DECLS #endif diff --git a/include/libopencm3/stm32/exti.h b/include/libopencm3/stm32/exti.h index 7645825d..48065b9a 100644 --- a/include/libopencm3/stm32/exti.h +++ b/include/libopencm3/stm32/exti.h @@ -53,6 +53,9 @@ #define EXTI17 (1 << 17) #define EXTI18 (1 << 18) #define EXTI19 (1 << 19) +#define EXTI20 (1 << 20) +#define EXTI21 (1 << 21) +#define EXTI22 (1 << 22) /* Trigger types */ typedef enum trigger_e { diff --git a/include/libopencm3/stm32/f1/dma.h b/include/libopencm3/stm32/f1/dma.h index 8a2edbad..6257394c 100644 --- a/include/libopencm3/stm32/f1/dma.h +++ b/include/libopencm3/stm32/f1/dma.h @@ -141,9 +141,30 @@ LGPL License Terms @ref lgpl_license /* --- DMA_ISR values ------------------------------------------------------ */ +/* --- DMA Interrupt Flag offset values ------------------------------------- */ +/* These are based on every interrupt flag and flag clear being at the same relative location */ +/** @defgroup dma_if_offset DMA Interrupt Flag Offsets within stream flag group. +@ingroup STM32F1xx_dma_defines + +@{*/ +/** Transfer Error Interrupt Flag */ +#define DMA_TEIF (1 << 3) +/** Half Transfer Interrupt Flag */ +#define DMA_HTIF (1 << 2) +/** Transfer Complete Interrupt Flag */ +#define DMA_TCIF (1 << 1) +/** Global Interrupt Flag */ +#define DMA_GIF (1 << 0) +/**@}*/ + +/* Offset within interrupt status register to start of stream interrupt flag field */ +#define DMA_FLAG_OFFSET(channel) (4*(channel - 1)) +#define DMA_FLAGS (DMA_TEIF | DMA_TCIF | DMA_HTIF | DMA_GIF) +#define DMA_ISR_MASK(channel) DMA_FLAGS << DMA_FLAG_OFFSET(channel) + /* TEIF: Transfer error interrupt flag */ -#define DMA_ISR_TEIF_BIT (1 << 3) -#define DMA_ISR_TEIF(channel) (DMA_ISR_TEIF_BIT << (4 * ((channel) -1))) +#define DMA_ISR_TEIF_BIT DMA_ISR_TEIF +#define DMA_ISR_TEIF(channel) (DMA_ISR_TEIF_BIT << DMA_FLAG_OFFSET(channel))) #define DMA_ISR_TEIF1 DMA_ISR_TEIF(DMA_CHANNEL1) #define DMA_ISR_TEIF2 DMA_ISR_TEIF(DMA_CHANNEL2) @@ -154,8 +175,8 @@ LGPL License Terms @ref lgpl_license #define DMA_ISR_TEIF7 DMA_ISR_TEIF(DMA_CHANNEL7) /* HTIF: Half transfer interrupt flag */ -#define DMA_ISR_HTIF_BIT (1 << 2) -#define DMA_ISR_HTIF(channel) (DMA_ISR_HTIF_BIT << (4 * ((channel) -1))) +#define DMA_ISR_HTIF_BIT DMA_HTIF +#define DMA_ISR_HTIF(channel) (DMA_ISR_HTIF_BIT << DMA_FLAG_OFFSET(channel))) #define DMA_ISR_HTIF1 DMA_ISR_HTIF(DMA_CHANNEL1) #define DMA_ISR_HTIF2 DMA_ISR_HTIF(DMA_CHANNEL2) @@ -166,8 +187,8 @@ LGPL License Terms @ref lgpl_license #define DMA_ISR_HTIF7 DMA_ISR_HTIF(DMA_CHANNEL7) /* TCIF: Transfer complete interrupt flag */ -#define DMA_ISR_TCIF_BIT (1 << 1) -#define DMA_ISR_TCIF(channel) (DMA_ISR_TCIF_BIT << (4 * ((channel) -1))) +#define DMA_ISR_TCIF_BIT DMA_TCIF +#define DMA_ISR_TCIF(channel) (DMA_ISR_TCIF_BIT << (DMA_FLAG_OFFSET(channel))) #define DMA_ISR_TCIF1 DMA_ISR_TCIF(DMA_CHANNEL1) #define DMA_ISR_TCIF2 DMA_ISR_TCIF(DMA_CHANNEL2) @@ -178,8 +199,8 @@ LGPL License Terms @ref lgpl_license #define DMA_ISR_TCIF7 DMA_ISR_TCIF(DMA_CHANNEL7) /* GIF: Global interrupt flag */ -#define DMA_ISR_GIF_BIT (1 << 0) -#define DMA_ISR_GIF(channel) (DMA_ISR_GIF_BIT << (4 * ((channel) -1))) +#define DMA_ISR_GIF_BIT DMA_GIF +#define DMA_ISR_GIF(channel) (DMA_ISR_GIF_BIT << (DMA_FLAG_OFFSET(channel))) #define DMA_ISR_GIF1 DMA_ISR_GIF(DMA_CHANNEL1) #define DMA_ISR_GIF2 DMA_ISR_GIF(DMA_CHANNEL2) @@ -192,8 +213,8 @@ LGPL License Terms @ref lgpl_license /* --- DMA_IFCR values ----------------------------------------------------- */ /* CTEIF: Transfer error clear */ -#define DMA_IFCR_CTEIF_BIT (1 << 3) -#define DMA_IFCR_CTEIF(channel) (DMA_IFCR_CTEIF_BIT << (4 * ((channel) -1))) +#define DMA_IFCR_CTEIF_BIT DMA_TEIF +#define DMA_IFCR_CTEIF(channel) (DMA_IFCR_CTEIF_BIT << (DMA_FLAG_OFFSET(channel))) #define DMA_IFCR_CTEIF1 DMA_IFCR_CTEIF(DMA_CHANNEL1) #define DMA_IFCR_CTEIF2 DMA_IFCR_CTEIF(DMA_CHANNEL2) @@ -204,8 +225,8 @@ LGPL License Terms @ref lgpl_license #define DMA_IFCR_CTEIF7 DMA_IFCR_CTEIF(DMA_CHANNEL7) /* CHTIF: Half transfer clear */ -#define DMA_IFCR_CHTIF_BIT (1 << 2) -#define DMA_IFCR_CHTIF(channel) (DMA_IFCR_CHTIF_BIT << (4 * ((channel) -1))) +#define DMA_IFCR_CHTIF_BIT DMA_HTIF +#define DMA_IFCR_CHTIF(channel) (DMA_IFCR_CHTIF_BIT << (DMA_FLAG_OFFSET(channel))) #define DMA_IFCR_CHTIF1 DMA_IFCR_CHTIF(DMA_CHANNEL1) #define DMA_IFCR_CHTIF2 DMA_IFCR_CHTIF(DMA_CHANNEL2) @@ -216,8 +237,8 @@ LGPL License Terms @ref lgpl_license #define DMA_IFCR_CHTIF7 DMA_IFCR_CHTIF(DMA_CHANNEL7) /* CTCIF: Transfer complete clear */ -#define DMA_IFCR_CTCIF_BIT (1 << 1) -#define DMA_IFCR_CTCIF(channel) (DMA_IFCR_CTCIF_BIT << (4 * ((channel) -1))) +#define DMA_IFCR_CTCIF_BIT DMA_TCIF +#define DMA_IFCR_CTCIF(channel) (DMA_IFCR_CTCIF_BIT << (DMA_FLAG_OFFSET(channel))) #define DMA_IFCR_CTCIF1 DMA_IFCR_CTCIF(DMA_CHANNEL1) #define DMA_IFCR_CTCIF2 DMA_IFCR_CTCIF(DMA_CHANNEL2) @@ -228,8 +249,8 @@ LGPL License Terms @ref lgpl_license #define DMA_IFCR_CTCIF7 DMA_IFCR_CTCIF(DMA_CHANNEL7) /* CGIF: Global interrupt clear */ -#define DMA_IFCR_CGIF_BIT (1 << 0) -#define DMA_IFCR_CGIF(channel) (DMA_IFCR_CGIF_BIT << (4 * ((channel) -1))) +#define DMA_IFCR_CGIF_BIT DMA_GIF +#define DMA_IFCR_CGIF(channel) (DMA_IFCR_CGIF_BIT << (DMA_FLAG_OFFSET(channel))) #define DMA_IFCR_CGIF1 DMA_IFCR_CGIF(DMA_CHANNEL1) #define DMA_IFCR_CGIF2 DMA_IFCR_CGIF(DMA_CHANNEL2) @@ -241,7 +262,7 @@ LGPL License Terms @ref lgpl_license /* Clear interrupts mask */ #define DMA_IFCR_CIF_BIT 0xF -#define DMA_IFCR_CIF(channel) (DMA_IFCR_CIF_BIT << (4 * ((channel) - 1))) +#define DMA_IFCR_CIF(channel) (DMA_IFCR_CIF_BIT << (DMA_FLAG_OFFSET(channel))) #define DMA_IFCR_CIF1 DMA_IFCR_CIF(DMA_CHANNEL1) #define DMA_IFCR_CIF2 DMA_IFCR_CIF(DMA_CHANNEL2) @@ -349,12 +370,16 @@ LGPL License Terms @ref lgpl_license BEGIN_DECLS void dma_channel_reset(u32 dma, u8 channel); +void dma_clear_interrupt_flags(u32 dma, u8 channel, u32 interrupts); +bool dma_get_interrupt_flag(u32 dma, u8 channel, u32 interrupts); void dma_enable_mem2mem_mode(u32 dma, u8 channel); void dma_set_priority(u32 dma, u8 channel, u32 prio); void dma_set_memory_size(u32 dma, u8 channel, u32 mem_size); void dma_set_peripheral_size(u32 dma, u8 channel, u32 peripheral_size); void dma_enable_memory_increment_mode(u32 dma, u8 channel); +void dma_disable_memory_increment_mode(u32 dma, u8 channel); void dma_enable_peripheral_increment_mode(u32 dma, u8 channel); +void dma_disable_peripheral_increment_mode(u32 dma, u8 channel); void dma_enable_circular_mode(u32 dma, u8 channel); void dma_set_read_from_peripheral(u32 dma, u8 channel); void dma_set_read_from_memory(u32 dma, u8 channel); diff --git a/include/libopencm3/stm32/f1/gpio.h b/include/libopencm3/stm32/f1/gpio.h index a1e74cc2..f3425045 100644 --- a/include/libopencm3/stm32/f1/gpio.h +++ b/include/libopencm3/stm32/f1/gpio.h @@ -103,18 +103,18 @@ LGPL License Terms @ref lgpl_license /* CAN1 / CAN BANK */ #define GPIO_BANK_CAN1_RX GPIOA /* PA11 */ #define GPIO_BANK_CAN1_TX GPIOA /* PA12 */ -#define GPIO_BANK_CAN_RX GPIO_CAN1_RX /* Alias */ -#define GPIO_BANK_CAN_TX GPIO_CAN1_TX /* Alias */ +#define GPIO_BANK_CAN_RX GPIO_BANK_CAN1_RX /* Alias */ +#define GPIO_BANK_CAN_TX GPIO_BANK_CAN1_TX /* Alias */ #define GPIO_BANK_CAN_PB_RX GPIOB /* PB8 */ #define GPIO_BANK_CAN_PB_TX GPIOB /* PB9 */ -#define GPIO_BANK_CAN1_PB_RX GPIO_CAN_PB_RX /* Alias */ -#define GPIO_BANK_CAN1_PB_TX GPIO_CAN_PB_TX /* Alias */ +#define GPIO_BANK_CAN1_PB_RX GPIO_BANK_CAN_PB_RX /* Alias */ +#define GPIO_BANK_CAN1_PB_TX GPIO_BANK_CAN_PB_TX /* Alias */ #define GPIO_BANK_CAN_PD_RX GPIOD /* PD0 */ #define GPIO_BANK_CAN_PD_TX GPIOD /* PD1 */ -#define GPIO_BANK_CAN1_PD_RX GPIO_CAN_PD_RX /* Alias */ -#define GPIO_BANK_CAN1_PD_TX GPIO_CAN_PD_TX /* Alias */ +#define GPIO_BANK_CAN1_PD_RX GPIO_BANK_CAN_PD_RX /* Alias */ +#define GPIO_BANK_CAN1_PD_TX GPIO_BANK_CAN_PD_TX /* Alias */ /* CAN2 GPIO */ #define GPIO_CAN2_RX GPIO12 /* PB12 */ diff --git a/include/libopencm3/stm32/f1/irq.yaml b/include/libopencm3/stm32/f1/irq.yaml new file mode 100644 index 00000000..14cbcc03 --- /dev/null +++ b/include/libopencm3/stm32/f1/irq.yaml @@ -0,0 +1,72 @@ +includeguard: LIBOPENCM3_STM32_F1_NVIC_H +partname_humanreadable: STM32 F1 series +partname_doxygen: STM32F1 +irqs: + - wwdg + - pvd + - tamper + - rtc + - flash + - rcc + - exti0 + - exti1 + - exti2 + - exti3 + - exti4 + - dma1_channel1 + - dma1_channel2 + - dma1_channel3 + - dma1_channel4 + - dma1_channel5 + - dma1_channel6 + - dma1_channel7 + - adc1_2 + - usb_hp_can_tx + - usb_lp_can_rx0 + - can_rx1 + - can_sce + - exti9_5 + - tim1_brk + - tim1_up + - tim1_trg_com + - tim1_cc + - tim2 + - tim3 + - tim4 + - i2c1_ev + - i2c1_er + - i2c2_ev + - i2c2_er + - spi1 + - spi2 + - usart1 + - usart2 + - usart3 + - exti15_10 + - rtc_alarm + - usb_wakeup + - tim8_brk + - tim8_up + - tim8_trg_com + - tim8_cc + - adc3 + - fsmc + - sdio + - tim5 + - spi3 + - uart4 + - uart5 + - tim6 + - tim7 + - dma2_channel1 + - dma2_channel2 + - dma2_channel3 + - dma2_channel4_5 + - dma2_channel5 + - eth + - eth_wkup + - can2_tx + - can2_rx0 + - can2_rx1 + - can2_sce + - otg_fs diff --git a/include/libopencm3/stm32/f1/nvic_f1.h b/include/libopencm3/stm32/f1/nvic_f1.h deleted file mode 100644 index 5223bb6b..00000000 --- a/include/libopencm3/stm32/f1/nvic_f1.h +++ /dev/null @@ -1,114 +0,0 @@ -/** @brief <b>Defined Constants and Types for the STM32F1xx Nested Vectored Interrupt Controller</b> - -@version 1.0.0 - -@author @htmlonly © @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org> - -@date 18 August 2012 - -LGPL License Terms @ref lgpl_license - */ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LIBOPENCM3_NVIC_F1_H -#define LIBOPENCM3_NVIC_F1_H - -/* --- IRQ channel numbers-------------------------------------------------- */ - -/* Note: These F1 specific user interrupt definitions supplement the - * general NVIC definitions in ../nvic.h - */ - -/* User Interrupts */ -/** @defgroup nvic_stm32f1_userint STM32F1xx User Interrupts -@ingroup STM32F_nvic_defines - -@{*/ -#define NVIC_WWDG_IRQ 0 -#define NVIC_PVD_IRQ 1 -#define NVIC_TAMPER_IRQ 2 -#define NVIC_RTC_IRQ 3 -#define NVIC_FLASH_IRQ 4 -#define NVIC_RCC_IRQ 5 -#define NVIC_EXTI0_IRQ 6 -#define NVIC_EXTI1_IRQ 7 -#define NVIC_EXTI2_IRQ 8 -#define NVIC_EXTI3_IRQ 9 -#define NVIC_EXTI4_IRQ 10 -#define NVIC_DMA1_CHANNEL1_IRQ 11 -#define NVIC_DMA1_CHANNEL2_IRQ 12 -#define NVIC_DMA1_CHANNEL3_IRQ 13 -#define NVIC_DMA1_CHANNEL4_IRQ 14 -#define NVIC_DMA1_CHANNEL5_IRQ 15 -#define NVIC_DMA1_CHANNEL6_IRQ 16 -#define NVIC_DMA1_CHANNEL7_IRQ 17 -#define NVIC_ADC1_2_IRQ 18 -#define NVIC_USB_HP_CAN_TX_IRQ 19 -#define NVIC_USB_LP_CAN_RX0_IRQ 20 -#define NVIC_CAN_RX1_IRQ 21 -#define NVIC_CAN_SCE_IRQ 22 -#define NVIC_EXTI9_5_IRQ 23 -#define NVIC_TIM1_BRK_IRQ 24 -#define NVIC_TIM1_UP_IRQ 25 -#define NVIC_TIM1_TRG_COM_IRQ 26 -#define NVIC_TIM1_CC_IRQ 27 -#define NVIC_TIM2_IRQ 28 -#define NVIC_TIM3_IRQ 29 -#define NVIC_TIM4_IRQ 30 -#define NVIC_I2C1_EV_IRQ 31 -#define NVIC_I2C1_ER_IRQ 32 -#define NVIC_I2C2_EV_IRQ 33 -#define NVIC_I2C2_ER_IRQ 34 -#define NVIC_SPI1_IRQ 35 -#define NVIC_SPI2_IRQ 36 -#define NVIC_USART1_IRQ 37 -#define NVIC_USART2_IRQ 38 -#define NVIC_USART3_IRQ 39 -#define NVIC_EXTI15_10_IRQ 40 -#define NVIC_RTC_ALARM_IRQ 41 -#define NVIC_USB_WAKEUP_IRQ 42 -#define NVIC_TIM8_BRK_IRQ 43 -#define NVIC_TIM8_UP_IRQ 44 -#define NVIC_TIM8_TRG_COM_IRQ 45 -#define NVIC_TIM8_CC_IRQ 46 -#define NVIC_ADC3_IRQ 47 -#define NVIC_FSMC_IRQ 48 -#define NVIC_SDIO_IRQ 49 -#define NVIC_TIM5_IRQ 50 -#define NVIC_SPI3_IRQ 51 -#define NVIC_UART4_IRQ 52 -#define NVIC_UART5_IRQ 53 -#define NVIC_TIM6_IRQ 54 -#define NVIC_TIM7_IRQ 55 -#define NVIC_DMA2_CHANNEL1_IRQ 56 -#define NVIC_DMA2_CHANNEL2_IRQ 57 -#define NVIC_DMA2_CHANNEL3_IRQ 58 -#define NVIC_DMA2_CHANNEL4_5_IRQ 59 -#define NVIC_DMA2_CHANNEL5_IRQ 60 -#define NVIC_ETH_IRQ 61 -#define NVIC_ETH_WKUP_IRQ 62 -#define NVIC_CAN2_TX_IRQ 63 -#define NVIC_CAN2_RX0_IRQ 64 -#define NVIC_CAN2_RX1_IRQ 65 -#define NVIC_CAN2_SCE_IRQ 66 -#define NVIC_OTG_FS_IRQ 67 -/**@}*/ - -#endif diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index 52b3469c..868ad9ce 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -507,6 +507,7 @@ void rcc_osc_on(osc_t osc); void rcc_osc_off(osc_t osc); void rcc_css_enable(void); void rcc_css_disable(void); +void rcc_set_mco(u32 mcosrc); void rcc_osc_bypass_enable(osc_t osc); void rcc_osc_bypass_disable(osc_t osc); void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en); diff --git a/include/libopencm3/stm32/f1/scb.h b/include/libopencm3/stm32/f1/scb.h deleted file mode 100644 index 181aa7a0..00000000 --- a/include/libopencm3/stm32/f1/scb.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> - * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LIBOPENCM3_SCB_H -#define LIBOPENCM3_SCB_H - -#include <libopencm3/stm32/memorymap.h> -#include <libopencm3/cm3/common.h> - -/* --- SCB: Registers ------------------------------------------------------ */ - -/* CPUID: CPUID base register */ -#define SCB_CPUID MMIO32(SCB_BASE + 0x00) - -/* ICSR: Interrupt Control State Register */ -#define SCB_ICSR MMIO32(SCB_BASE + 0x04) - -/* VTOR: Vector Table Offset Register */ -#define SCB_VTOR MMIO32(SCB_BASE + 0x08) - -/* AIRCR: Application Interrupt and Reset Control Register */ -#define SCB_AIRCR MMIO32(SCB_BASE + 0x0C) - -/* SCR: System Control Register */ -#define SCB_SCR MMIO32(SCB_BASE + 0x10) - -/* CCR: Configuration Control Register */ -#define SCB_CCR MMIO32(SCB_BASE + 0x14) - -/* SHP: System Handler Priority Registers */ -/* Note: 12 8bit registers */ -#define SCB_SHPR(shpr_id) MMIO8(SCB_BASE + 0x18 + shpr_id) -#define SCB_SHPR1 MMIO8(SCB_BASE + 0x18 + 1) -#define SCB_SHPR2 MMIO8(SCB_BASE + 0x18 + 2) -#define SCB_SHPR3 MMIO8(SCB_BASE + 0x18 + 3) - -/* SHCSR: System Handler Control and State Register */ -#define SCB_SHCSR MMIO32(SCB_BASE + 0x24) - -/* CFSR: Configurable Fault Status Registers */ -#define SCB_CFSR MMIO32(SCB_BASE + 0x28) - -/* HFSR: Hard Fault Status Register */ -#define SCB_HFSR MMIO32(SCB_BASE + 0x2C) - -/* DFSR: Debug Fault Status Register */ -#define SCB_DFSR MMIO32(SCB_BASE + 0x30) - -/* MMFAR: Memory Manage Fault Address Register */ -#define SCB_MMFAR MMIO32(SCB_BASE + 0x34) - -/* BFAR: Bus Fault Address Register */ -#define SCB_BFAR MMIO32(SCB_BASE + 0x38) - -/* AFSR: Auxiliary Fault Status Register */ -#define SCB_AFSR MMIO32(SCB_BASE + 0x3C) - -/* --- SCB values ---------------------------------------------------------- */ - -/* --- SCB_CPUID values ---------------------------------------------------- */ - -/* Implementer[31:24]: Implementer code */ -#define SCP_CPUID_IMPLEMENTER_LSB 24 -/* Variant[23:20]: Variant number */ -#define SCP_CPUID_VARIANT_LSB 20 -/* Constant[19:16]: Reads as 0xF */ -#define SCP_CPUID_CONSTANT_LSB 16 -/* PartNo[15:4]: Part number of the processor */ -#define SCP_CPUID_PARTNO_LSB 4 -/* Revision[3:0]: Revision number */ -#define SCP_CPUID_REVISION_LSB 0 - -/* --- SCB_ICSR values ----------------------------------------------------- */ - -/* NMIPENDSET: NMI set-pending bit */ -#define SCB_ICSR_NMIPENDSET (1 << 31) -/* Bits [30:29]: reserved - must be kept cleared */ -/* PENDSVSET: PendSV set-pending bit */ -#define SCB_ICSR_PENDSVSET (1 << 28) -/* PENDSVCLR: PendSV clear-pending bit */ -#define SCB_ICSR_PENDSVCLR (1 << 27) -/* PENDSTSET: SysTick exception set-pending bit */ -#define SCB_ICSR_PENDSTSET (1 << 26) -/* PENDSTCLR: SysTick exception clear-pending bit */ -#define SCB_ICSR_PENDSTCLR (1 << 25) -/* Bit 24: reserved - must be kept cleared */ -/* Bit 23: reserved for debug - reads as 0 when not in debug mode */ -/* ISRPENDING: Interrupt pending flag, excluding NMI and Faults */ -#define SCB_ICSR_ISRPENDING (1 << 22) -/* VECTPENDING[21:12] Pending vector */ -#define SCB_ICSR_VECTPENDING_LSB 12 -/* RETOBASE: Return to base level */ -#define SCB_ICSR_RETOBASE (1 << 11) -/* Bits [10:9]: reserved - must be kept cleared */ -/* VECTACTIVE[8:0] Active vector */ -#define SCB_ICSR_VECTACTIVE_LSB 0 - -/* --- SCB_VTOR values ----------------------------------------------------- */ - -/* Bits [31:30]: reserved - must be kept cleared */ -/* TBLOFF[29:9]: Vector table base offset field */ -#define SCB_VTOR_TBLOFF_LSB 9 /* inconsistent datasheet - LSB could be 11 */ - -/* --- SCB_AIRCR values ---------------------------------------------------- */ - -/* VECTKEYSTAT[31:16]/ VECTKEY[31:16] Register key */ -#define SCB_AIRCR_VECTKEYSTAT_LSB 16 -#define SCB_AIRCR_VECTKEY 0x05FA0000 -/* ENDIANESS Data endianness bit */ -#define SCB_AIRCR_ENDIANESS (1 << 15) -/* Bits [14:11]: reserved - must be kept cleared */ -/* PRIGROUP[10:8]: Interrupt priority grouping field */ -#define SCB_AIRCR_PRIGROUP_GROUP16_NOSUB (0x3 << 8) -#define SCB_AIRCR_PRIGROUP_GROUP8_SUB2 (0x4 << 8) -#define SCB_AIRCR_PRIGROUP_GROUP4_SUB4 (0x5 << 8) -#define SCB_AIRCR_PRIGROUP_GROUP2_SUB8 (0x6 << 8) -#define SCB_AIRCR_PRIGROUP_NOGROUP_SUB16 (0x7 << 8) -#define SCB_AIRCR_PRIGROUP_MASK (0x7 << 8) -#define SCB_AIRCR_PRIGROUP_SHIFT 8 -/* Bits [7:3]: reserved - must be kept cleared */ -/* SYSRESETREQ System reset request */ -#define SCB_AIRCR_SYSRESETREQ (1 << 2) -/* VECTCLRACTIVE */ -#define SCB_AIRCR_VECTCLRACTIVE (1 << 1) -/* VECTRESET */ -#define SCB_AIRCR_VECTRESET (1 << 0) - -/* --- SCB_SCR values ------------------------------------------------------ */ - -/* Bits [31:5]: reserved - must be kept cleared */ -/* SEVEONPEND Send Event on Pending bit */ -#define SCB_SCR_SEVEONPEND (1 << 4) -/* Bit 3: reserved - must be kept cleared */ -/* SLEEPDEEP */ -#define SCB_SCR_SLEEPDEEP (1 << 2) -/* SLEEPONEXIT */ -#define SCB_SCR_SLEEPONEXIT (1 << 1) -/* Bit 0: reserved - must be kept cleared */ - -/* --- SCB_CCR values ------------------------------------------------------ */ - -/* Bits [31:10]: reserved - must be kept cleared */ -/* STKALIGN */ -#define SCB_CCR_STKALIGN (1 << 9) -/* BFHFNMIGN */ -#define SCB_CCR_BFHFNMIGN (1 << 8) -/* Bits [7:5]: reserved - must be kept cleared */ -/* DIV_0_TRP */ -#define SCB_CCR_DIV_0_TRP (1 << 4) -/* UNALIGN_TRP */ -#define SCB_CCR_UNALIGN_TRP (1 << 3) -/* Bit 2: reserved - must be kept cleared */ -/* USERSETMPEND */ -#define SCB_CCR_USERSETMPEND (1 << 1) -/* NONBASETHRDENA */ -#define SCB_CCR_NONBASETHRDENA (1 << 0) - -/* --- SCB_SHPR1 values ---------------------------------------------------- */ - -/* Bits [31:24]: reserved - must be kept cleared */ -/* PRI_6[23:16]: Priority of system handler 6, usage fault */ -#define SCB_SHPR1_PRI_6_LSB 16 -/* PRI_5[15:8]: Priority of system handler 5, bus fault */ -#define SCB_SHPR1_PRI_5_LSB 8 -/* PRI_4[7:0]: Priority of system handler 4, memory management fault */ -#define SCB_SHPR1_PRI_4_LSB 0 - -/* --- SCB_SHPR2 values ---------------------------------------------------- */ - -/* PRI_11[31:24]: Priority of system handler 11, SVCall */ -#define SCB_SHPR2_PRI_11_LSB 24 -/* Bits [23:0]: reserved - must be kept cleared */ - -/* --- SCB_SHPR3 values ---------------------------------------------------- */ - -/* PRI_15[31:24]: Priority of system handler 15, SysTick exception */ -#define SCB_SHPR3_PRI_15_LSB 24 -/* PRI_14[23:16]: Priority of system handler 14, PendSV */ -#define SCB_SHPR3_PRI_14_LSB 16 -/* Bits [15:0]: reserved - must be kept cleared */ - -/* --- SCB_SHCSR values ---------------------------------------------------- */ - -/* Bits [31:19]: reserved - must be kept cleared */ -/* USGFAULTENA: Usage fault enable */ -#define SCB_SHCSR_USGFAULTENA (1 << 18) -/* BUSFAULTENA: Bus fault enable */ -#define SCB_SHCSR_BUSFAULTENA (1 << 17) -/* MEMFAULTENA: Memory management fault enable */ -#define SCB_SHCSR_MEMFAULTENA (1 << 16) -/* SVCALLPENDED: SVC call pending */ -#define SCB_SHCSR_SVCALLPENDED (1 << 15) -/* BUSFAULTPENDED: Bus fault exception pending */ -#define SCB_SHCSR_BUSFAULTPENDED (1 << 14) -/* MEMFAULTPENDED: Memory management fault exception pending */ -#define SCB_SHCSR_MEMFAULTPENDED (1 << 13) -/* USGFAULTPENDED: Usage fault exception pending */ -#define SCB_SHCSR_USGFAULTPENDED (1 << 12) -/* SYSTICKACT: SysTick exception active */ -#define SCB_SHCSR_SYSTICKACT (1 << 11) -/* PENDSVACT: PendSV exception active */ -#define SCB_SHCSR_PENDSVACT (1 << 10) -/* Bit 9: reserved - must be kept cleared */ -/* MONITORACT: Debug monitor active */ -#define SCB_SHCSR_MONITORACT (1 << 8) -/* SVCALLACT: SVC call active */ -#define SCB_SHCSR_SVCALLACT (1 << 7) -/* Bits [6:4]: reserved - must be kept cleared */ -/* USGFAULTACT: Usage fault exception active */ -#define SCB_SHCSR_USGFAULTACT (1 << 3) -/* Bit 2: reserved - must be kept cleared */ -/* BUSFAULTACT: Bus fault exception active */ -#define SCB_SHCSR_BUSFAULTACT (1 << 1) -/* MEMFAULTACT: Memory management fault exception active */ -#define SCB_SHCSR_MEMFAULTACT (1 << 0) - -/* --- SCB_CFSR values ----------------------------------------------------- */ - -/* Bits [31:26]: reserved - must be kept cleared */ -/* DIVBYZERO: Divide by zero usage fault */ -#define SCB_CFSR_DIVBYZERO (1 << 25) -/* UNALIGNED: Unaligned access usage fault */ -#define SCB_CFSR_UNALIGNED (1 << 24) -/* Bits [23:20]: reserved - must be kept cleared */ -/* NOCP: No coprocessor usage fault */ -#define SCB_CFSR_NOCP (1 << 19) -/* INVPC: Invalid PC load usage fault */ -#define SCB_CFSR_INVPC (1 << 18) -/* INVSTATE: Invalid state usage fault */ -#define SCB_CFSR_INVSTATE (1 << 17) -/* UNDEFINSTR: Undefined instruction usage fault */ -#define SCB_CFSR_UNDEFINSTR (1 << 16) -/* BFARVALID: Bus Fault Address Register (BFAR) valid flag */ -#define SCB_CFSR_BFARVALID (1 << 15) -/* Bits [14:13]: reserved - must be kept cleared */ -/* STKERR: Bus fault on stacking for exception entry */ -#define SCB_CFSR_STKERR (1 << 12) -/* UNSTKERR: Bus fault on unstacking for a return from exception */ -#define SCB_CFSR_UNSTKERR (1 << 11) -/* IMPRECISERR: Imprecise data bus error */ -#define SCB_CFSR_IMPRECISERR (1 << 10) -/* PRECISERR: Precise data bus error */ -#define SCB_CFSR_PRECISERR (1 << 9) -/* IBUSERR: Instruction bus error */ -#define SCB_CFSR_IBUSERR (1 << 8) -/* MMARVALID: Memory Management Fault Address Register (MMAR) valid flag */ -#define SCB_CFSR_MMARVALID (1 << 7) -/* Bits [6:5]: reserved - must be kept cleared */ -/* MSTKERR: Memory manager fault on stacking for exception entry */ -#define SCB_CFSR_MSTKERR (1 << 4) -/* MUNSTKERR: Memory manager fault on unstacking for a return from exception */ -#define SCB_CFSR_MUNSTKERR (1 << 3) -/* Bit 2: reserved - must be kept cleared */ -/* DACCVIOL: Data access violation flag */ -#define SCB_CFSR_DACCVIOL (1 << 1) -/* IACCVIOL: Instruction access violation flag */ -#define SCB_CFSR_IACCVIOL (1 << 0) - -/* --- SCB_HFSR values ----------------------------------------------------- */ - -/* DEBUG_VT: reserved for debug use */ -#define SCB_HFSR_DEBUG_VT (1 << 31) -/* FORCED: Forced hard fault */ -#define SCB_HFSR_FORCED (1 << 30) -/* Bits [29:2]: reserved - must be kept cleared */ -/* VECTTBL: Vector table hard fault */ -#define SCB_HFSR_VECTTBL (1 << 1) -/* Bit 0: reserved - must be kept cleared */ - -/* --- SCB_MMFAR values ---------------------------------------------------- */ - -/* MMFAR [31:0]: Memory management fault address */ - -/* --- SCB_BFAR values ----------------------------------------------------- */ - -/* BFAR [31:0]: Bus fault address */ - -/* --- SCB functions ------------------------------------------------------- */ - -BEGIN_DECLS - -void scb_reset_core(void); -void scb_reset_system(void); -void scb_set_priority_grouping(u32 prigroup); - -/* TODO: */ - -END_DECLS - -#endif diff --git a/include/libopencm3/stm32/f2/irq.yaml b/include/libopencm3/stm32/f2/irq.yaml new file mode 100644 index 00000000..c3600b36 --- /dev/null +++ b/include/libopencm3/stm32/f2/irq.yaml @@ -0,0 +1,85 @@ +includeguard: LIBOPENCM3_STM32_F2_NVIC_H +partname_humanreadable: STM32 F2 series +partname_doxygen: STM32F2 +irqs: + - nvic_wwdg + - pvd + - tamp_stamp + - rtc_wkup + - flash + - rcc + - exti0 + - exti1 + - exti2 + - exti3 + - exti4 + - dma1_stream0 + - dma1_stream1 + - dma1_stream2 + - dma1_stream3 + - dma1_stream4 + - dma1_stream5 + - dma1_stream6 + - adc + - can1_tx + - can1_rx0 + - can1_rx1 + - can1_sce + - exti9_5 + - tim1_brk_tim9 + - tim1_up_tim10 + - tim1_trg_com_tim11 + - tim1_cc + - tim2 + - tim3 + - tim4 + - i2c1_ev + - i2c1_er + - i2c2_ev + - i2c2_er + - spi1 + - spi2 + - usart1 + - usart2 + - usart3 + - exti15_10 + - rtc_alarm + - usb_fs_wkup + - tim8_brk_tim12 + - tim8_up_tim13 + - tim8_trg_com_tim14 + - tim8_cc + - dma1_stream7 + - fsmc + - sdio + - tim5 + - spi3 + - uart4 + - uart5 + - tim6_dac + - tim7 + - dma2_stream0 + - dma2_stream1 + - dma2_stream2 + - dma2_stream3 + - dma2_stream4 + - eth + - eth_wkup + - can2_tx + - can2_rx0 + - can2_rx1 + - can2_sce + - otg_fs + - dma2_stream5 + - dma2_stream6 + - dma2_stream7 + - usart6 + - i2c3_ev + - i2c3_er + - otg_hs_ep1_out + - otg_hs_ep1_in + - otg_hs_wkup + - otg_hs + - dcmi + - cryp + - hash_rng diff --git a/include/libopencm3/stm32/f2/nvic_f2.h b/include/libopencm3/stm32/f2/nvic_f2.h deleted file mode 100644 index 2bf29971..00000000 --- a/include/libopencm3/stm32/f2/nvic_f2.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LIBOPENCM3_NVIC_F2_H -#define LIBOPENCM3_NVIC_F2_H - -/* --- IRQ channel numbers-------------------------------------------------- */ - -/* Note: These F2 specific user interrupt definitions supplement the - * general NVIC definitions in ../nvic.h - */ - -/* User Interrupts */ -#define NVIC_NVIC_WWDG_IRQ 0 -#define NVIC_PVD_IRQ 1 -#define NVIC_TAMP_STAMP_IRQ 2 -#define NVIC_RTC_WKUP_IRQ 3 -#define NVIC_FLASH_IRQ 4 -#define NVIC_RCC_IRQ 5 -#define NVIC_EXTI0_IRQ 6 -#define NVIC_EXTI1_IRQ 7 -#define NVIC_EXTI2_IRQ 8 -#define NVIC_EXTI3_IRQ 9 -#define NVIC_EXTI4_IRQ 10 -#define NVIC_DMA1_STREAM0_IRQ 11 -#define NVIC_DMA1_STREAM1_IRQ 12 -#define NVIC_DMA1_STREAM2_IRQ 13 -#define NVIC_DMA1_STREAM3_IRQ 14 -#define NVIC_DMA1_STREAM4_IRQ 15 -#define NVIC_DMA1_STREAM5_IRQ 16 -#define NVIC_DMA1_STREAM6_IRQ 17 -#define NVIC_ADC_IRQ 18 -#define NVIC_CAN1_TX_IRQ 19 -#define NVIC_CAN1_RX0_IRQ 20 -#define NVIC_CAN1_RX1_IRQ 21 -#define NVIC_CAN1_SCE_IRQ 22 -#define NVIC_EXTI9_5_IRQ 23 -#define NVIC_TIM1_BRK_TIM9_IRQ 24 -#define NVIC_TIM1_UP_TIM10_IRQ 25 -#define NVIC_TIM1_TRG_COM_TIM11_IRQ 26 -#define NVIC_TIM1_CC_IRQ 27 -#define NVIC_TIM2_IRQ 28 -#define NVIC_TIM3_IRQ 29 -#define NVIC_TIM4_IRQ 30 -#define NVIC_I2C1_EV_IRQ 31 -#define NVIC_I2C1_ER_IRQ 32 -#define NVIC_I2C2_EV_IRQ 33 -#define NVIC_I2C2_ER_IRQ 34 -#define NVIC_SPI1_IRQ 35 -#define NVIC_SPI2_IRQ 36 -#define NVIC_USART1_IRQ 37 -#define NVIC_USART2_IRQ 38 -#define NVIC_USART3_IRQ 39 -#define NVIC_EXTI15_10_IRQ 40 -#define NVIC_RTC_ALARM_IRQ 41 -#define NVIC_USB_FS_WKUP_IRQ 42 -#define NVIC_TIM8_BRK_TIM12_IRQ 43 -#define NVIC_TIM8_UP_TIM13_IRQ 44 -#define NVIC_TIM8_TRG_COM_TIM14_IRQ 45 -#define NVIC_TIM8_CC_IRQ 46 -#define NVIC_DMA1_STREAM7_IRQ 47 -#define NVIC_FSMC_IRQ 48 -#define NVIC_SDIO_IRQ 49 -#define NVIC_TIM5_IRQ 50 -#define NVIC_SPI3_IRQ 51 -#define NVIC_UART4_IRQ 52 -#define NVIC_UART5_IRQ 53 -#define NVIC_TIM6_DAC_IRQ 54 -#define NVIC_TIM7_IRQ 55 -#define NVIC_DMA2_STREAM0_IRQ 56 -#define NVIC_DMA2_STREAM1_IRQ 57 -#define NVIC_DMA2_STREAM2_IRQ 58 -#define NVIC_DMA2_STREAM3_IRQ 59 -#define NVIC_DMA2_STREAM4_IRQ 60 -#define NVIC_ETH_IRQ 61 -#define NVIC_ETH_WKUP_IRQ 62 -#define NVIC_CAN2_TX_IRQ 63 -#define NVIC_CAN2_RX0_IRQ 64 -#define NVIC_CAN2_RX1_IRQ 65 -#define NVIC_CAN2_SCE_IRQ 66 -#define NVIC_OTG_FS_IRQ 67 -#define NVIC_DMA2_STREAM5_IRQ 68 -#define NVIC_DMA2_STREAM6_IRQ 69 -#define NVIC_DMA2_STREAM7_IRQ 70 -#define NVIC_USART6_IRQ 71 -#define NVIC_I2C3_EV_IRQ 72 -#define NVIC_I2C3_ER_IRQ 73 -#define NVIC_OTG_HS_EP1_OUT_IRQ 74 -#define NVIC_OTG_HS_EP1_IN_IRQ 75 -#define NVIC_OTG_HS_WKUP_IRQ 76 -#define NVIC_OTG_HS_IRQ 77 -#define NVIC_DCMI_IRQ 78 -#define NVIC_CRYP_IRQ 79 -#define NVIC_HASH_RNG_IRQ 80 - -#endif diff --git a/include/libopencm3/stm32/f2/scb.h b/include/libopencm3/stm32/f2/scb.h deleted file mode 100644 index 181aa7a0..00000000 --- a/include/libopencm3/stm32/f2/scb.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> - * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LIBOPENCM3_SCB_H -#define LIBOPENCM3_SCB_H - -#include <libopencm3/stm32/memorymap.h> -#include <libopencm3/cm3/common.h> - -/* --- SCB: Registers ------------------------------------------------------ */ - -/* CPUID: CPUID base register */ -#define SCB_CPUID MMIO32(SCB_BASE + 0x00) - -/* ICSR: Interrupt Control State Register */ -#define SCB_ICSR MMIO32(SCB_BASE + 0x04) - -/* VTOR: Vector Table Offset Register */ -#define SCB_VTOR MMIO32(SCB_BASE + 0x08) - -/* AIRCR: Application Interrupt and Reset Control Register */ -#define SCB_AIRCR MMIO32(SCB_BASE + 0x0C) - -/* SCR: System Control Register */ -#define SCB_SCR MMIO32(SCB_BASE + 0x10) - -/* CCR: Configuration Control Register */ -#define SCB_CCR MMIO32(SCB_BASE + 0x14) - -/* SHP: System Handler Priority Registers */ -/* Note: 12 8bit registers */ -#define SCB_SHPR(shpr_id) MMIO8(SCB_BASE + 0x18 + shpr_id) -#define SCB_SHPR1 MMIO8(SCB_BASE + 0x18 + 1) -#define SCB_SHPR2 MMIO8(SCB_BASE + 0x18 + 2) -#define SCB_SHPR3 MMIO8(SCB_BASE + 0x18 + 3) - -/* SHCSR: System Handler Control and State Register */ -#define SCB_SHCSR MMIO32(SCB_BASE + 0x24) - -/* CFSR: Configurable Fault Status Registers */ -#define SCB_CFSR MMIO32(SCB_BASE + 0x28) - -/* HFSR: Hard Fault Status Register */ -#define SCB_HFSR MMIO32(SCB_BASE + 0x2C) - -/* DFSR: Debug Fault Status Register */ -#define SCB_DFSR MMIO32(SCB_BASE + 0x30) - -/* MMFAR: Memory Manage Fault Address Register */ -#define SCB_MMFAR MMIO32(SCB_BASE + 0x34) - -/* BFAR: Bus Fault Address Register */ -#define SCB_BFAR MMIO32(SCB_BASE + 0x38) - -/* AFSR: Auxiliary Fault Status Register */ -#define SCB_AFSR MMIO32(SCB_BASE + 0x3C) - -/* --- SCB values ---------------------------------------------------------- */ - -/* --- SCB_CPUID values ---------------------------------------------------- */ - -/* Implementer[31:24]: Implementer code */ -#define SCP_CPUID_IMPLEMENTER_LSB 24 -/* Variant[23:20]: Variant number */ -#define SCP_CPUID_VARIANT_LSB 20 -/* Constant[19:16]: Reads as 0xF */ -#define SCP_CPUID_CONSTANT_LSB 16 -/* PartNo[15:4]: Part number of the processor */ -#define SCP_CPUID_PARTNO_LSB 4 -/* Revision[3:0]: Revision number */ -#define SCP_CPUID_REVISION_LSB 0 - -/* --- SCB_ICSR values ----------------------------------------------------- */ - -/* NMIPENDSET: NMI set-pending bit */ -#define SCB_ICSR_NMIPENDSET (1 << 31) -/* Bits [30:29]: reserved - must be kept cleared */ -/* PENDSVSET: PendSV set-pending bit */ -#define SCB_ICSR_PENDSVSET (1 << 28) -/* PENDSVCLR: PendSV clear-pending bit */ -#define SCB_ICSR_PENDSVCLR (1 << 27) -/* PENDSTSET: SysTick exception set-pending bit */ -#define SCB_ICSR_PENDSTSET (1 << 26) -/* PENDSTCLR: SysTick exception clear-pending bit */ -#define SCB_ICSR_PENDSTCLR (1 << 25) -/* Bit 24: reserved - must be kept cleared */ -/* Bit 23: reserved for debug - reads as 0 when not in debug mode */ -/* ISRPENDING: Interrupt pending flag, excluding NMI and Faults */ -#define SCB_ICSR_ISRPENDING (1 << 22) -/* VECTPENDING[21:12] Pending vector */ -#define SCB_ICSR_VECTPENDING_LSB 12 -/* RETOBASE: Return to base level */ -#define SCB_ICSR_RETOBASE (1 << 11) -/* Bits [10:9]: reserved - must be kept cleared */ -/* VECTACTIVE[8:0] Active vector */ -#define SCB_ICSR_VECTACTIVE_LSB 0 - -/* --- SCB_VTOR values ----------------------------------------------------- */ - -/* Bits [31:30]: reserved - must be kept cleared */ -/* TBLOFF[29:9]: Vector table base offset field */ -#define SCB_VTOR_TBLOFF_LSB 9 /* inconsistent datasheet - LSB could be 11 */ - -/* --- SCB_AIRCR values ---------------------------------------------------- */ - -/* VECTKEYSTAT[31:16]/ VECTKEY[31:16] Register key */ -#define SCB_AIRCR_VECTKEYSTAT_LSB 16 -#define SCB_AIRCR_VECTKEY 0x05FA0000 -/* ENDIANESS Data endianness bit */ -#define SCB_AIRCR_ENDIANESS (1 << 15) -/* Bits [14:11]: reserved - must be kept cleared */ -/* PRIGROUP[10:8]: Interrupt priority grouping field */ -#define SCB_AIRCR_PRIGROUP_GROUP16_NOSUB (0x3 << 8) -#define SCB_AIRCR_PRIGROUP_GROUP8_SUB2 (0x4 << 8) -#define SCB_AIRCR_PRIGROUP_GROUP4_SUB4 (0x5 << 8) -#define SCB_AIRCR_PRIGROUP_GROUP2_SUB8 (0x6 << 8) -#define SCB_AIRCR_PRIGROUP_NOGROUP_SUB16 (0x7 << 8) -#define SCB_AIRCR_PRIGROUP_MASK (0x7 << 8) -#define SCB_AIRCR_PRIGROUP_SHIFT 8 -/* Bits [7:3]: reserved - must be kept cleared */ -/* SYSRESETREQ System reset request */ -#define SCB_AIRCR_SYSRESETREQ (1 << 2) -/* VECTCLRACTIVE */ -#define SCB_AIRCR_VECTCLRACTIVE (1 << 1) -/* VECTRESET */ -#define SCB_AIRCR_VECTRESET (1 << 0) - -/* --- SCB_SCR values ------------------------------------------------------ */ - -/* Bits [31:5]: reserved - must be kept cleared */ -/* SEVEONPEND Send Event on Pending bit */ -#define SCB_SCR_SEVEONPEND (1 << 4) -/* Bit 3: reserved - must be kept cleared */ -/* SLEEPDEEP */ -#define SCB_SCR_SLEEPDEEP (1 << 2) -/* SLEEPONEXIT */ -#define SCB_SCR_SLEEPONEXIT (1 << 1) -/* Bit 0: reserved - must be kept cleared */ - -/* --- SCB_CCR values ------------------------------------------------------ */ - -/* Bits [31:10]: reserved - must be kept cleared */ -/* STKALIGN */ -#define SCB_CCR_STKALIGN (1 << 9) -/* BFHFNMIGN */ -#define SCB_CCR_BFHFNMIGN (1 << 8) -/* Bits [7:5]: reserved - must be kept cleared */ -/* DIV_0_TRP */ -#define SCB_CCR_DIV_0_TRP (1 << 4) -/* UNALIGN_TRP */ -#define SCB_CCR_UNALIGN_TRP (1 << 3) -/* Bit 2: reserved - must be kept cleared */ -/* USERSETMPEND */ -#define SCB_CCR_USERSETMPEND (1 << 1) -/* NONBASETHRDENA */ -#define SCB_CCR_NONBASETHRDENA (1 << 0) - -/* --- SCB_SHPR1 values ---------------------------------------------------- */ - -/* Bits [31:24]: reserved - must be kept cleared */ -/* PRI_6[23:16]: Priority of system handler 6, usage fault */ -#define SCB_SHPR1_PRI_6_LSB 16 -/* PRI_5[15:8]: Priority of system handler 5, bus fault */ -#define SCB_SHPR1_PRI_5_LSB 8 -/* PRI_4[7:0]: Priority of system handler 4, memory management fault */ -#define SCB_SHPR1_PRI_4_LSB 0 - -/* --- SCB_SHPR2 values ---------------------------------------------------- */ - -/* PRI_11[31:24]: Priority of system handler 11, SVCall */ -#define SCB_SHPR2_PRI_11_LSB 24 -/* Bits [23:0]: reserved - must be kept cleared */ - -/* --- SCB_SHPR3 values ---------------------------------------------------- */ - -/* PRI_15[31:24]: Priority of system handler 15, SysTick exception */ -#define SCB_SHPR3_PRI_15_LSB 24 -/* PRI_14[23:16]: Priority of system handler 14, PendSV */ -#define SCB_SHPR3_PRI_14_LSB 16 -/* Bits [15:0]: reserved - must be kept cleared */ - -/* --- SCB_SHCSR values ---------------------------------------------------- */ - -/* Bits [31:19]: reserved - must be kept cleared */ -/* USGFAULTENA: Usage fault enable */ -#define SCB_SHCSR_USGFAULTENA (1 << 18) -/* BUSFAULTENA: Bus fault enable */ -#define SCB_SHCSR_BUSFAULTENA (1 << 17) -/* MEMFAULTENA: Memory management fault enable */ -#define SCB_SHCSR_MEMFAULTENA (1 << 16) -/* SVCALLPENDED: SVC call pending */ -#define SCB_SHCSR_SVCALLPENDED (1 << 15) -/* BUSFAULTPENDED: Bus fault exception pending */ -#define SCB_SHCSR_BUSFAULTPENDED (1 << 14) -/* MEMFAULTPENDED: Memory management fault exception pending */ -#define SCB_SHCSR_MEMFAULTPENDED (1 << 13) -/* USGFAULTPENDED: Usage fault exception pending */ -#define SCB_SHCSR_USGFAULTPENDED (1 << 12) -/* SYSTICKACT: SysTick exception active */ -#define SCB_SHCSR_SYSTICKACT (1 << 11) -/* PENDSVACT: PendSV exception active */ -#define SCB_SHCSR_PENDSVACT (1 << 10) -/* Bit 9: reserved - must be kept cleared */ -/* MONITORACT: Debug monitor active */ -#define SCB_SHCSR_MONITORACT (1 << 8) -/* SVCALLACT: SVC call active */ -#define SCB_SHCSR_SVCALLACT (1 << 7) -/* Bits [6:4]: reserved - must be kept cleared */ -/* USGFAULTACT: Usage fault exception active */ -#define SCB_SHCSR_USGFAULTACT (1 << 3) -/* Bit 2: reserved - must be kept cleared */ -/* BUSFAULTACT: Bus fault exception active */ -#define SCB_SHCSR_BUSFAULTACT (1 << 1) -/* MEMFAULTACT: Memory management fault exception active */ -#define SCB_SHCSR_MEMFAULTACT (1 << 0) - -/* --- SCB_CFSR values ----------------------------------------------------- */ - -/* Bits [31:26]: reserved - must be kept cleared */ -/* DIVBYZERO: Divide by zero usage fault */ -#define SCB_CFSR_DIVBYZERO (1 << 25) -/* UNALIGNED: Unaligned access usage fault */ -#define SCB_CFSR_UNALIGNED (1 << 24) -/* Bits [23:20]: reserved - must be kept cleared */ -/* NOCP: No coprocessor usage fault */ -#define SCB_CFSR_NOCP (1 << 19) -/* INVPC: Invalid PC load usage fault */ -#define SCB_CFSR_INVPC (1 << 18) -/* INVSTATE: Invalid state usage fault */ -#define SCB_CFSR_INVSTATE (1 << 17) -/* UNDEFINSTR: Undefined instruction usage fault */ -#define SCB_CFSR_UNDEFINSTR (1 << 16) -/* BFARVALID: Bus Fault Address Register (BFAR) valid flag */ -#define SCB_CFSR_BFARVALID (1 << 15) -/* Bits [14:13]: reserved - must be kept cleared */ -/* STKERR: Bus fault on stacking for exception entry */ -#define SCB_CFSR_STKERR (1 << 12) -/* UNSTKERR: Bus fault on unstacking for a return from exception */ -#define SCB_CFSR_UNSTKERR (1 << 11) -/* IMPRECISERR: Imprecise data bus error */ -#define SCB_CFSR_IMPRECISERR (1 << 10) -/* PRECISERR: Precise data bus error */ -#define SCB_CFSR_PRECISERR (1 << 9) -/* IBUSERR: Instruction bus error */ -#define SCB_CFSR_IBUSERR (1 << 8) -/* MMARVALID: Memory Management Fault Address Register (MMAR) valid flag */ -#define SCB_CFSR_MMARVALID (1 << 7) -/* Bits [6:5]: reserved - must be kept cleared */ -/* MSTKERR: Memory manager fault on stacking for exception entry */ -#define SCB_CFSR_MSTKERR (1 << 4) -/* MUNSTKERR: Memory manager fault on unstacking for a return from exception */ -#define SCB_CFSR_MUNSTKERR (1 << 3) -/* Bit 2: reserved - must be kept cleared */ -/* DACCVIOL: Data access violation flag */ -#define SCB_CFSR_DACCVIOL (1 << 1) -/* IACCVIOL: Instruction access violation flag */ -#define SCB_CFSR_IACCVIOL (1 << 0) - -/* --- SCB_HFSR values ----------------------------------------------------- */ - -/* DEBUG_VT: reserved for debug use */ -#define SCB_HFSR_DEBUG_VT (1 << 31) -/* FORCED: Forced hard fault */ -#define SCB_HFSR_FORCED (1 << 30) -/* Bits [29:2]: reserved - must be kept cleared */ -/* VECTTBL: Vector table hard fault */ -#define SCB_HFSR_VECTTBL (1 << 1) -/* Bit 0: reserved - must be kept cleared */ - -/* --- SCB_MMFAR values ---------------------------------------------------- */ - -/* MMFAR [31:0]: Memory management fault address */ - -/* --- SCB_BFAR values ----------------------------------------------------- */ - -/* BFAR [31:0]: Bus fault address */ - -/* --- SCB functions ------------------------------------------------------- */ - -BEGIN_DECLS - -void scb_reset_core(void); -void scb_reset_system(void); -void scb_set_priority_grouping(u32 prigroup); - -/* TODO: */ - -END_DECLS - -#endif diff --git a/include/libopencm3/stm32/f4/adc.h b/include/libopencm3/stm32/f4/adc.h new file mode 100644 index 00000000..272c4c2a --- /dev/null +++ b/include/libopencm3/stm32/f4/adc.h @@ -0,0 +1,873 @@ +/** @defgroup STM32F4xx_adc_defines ADC Defines + +@brief <b>Defined Constants and Types for the STM32F4xx Analog to Digital Converters</b> + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Matthew Lai <m@matthewlai.ca> +@author @htmlonly © @endhtmlonly 2009 Edward Cheeseman <evbuilder@users.sourceforge.net> + +@date 31 August 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Matthew Lai <m@matthewlai.ca> + * Copyright (C) 2009 Edward Cheeseman <evbuilder@users.sourceforge.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include <libopencm3/stm32/f4/memorymap.h> +#include <libopencm3/cm3/common.h> + +/* --- Convenience macros -------------------------------------------------- */ + +/* ADC port base addresses (for convenience) */ +/****************************************************************************/ +/** @defgroup adc_reg_base ADC register base addresses +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC1 ADC1_BASE +#define ADC2 ADC2_BASE +#define ADC3 ADC3_BASE +/**@}*/ + +/* --- ADC registers ------------------------------------------------------- */ + +/* ADC status register (ADC_SR) */ +#define ADC_SR(block) MMIO32(block + 0x00) +#define ADC1_SR ADC_SR(ADC1) +#define ADC2_SR ADC_SR(ADC2) +#define ADC3_SR ADC_SR(ADC3) + +/* ADC control register 1 (ADC_CR1) */ +#define ADC_CR1(block) MMIO32(block + 0x04) +#define ADC1_CR1 ADC_CR1(ADC1) +#define ADC2_CR1 ADC_CR1(ADC2) +#define ADC3_CR1 ADC_CR1(ADC3) + +/* ADC control register 2 (ADC_CR2) */ +#define ADC_CR2(block) MMIO32(block + 0x08) +#define ADC1_CR2 ADC_CR2(ADC1) +#define ADC2_CR2 ADC_CR2(ADC2) +#define ADC3_CR2 ADC_CR2(ADC3) + +/* ADC sample time register 1 (ADC_SMPR1) */ +#define ADC_SMPR1(block) MMIO32(block + 0x0c) +#define ADC1_SMPR1 ADC_SMPR1(ADC1) +#define ADC2_SMPR1 ADC_SMPR1(ADC2) +#define ADC3_SMPR1 ADC_SMPR1(ADC3) + +/* ADC sample time register 2 (ADC_SMPR2) */ +#define ADC_SMPR2(block) MMIO32(block + 0x10) +#define ADC1_SMPR2 ADC_SMPR2(ADC1) +#define ADC2_SMPR2 ADC_SMPR2(ADC2) +#define ADC3_SMPR2 ADC_SMPR2(ADC3) + +/* ADC injected channel data offset register x (ADC_JOFRx) (x=1..4) */ +#define ADC_JOFR1(block) MMIO32(block + 0x14) +#define ADC_JOFR2(block) MMIO32(block + 0x18) +#define ADC_JOFR3(block) MMIO32(block + 0x1c) +#define ADC_JOFR4(block) MMIO32(block + 0x20) +#define ADC1_JOFR1 ADC_JOFR1(ADC1) +#define ADC2_JOFR1 ADC_JOFR1(ADC2) +#define ADC3_JOFR1 ADC_JOFR1(ADC3) +#define ADC1_JOFR2 ADC_JOFR2(ADC1) +#define ADC2_JOFR2 ADC_JOFR2(ADC2) +#define ADC3_JOFR2 ADC_JOFR2(ADC3) +#define ADC1_JOFR3 ADC_JOFR3(ADC1) +#define ADC2_JOFR3 ADC_JOFR3(ADC2) +#define ADC3_JOFR3 ADC_JOFR3(ADC3) +#define ADC1_JOFR4 ADC_JOFR4(ADC1) +#define ADC2_JOFR4 ADC_JOFR4(ADC2) +#define ADC3_JOFR4 ADC_JOFR4(ADC3) + +/* ADC watchdog high threshold register (ADC_HTR) */ +#define ADC_HTR(block) MMIO32(block + 0x24) +#define ADC1_HTR ADC_HTR(ADC1) +#define ADC2_HTR ADC_HTR(ADC2) +#define ADC3_HTR ADC_HTR(ADC3) + +/* ADC watchdog low threshold register (ADC_LTR) */ +#define ADC_LTR(block) MMIO32(block + 0x28) +#define ADC1_LTR ADC_LTR(ADC1_BASE) +#define ADC2_LTR ADC_LTR(ADC2_BASE) +#define ADC3_LTR ADC_LTR(ADC3_BASE) + +/* ADC regular sequence register 1 (ADC_SQR1) */ +#define ADC_SQR1(block) MMIO32(block + 0x2c) +#define ADC1_SQR1 ADC_SQR1(ADC1) +#define ADC2_SQR1 ADC_SQR1(ADC2) +#define ADC3_SQR1 ADC_SQR1(ADC3) + +/* ADC regular sequence register 2 (ADC_SQR2) */ +#define ADC_SQR2(block) MMIO32(block + 0x30) +#define ADC1_SQR2 ADC_SQR2(ADC1) +#define ADC2_SQR2 ADC_SQR2(ADC2) +#define ADC3_SQR2 ADC_SQR2(ADC3) + +/* ADC regular sequence register 3 (ADC_SQR3) */ +#define ADC_SQR3(block) MMIO32(block + 0x34) +#define ADC1_SQR3 ADC_SQR3(ADC1) +#define ADC2_SQR3 ADC_SQR3(ADC2) +#define ADC3_SQR3 ADC_SQR3(ADC3) + +/* ADC injected sequence register (ADC_JSQR) */ +#define ADC_JSQR(block) MMIO32(block + 0x38) +#define ADC1_JSQR ADC_JSQR(ADC1_BASE) +#define ADC2_JSQR ADC_JSQR(ADC2_BASE) +#define ADC3_JSQR ADC_JSQR(ADC3_BASE) + +/* ADC injected data register x (ADC_JDRx) (x=1..4) */ +#define ADC_JDR1(block) MMIO32(block + 0x3c) +#define ADC_JDR2(block) MMIO32(block + 0x40) +#define ADC_JDR3(block) MMIO32(block + 0x44) +#define ADC_JDR4(block) MMIO32(block + 0x48) +#define ADC1_JDR1 ADC_JDR1(ADC1) +#define ADC2_JDR1 ADC_JDR1(ADC2) +#define ADC3_JDR1 ADC_JDR1(ADC3) +#define ADC1_JDR2 ADC_JDR2(ADC1) +#define ADC2_JDR2 ADC_JDR2(ADC2) +#define ADC3_JDR2 ADC_JDR2(ADC3) +#define ADC1_JDR3 ADC_JDR3(ADC1) +#define ADC2_JDR3 ADC_JDR3(ADC2) +#define ADC3_JDR3 ADC_JDR3(ADC3) +#define ADC1_JDR4 ADC_JDR4(ADC1) +#define ADC2_JDR4 ADC_JDR4(ADC2) +#define ADC3_JDR4 ADC_JDR4(ADC3) + +/* ADC regular data register (ADC_DR) */ +#define ADC_DR(block) MMIO32(block + 0x4c) +#define ADC1_DR ADC_DR(ADC1) +#define ADC2_DR ADC_DR(ADC2) +#define ADC3_DR ADC_DR(ADC3) + +/* ADC common (shared) registers */ +#define ADC_COMMON_REGISTERS_BASE (ADC1_BASE+0x300) +#define ADC_CSR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x0) +#define ADC_CCR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x4) +#define ADC_CDR MMIO32(ADC_COMMON_REGISTERS_BASE + 0x8) + +/* --- ADC Channels ------------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup adc_channel ADC Channel Numbers +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CHANNEL0 0x00 +#define ADC_CHANNEL1 0x01 +#define ADC_CHANNEL2 0x02 +#define ADC_CHANNEL3 0x03 +#define ADC_CHANNEL4 0x04 +#define ADC_CHANNEL5 0x05 +#define ADC_CHANNEL6 0x06 +#define ADC_CHANNEL7 0x07 +#define ADC_CHANNEL8 0x08 +#define ADC_CHANNEL9 0x09 +#define ADC_CHANNEL10 0x0A +#define ADC_CHANNEL11 0x0B +#define ADC_CHANNEL12 0x0C +#define ADC_CHANNEL13 0x0D +#define ADC_CHANNEL14 0x0E +#define ADC_CHANNEL15 0x0F +#define ADC_CHANNEL16 0x10 +#define ADC_CHANNEL17 0x11 +#define ADC_CHANNEL18 0x12 +/**@}*/ +#define ADC_MASK 0x1F +#define ADC_SHIFT 0 + +/* --- ADC_SR values ------------------------------------------------------- */ + +#define ADC_SR_OVR (1 << 5) +#define ADC_SR_STRT (1 << 4) +#define ADC_SR_JSTRT (1 << 3) +#define ADC_SR_JEOC (1 << 2) +#define ADC_SR_EOC (1 << 1) +#define ADC_SR_AWD (1 << 0) + +/* --- ADC_CR1 values specific to STM32F2,4------------------------------------ */ + +/* OVRIE: Overrun interrupt enable */ +#define ADC_CR1_OVRIE (1 << 26) + +/* RES[1:0]: Resolution */ +/****************************************************************************/ +/** @defgroup adc_cr1_res ADC Resolution. +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CR1_RES_12BIT (0x0 << 24) +#define ADC_CR1_RES_10BIT (0x1 << 24) +#define ADC_CR1_RES_8BIT (0x2 << 24) +#define ADC_CR1_RES_6BIT (0x3 << 24) +/**@}*/ +#define ADC_CR1_RES_MASK (0x3 << 24) +#define ADC_CR1_RES_SHIFT 24 + +/* Note: Bits [21:16] are reserved, and must be kept at reset value. */ + +/* --- ADC_CR1 values (note some of these are defined elsewhere) ----------- */ + +/* AWDEN: Analog watchdog enable on regular channels */ +#define ADC_CR1_AWDEN (1 << 23) + +/* JAWDEN: Analog watchdog enable on injected channels */ +#define ADC_CR1_JAWDEN (1 << 22) + +/* DISCNUM[2:0]: Discontinuous mode channel count. */ +/****************************************************************************/ +/** @defgroup adc_cr1_discnum ADC Number of channels in discontinuous mode. +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CR1_DISCNUM_1CHANNELS (0x0 << 13) +#define ADC_CR1_DISCNUM_2CHANNELS (0x1 << 13) +#define ADC_CR1_DISCNUM_3CHANNELS (0x2 << 13) +#define ADC_CR1_DISCNUM_4CHANNELS (0x3 << 13) +#define ADC_CR1_DISCNUM_5CHANNELS (0x4 << 13) +#define ADC_CR1_DISCNUM_6CHANNELS (0x5 << 13) +#define ADC_CR1_DISCNUM_7CHANNELS (0x6 << 13) +#define ADC_CR1_DISCNUM_8CHANNELS (0x7 << 13) +/**@}*/ +#define ADC_CR1_DISCNUM_MASK (0x7 << 13) +#define ADC_CR1_DISCNUM_SHIFT 13 + +/* JDISCEN: */ /** Discontinuous mode on injected channels. */ +#define ADC_CR1_JDISCEN (1 << 12) + +/* DISCEN: */ /** Discontinuous mode on regular channels. */ +#define ADC_CR1_DISCEN (1 << 11) + +/* JAUTO: */ /** Automatic Injection Group conversion. */ +#define ADC_CR1_JAUTO (1 << 10) + +/* AWDSGL: */ /** Enable the watchdog on a single channel in scan mode. */ +#define ADC_CR1_AWDSGL (1 << 9) + +/* SCAN: */ /** Scan mode. */ +#define ADC_CR1_SCAN (1 << 8) + +/* JEOCIE: */ /** Interrupt enable for injected channels. */ +#define ADC_CR1_JEOCIE (1 << 7) + +/* AWDIE: */ /** Analog watchdog interrupt enable. */ +#define ADC_CR1_AWDIE (1 << 6) + +/* EOCIE: */ /** Interrupt enable EOC. */ +#define ADC_CR1_EOCIE (1 << 5) + +/* AWDCH[4:0]: Analog watchdog channel bits. (Up to 17 other values reserved) */ +/* Notes: + * ADC1: Analog channel 16 and 17 are internally connected to the temperature + * sensor and V_REFINT, respectively. + * ADC2: Analog channel 16 and 17 are internally connected to V_SS. + * ADC3: Analog channel 9, 14, 15, 16 and 17 are internally connected to V_SS. + */ +/****************************************************************************/ +/* ADC_CR1 AWDCH[4:0] ADC watchdog channel */ +/** @defgroup adc_watchdog_channel ADC watchdog channel +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CR1_AWDCH_CHANNEL0 (0x00 << 0) +#define ADC_CR1_AWDCH_CHANNEL1 (0x01 << 0) +#define ADC_CR1_AWDCH_CHANNEL2 (0x02 << 0) +#define ADC_CR1_AWDCH_CHANNEL3 (0x03 << 0) +#define ADC_CR1_AWDCH_CHANNEL4 (0x04 << 0) +#define ADC_CR1_AWDCH_CHANNEL5 (0x05 << 0) +#define ADC_CR1_AWDCH_CHANNEL6 (0x06 << 0) +#define ADC_CR1_AWDCH_CHANNEL7 (0x07 << 0) +#define ADC_CR1_AWDCH_CHANNEL8 (0x08 << 0) +#define ADC_CR1_AWDCH_CHANNEL9 (0x09 << 0) +#define ADC_CR1_AWDCH_CHANNEL10 (0x0A << 0) +#define ADC_CR1_AWDCH_CHANNEL11 (0x0B << 0) +#define ADC_CR1_AWDCH_CHANNEL12 (0x0C << 0) +#define ADC_CR1_AWDCH_CHANNEL13 (0x0D << 0) +#define ADC_CR1_AWDCH_CHANNEL14 (0x0E << 0) +#define ADC_CR1_AWDCH_CHANNEL15 (0x0F << 0) +#define ADC_CR1_AWDCH_CHANNEL16 (0x10 << 0) +#define ADC_CR1_AWDCH_CHANNEL17 (0x11 << 0) +/**@}*/ +#define ADC_CR1_AWDCH_MASK (0x1F << 0) +#define ADC_CR1_AWDCH_SHIFT 0 + +/* --- ADC_CR2 values ------------------------------------------------------ */ + +/* SWSTART: Start conversion of regular channels. */ +#define ADC_CR2_SWSTART (1 << 30) + +/* EXTEN[1:0]: External trigger enable for regular channels. */ +/****************************************************************************/ +/** @defgroup adc_trigger_polarity_regular ADC Trigger Polarity +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CR2_EXTEN_DISABLED (0x0 << 28) +#define ADC_CR2_EXTEN_RISING_EDGE (0x1 << 28) +#define ADC_CR2_EXTEN_FALLING_EDGE (0x2 << 28) +#define ADC_CR2_EXTEN_BOTH_EDGES (0x3 << 28) +/**@}*/ +#define ADC_CR2_EXTEN_MASK (0x3 << 28) +#define ADC_CR2_EXTEN_SHIFT 28 + +/* EXTSEL[3:0]: External event selection for regular group. */ +/****************************************************************************/ +/** @defgroup adc_trigger_regular ADC Trigger Identifier for Regular group +@ingroup STM32F4xx_adc_defines + +@{*/ +/** Timer 1 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM1_CC1 (0x0 << 24) +/** Timer 1 Compare Output 2 */ +#define ADC_CR2_EXTSEL_TIM1_CC2 (0x1 << 24) +/** Timer 1 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 24) +/** Timer 2 Compare Output 2 */ +#define ADC_CR2_EXTSEL_TIM2_CC2 (0x3 << 24) +/** Timer 2 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM2_CC3 (0x4 << 24) +/** Timer 2 Compare Output 4 */ +#define ADC_CR2_EXTSEL_TIM2_CC4 (0x5 << 24) +/** Timer 2 TRGO Event */ +#define ADC_CR2_EXTSEL_TIM2_TRGO (0x6 << 24) +/** Timer 3 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM3_CC1 (0x7 << 24) +/** Timer 3 TRGO Event */ +#define ADC_CR2_EXTSEL_TIM3_TRGO (0x8 << 24) +/** Timer 4 Compare Output 4 */ +#define ADC_CR2_EXTSEL_TIM4_CC4 (0x9 << 24) +/** Timer 5 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM5_CC1 (0xA << 24) +/** Timer 5 Compare Output 2 */ +#define ADC_CR2_EXTSEL_TIM5_CC2 (0xB << 24) +/** Timer 5 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM5_CC3 (0xC << 24) +/** Timer 8 Compare Output 1 */ +#define ADC_CR2_EXTSEL_TIM8_CC1 (0xD << 24) +/** Timer 8 TRGO Event */ +#define ADC_CR2_EXTSEL_TIM8_TRGO (0xE << 24) +/** EXTI Line 11 Event */ +#define ADC_CR2_EXTSEL_EXTI_LINE_11 (0xF << 24) +/**@}*/ +#define ADC_CR2_EXTSEL_MASK (0xF << 24) +#define ADC_CR2_EXTSEL_SHIFT 24 + +/* Bit 23 is reserved */ + +/* JSWSTART: Start conversion of injected channels. */ +#define ADC_CR2_JSWSTART (1 << 22) + +/* JEXTEN[1:0]: External trigger enable for injected channels. */ +/****************************************************************************/ +/** @defgroup adc_trigger_polarity_injected ADC Injected Trigger Polarity +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CR2_JEXTEN_DISABLED (0x0 << 20) +#define ADC_CR2_JEXTEN_RISING_EDGE (0x1 << 20) +#define ADC_CR2_JEXTEN_FALLING_EDGE (0x2 << 20) +#define ADC_CR2_JEXTEN_BOTH_EDGES (0x3 << 20) +/**@}*/ +#define ADC_CR2_JEXTEN_MASK (0x3 << 20) +#define ADC_CR2_JEXTEN_SHIFT 20 + +/* JEXTSEL[3:0]: External event selection for injected group. */ +/****************************************************************************/ +/** @defgroup adc_trigger_injected ADC Trigger Identifier for Injected group +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x0 << 16) +#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x1 << 16) +#define ADC_CR2_JEXTSEL_TIM2_CC1 (0x2 << 16) +#define ADC_CR2_JEXTSEL_TIM2_TRGO (0x3 << 16) +#define ADC_CR2_JEXTSEL_TIM3_CC2 (0x4 << 16) +#define ADC_CR2_JEXTSEL_TIM3_CC4 (0x5 << 16) +#define ADC_CR2_JEXTSEL_TIM4_CC1 (0x6 << 16) +#define ADC_CR2_JEXTSEL_TIM4_CC2 (0x7 << 16) +#define ADC_CR2_JEXTSEL_TIM4_CC3 (0x8 << 16) +#define ADC_CR2_JEXTSEL_TIM4_TRGO (0x9 << 16) +#define ADC_CR2_JEXTSEL_TIM5_CC4 (0xA << 16) +#define ADC_CR2_JEXTSEL_TIM5_TRGO (0xB << 16) +#define ADC_CR2_JEXTSEL_TIM8_CC2 (0xC << 16) +#define ADC_CR2_JEXTSEL_TIM8_CC3 (0xD << 16) +#define ADC_CR2_JEXTSEL_TIM8_CC4 (0xE << 16) +#define ADC_CR2_JEXTSEL_EXTI_LINE_15 (0xF << 16) +/**@}*/ +#define ADC_CR2_JEXTSEL_MASK (0xF << 16) +#define ADC_CR2_JEXTSEL_SHIFT 16 + +/* ALIGN: Data alignement. */ +#define ADC_CR2_ALIGN_RIGHT (0 << 11) +#define ADC_CR2_ALIGN_LEFT (1 << 11) +#define ADC_CR2_ALIGN (1 << 11) + +/* EOCS: End of conversion selection. */ +#define ADC_CR2_EOCS (1 << 10) + +/* DDS: DMA disable selection */ +#define ADC_CR2_DDS (1 << 9) + +/* DMA: Direct memory access mode. (ADC1 and ADC3 only!) */ +#define ADC_CR2_DMA (1 << 8) + +/* Note: Bits [7:2] are reserved and must be kept at reset value. */ + +/* CONT: Continous conversion. */ +#define ADC_CR2_CONT (1 << 1) + +/* ADON: A/D converter On/Off. */ +/* Note: If any other bit in this register apart from ADON is changed at the + * same time, then conversion is not triggered. This is to prevent triggering + * an erroneous conversion. + * Conclusion: Must be separately written. + */ +#define ADC_CR2_ADON (1 << 0) + +/* --- ADC_SMPR1 values ---------------------------------------------------- */ + +#define ADC_SMPR1_SMP17_LSB 21 +#define ADC_SMPR1_SMP16_LSB 18 +#define ADC_SMPR1_SMP15_LSB 15 +#define ADC_SMPR1_SMP14_LSB 12 +#define ADC_SMPR1_SMP13_LSB 9 +#define ADC_SMPR1_SMP12_LSB 6 +#define ADC_SMPR1_SMP11_LSB 3 +#define ADC_SMPR1_SMP10_LSB 0 +#define ADC_SMPR1_SMP17_MSK (0x7 << ADC_SMP17_LSB) +#define ADC_SMPR1_SMP16_MSK (0x7 << ADC_SMP16_LSB) +#define ADC_SMPR1_SMP15_MSK (0x7 << ADC_SMP15_LSB) +#define ADC_SMPR1_SMP14_MSK (0x7 << ADC_SMP14_LSB) +#define ADC_SMPR1_SMP13_MSK (0x7 << ADC_SMP13_LSB) +#define ADC_SMPR1_SMP12_MSK (0x7 << ADC_SMP12_LSB) +#define ADC_SMPR1_SMP11_MSK (0x7 << ADC_SMP11_LSB) +#define ADC_SMPR1_SMP10_MSK (0x7 << ADC_SMP10_LSB) +/****************************************************************************/ +/* ADC_SMPR1 ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_r1 ADC Sample Time Selection for ADC1 +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_SMPR1_SMP_1DOT5CYC 0x0 +#define ADC_SMPR1_SMP_7DOT5CYC 0x1 +#define ADC_SMPR1_SMP_13DOT5CYC 0x2 +#define ADC_SMPR1_SMP_28DOT5CYC 0x3 +#define ADC_SMPR1_SMP_41DOT5CYC 0x4 +#define ADC_SMPR1_SMP_55DOT5CYC 0x5 +#define ADC_SMPR1_SMP_71DOT5CYC 0x6 +#define ADC_SMPR1_SMP_239DOT5CYC 0x7 +/**@}*/ + +/* --- ADC_SMPR2 values ---------------------------------------------------- */ + +#define ADC_SMPR2_SMP9_LSB 27 +#define ADC_SMPR2_SMP8_LSB 24 +#define ADC_SMPR2_SMP7_LSB 21 +#define ADC_SMPR2_SMP6_LSB 18 +#define ADC_SMPR2_SMP5_LSB 15 +#define ADC_SMPR2_SMP4_LSB 12 +#define ADC_SMPR2_SMP3_LSB 9 +#define ADC_SMPR2_SMP2_LSB 6 +#define ADC_SMPR2_SMP1_LSB 3 +#define ADC_SMPR2_SMP0_LSB 0 +#define ADC_SMPR2_SMP9_MSK (0x7 << ADC_SMP9_LSB) +#define ADC_SMPR2_SMP8_MSK (0x7 << ADC_SMP8_LSB) +#define ADC_SMPR2_SMP7_MSK (0x7 << ADC_SMP7_LSB) +#define ADC_SMPR2_SMP6_MSK (0x7 << ADC_SMP6_LSB) +#define ADC_SMPR2_SMP5_MSK (0x7 << ADC_SMP5_LSB) +#define ADC_SMPR2_SMP4_MSK (0x7 << ADC_SMP4_LSB) +#define ADC_SMPR2_SMP3_MSK (0x7 << ADC_SMP3_LSB) +#define ADC_SMPR2_SMP2_MSK (0x7 << ADC_SMP2_LSB) +#define ADC_SMPR2_SMP1_MSK (0x7 << ADC_SMP1_LSB) +#define ADC_SMPR2_SMP0_MSK (0x7 << ADC_SMP0_LSB) +/****************************************************************************/ +/* ADC_SMPR2 ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_r2 ADC Sample Time Selection for ADC2 +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_SMPR2_SMP_1DOT5CYC 0x0 +#define ADC_SMPR2_SMP_7DOT5CYC 0x1 +#define ADC_SMPR2_SMP_13DOT5CYC 0x2 +#define ADC_SMPR2_SMP_28DOT5CYC 0x3 +#define ADC_SMPR2_SMP_41DOT5CYC 0x4 +#define ADC_SMPR2_SMP_55DOT5CYC 0x5 +#define ADC_SMPR2_SMP_71DOT5CYC 0x6 +#define ADC_SMPR2_SMP_239DOT5CYC 0x7 +/**@}*/ + +/* --- ADC_SMPRx generic values -------------------------------------------- */ +/****************************************************************************/ +/* ADC_SMPRG ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_rg ADC Sample Time Selection for All Channels +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_SMPR_SMP_1DOT5CYC 0x0 +#define ADC_SMPR_SMP_7DOT5CYC 0x1 +#define ADC_SMPR_SMP_13DOT5CYC 0x2 +#define ADC_SMPR_SMP_28DOT5CYC 0x3 +#define ADC_SMPR_SMP_41DOT5CYC 0x4 +#define ADC_SMPR_SMP_55DOT5CYC 0x5 +#define ADC_SMPR_SMP_71DOT5CYC 0x6 +#define ADC_SMPR_SMP_239DOT5CYC 0x7 +/**@}*/ + +/* --- ADC_JOFRx, ADC_HTR, ADC_LTR values ---------------------------------- */ + +#define ADC_JOFFSET_LSB 0 +#define ADC_JOFFSET_MSK (0x7ff << 0) +#define ADC_HT_LSB 0 +#define ADC_HT_MSK (0x7ff << 0) +#define ADC_LT_LSB 0 +#define ADC_LT_MSK (0x7ff << 0) + +/* --- ADC_SQR1 values ----------------------------------------------------- */ + +#define ADC_SQR1_L_LSB 20 +#define ADC_SQR1_SQ16_LSB 15 +#define ADC_SQR1_SQ15_LSB 10 +#define ADC_SQR1_SQ14_LSB 5 +#define ADC_SQR1_SQ13_LSB 0 +#define ADC_SQR1_L_MSK (0xf << ADC_SQR1_L_LSB) +#define ADC_SQR1_SQ16_MSK (0x1f << ADC_SQR1_SQ16_LSB) +#define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQR1_SQ15_LSB) +#define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQR1_SQ14_LSB) +#define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQR1_SQ13_LSB) + +/* --- ADC_SQR2 values ----------------------------------------------------- */ + +#define ADC_SQR2_SQ12_LSB 25 +#define ADC_SQR2_SQ11_LSB 20 +#define ADC_SQR2_SQ10_LSB 15 +#define ADC_SQR2_SQ9_LSB 10 +#define ADC_SQR2_SQ8_LSB 5 +#define ADC_SQR2_SQ7_LSB 0 +#define ADC_SQR2_SQ12_MSK (0x1f << ADC_SQR2_SQ12_LSB) +#define ADC_SQR2_SQ11_MSK (0x1f << ADC_SQR2_SQ11_LSB) +#define ADC_SQR2_SQ10_MSK (0x1f << ADC_SQR2_SQ10_LSB) +#define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQR2_SQ9_LSB) +#define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQR2_SQ8_LSB) +#define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQR2_SQ7_LSB) + +/* --- ADC_SQR3 values ----------------------------------------------------- */ + +#define ADC_SQR3_SQ6_LSB 25 +#define ADC_SQR3_SQ5_LSB 20 +#define ADC_SQR3_SQ4_LSB 15 +#define ADC_SQR3_SQ3_LSB 10 +#define ADC_SQR3_SQ2_LSB 5 +#define ADC_SQR3_SQ1_LSB 0 +#define ADC_SQR3_SQ6_MSK (0x1f << ADC_SQR3_SQ6_LSB) +#define ADC_SQR3_SQ5_MSK (0x1f << ADC_SQR3_SQ5_LSB) +#define ADC_SQR3_SQ4_MSK (0x1f << ADC_SQR3_SQ4_LSB) +#define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQR3_SQ3_LSB) +#define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQR3_SQ2_LSB) +#define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQR3_SQ1_LSB) + +/* --- ADC_JSQR values ----------------------------------------------------- */ + +#define ADC_JSQR_JL_LSB 20 +#define ADC_JSQR_JSQ4_LSB 15 +#define ADC_JSQR_JSQ3_LSB 10 +#define ADC_JSQR_JSQ2_LSB 5 +#define ADC_JSQR_JSQ1_LSB 0 + +/* JL[2:0]: Discontinous mode channel count injected channels. */ +/****************************************************************************/ +/** @defgroup adc_jsqr_jl ADC Number of channels in discontinuous mode fro injected channels. +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_JSQR_JL_1CHANNELS (0x0 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_2CHANNELS (0x1 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_3CHANNELS (0x2 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_4CHANNELS (0x3 << ADC_JSQR_JL_LSB) +/**@}*/ +#define ADC_JSQR_JL_SHIFT 13 +#define ADC_JSQR_JL_MSK (0x2 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JSQ4_MSK (0x1f << ADC_JSQR_JSQ4_LSB) +#define ADC_JSQR_JSQ3_MSK (0x1f << ADC_JSQR_JSQ3_LSB) +#define ADC_JSQR_JSQ2_MSK (0x1f << ADC_JSQR_JSQ2_LSB) +#define ADC_JSQR_JSQ1_MSK (0x1f << ADC_JSQR_JSQ1_LSB) + +/* --- ADC_JDRx, ADC_DR values --------------------------------------------- */ + +#define ADC_JDATA_LSB 0 +#define ADC_DATA_LSB 0 +#define ADC_JDATA_MSK (0xffff << ADC_JDATA_LSB) +#define ADC_DATA_MSK (0xffff << ADC_DA) + +/* --- Common Registers ---------------------------------------------------- */ + +/* --- ADC_CSR values (read only images) ------------------------------------ */ + +/* OVR3: Overrun ADC3. */ +#define ADC_CSR_OVR3 (1 << 21) + +/* STRT3: Regular channel start ADC3. */ +#define ADC_CSR_STRT3 (1 << 20) + +/* JSTRT3: Injected channel start ADC3. */ +#define ADC_CSR_JSTRT3 (1 << 19) + +/* JEOC3: Injected channel end of conversion ADC3. */ +#define ADC_CSR_JEOC3 (1 << 18) + +/* EOC3: Regular channel end of conversion ADC3. */ +#define ADC_CSR_EOC3 (1 << 17) + +/* EOC3: Regular channel end of conversion ADC3. */ +#define ADC_CSR_AWD3 (1 << 16) + +/* Bits 15:14 Reserved, must be kept at reset value */ + +/* OVR2: Overrun ADC2. */ +#define ADC_CSR_OVR2 (1 << 13) + +/* STRT2: Regular channel start ADC2. */ +#define ADC_CSR_STRT2 (1 << 12) + +/* JSTRT2: Injected channel start ADC2. */ +#define ADC_CSR_JSTRT2 (1 << 11) + +/* JEOC2: Injected channel end of conversion ADC2. */ +#define ADC_CSR_JEOC2 (1 << 10) + +/* EOC2: Regular channel end of conversion ADC2. */ +#define ADC_CSR_EOC2 (1 << 9) + +/* EOC2: Regular channel end of conversion ADC2. */ +#define ADC_CSR_AWD2 (1 << 8) + +/* Bits 7:6 Reserved, must be kept at reset value */ + +/* OVR1: Overrun ADC1. */ +#define ADC_CSR_OVR1 (1 << 5) + +/* STRT1: Regular channel start ADC1. */ +#define ADC_CSR_STRT1 (1 << 4) + +/* JSTRT1: Injected channel start ADC1. */ +#define ADC_CSR_JSTRT1 (1 << 3) + +/* JEOC1: Injected channel end of conversion ADC1. */ +#define ADC_CSR_JEOC1 (1 << 2) + +/* EOC1: Regular channel end of conversion ADC1. */ +#define ADC_CSR_EOC1 (1 << 1) + +/* EOC1: Regular channel end of conversion ADC1. */ +#define ADC_CSR_AWD1 (1 << 0) + +/* --- ADC_CCR values ------------------------------------------------------ */ + +/* TSVREFE: Temperature sensor and Vrefint enable. */ +#define ADC_CCR_TSVREFE (1 << 23) + +/* VBATE: VBat enable. */ +#define ADC_CCR_VBATE (1 << 22) + +/* Bit 18:21 reserved, must be kept at reset value. */ + +/* ADCPRE: ADC prescaler. */ +/****************************************************************************/ +/** @defgroup adc_ccr_adcpre ADC Prescale +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CCR_ADCPRE_BY2 (0x0 << 16) +#define ADC_CCR_ADCPRE_BY4 (0x1 << 16) +#define ADC_CCR_ADCPRE_BY6 (0x2 << 16) +#define ADC_CCR_ADCPRE_BY8 (0x3 << 16) +/**@}*/ +#define ADC_CCR_ADCPRE_MASK (0x3 << 16) +#define ADC_CCR_ADCPRE_SHIFT 16 + +/* DMA: Direct memory access mode for multi ADC mode. */ +/****************************************************************************/ +/** @defgroup adc_dma_mode ADC DMA mode for multi ADC mode +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CCR_DMA_DISABLE (0x0 << 14) +#define ADC_CCR_DMA_MODE_1 (0x1 << 14) +#define ADC_CCR_DMA_MODE_2 (0x2 << 14) +#define ADC_CCR_DMA_MODE_3 (0x3 << 14) +/**@}*/ +#define ADC_CCR_DMA_MASK (0x3 << 14) +#define ADC_CCR_DMA_SHIFT 14 + +/* DDS: DMA disable selection (for multi-ADC mode). */ +#define ADC_CCR_DDS (1 << 13) + +/* Bit 12 reserved, must be kept at reset value */ + +/* DELAY: Delay between 2 sampling phases. */ +/****************************************************************************/ +/** @defgroup adc_delay ADC Delay between 2 sampling phases +@ingroup STM32F4xx_adc_defines + +@{*/ +#define ADC_CCR_DELAY_5ADCCLK (0x0 << 8) +#define ADC_CCR_DELAY_6ADCCLK (0x1 << 8) +#define ADC_CCR_DELAY_7ADCCLK (0x2 << 8) +#define ADC_CCR_DELAY_8ADCCLK (0x3 << 8) +#define ADC_CCR_DELAY_9ADCCLK (0x4 << 8) +#define ADC_CCR_DELAY_10ADCCLK (0x5 << 8) +#define ADC_CCR_DELAY_11ADCCLK (0x6 << 8) +#define ADC_CCR_DELAY_12ADCCLK (0x7 << 8) +#define ADC_CCR_DELAY_13ADCCLK (0x8 << 8) +#define ADC_CCR_DELAY_14ADCCLK (0x9 << 8) +#define ADC_CCR_DELAY_15ADCCLK (0xa << 8) +#define ADC_CCR_DELAY_16ADCCLK (0xb << 8) +#define ADC_CCR_DELAY_17ADCCLK (0xc << 8) +#define ADC_CCR_DELAY_18ADCCLK (0xd << 8) +#define ADC_CCR_DELAY_19ADCCLK (0xe << 8) +#define ADC_CCR_DELAY_20ADCCLK (0xf << 8) +/**@}*/ +#define ADC_CCR_DELAY_MASK (0xf << 8) +#define ADC_CCR_DELAY_SHIFT 8 + +/* Bit 7:5 reserved, must be kept at reset value */ + +/* MULTI: Multi ADC mode selection. */ +/****************************************************************************/ +/** @defgroup adc_multi_mode ADC Multi mode selection +@ingroup STM32F4xx_adc_defines + +@{*/ + +/** All ADCs independent */ +#define ADC_CCR_MULTI_INDEPENDENT (0x00 << 0) + +/* dual modes (ADC1 + ADC2) */ +/** Dual modes (ADC1 + ADC2) Combined regular simultaneous + injected simultaneous mode */ +#define ADC_CCR_MULTI_DUAL_REG_SIMUL_AND_INJECTED_SIMUL (0x01 << 0) +/** Dual modes (ADC1 + ADC2) Combined regular simultaneous + alternate trigger mode. */ +#define ADC_CCR_MULTI_DUAL_REG_SIMUL_AND_ALTERNATE_TRIG (0x02 << 0) +/** Dual modes (ADC1 + ADC2) Injected simultaneous mode only. */ +#define ADC_CCR_MULTI_DUAL_INJECTED_SIMUL (0x05 << 0) +/** Dual modes (ADC1 + ADC2) Regular simultaneous mode only. */ +#define ADC_CCR_MULTI_DUAL_REGULAR_SIMUL (0x06 << 0) +/** Dual modes (ADC1 + ADC2) Interleaved mode only. */ +#define ADC_CCR_MULTI_DUAL_INTERLEAVED (0x07 << 0) +/** Dual modes (ADC1 + ADC2) Alternate trigger mode only. */ +#define ADC_CCR_MULTI_DUAL_ALTERNATE_TRIG (0x09 << 0) + +/* Triple modes (ADC1 + ADC2 + ADC3) */ +/** Triple modes (ADC1 + ADC2 + ADC3) Combined regular simultaneous + injected simultaneous mode */ +#define ADC_CCR_MULTI_TRIPLE_REG_SIMUL_AND_INJECTED_SIMUL (0x11 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Combined regular simultaneous + alternate trigger mode. */ +#define ADC_CCR_MULTI_TRIPLE_REG_SIMUL_AND_ALTERNATE_TRIG (0x12 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Injected simultaneous mode only. */ +#define ADC_CCR_MULTI_TRIPLE_INJECTED_SIMUL (0x15 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Regular simultaneous mode only. */ +#define ADC_CCR_MULTI_TRIPLE_REGULAR_SIMUL (0x16 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Interleaved mode only. */ +#define ADC_CCR_MULTI_TRIPLE_INTERLEAVED (0x17 << 0) +/** Triple modes (ADC1 + ADC2 + ADC3) Alternate trigger mode only. */ +#define ADC_CCR_MULTI_TRIPLE_ALTERNATE_TRIG (0x19 << 0) +/**@}*/ + +#define ADC_CCR_MULTI_MASK (0x1f << 0) +#define ADC_CCR_MULTI_SHIFT 0 + +/* --- ADC_CDR values ------------------------------------------------------ */ + +#define ADC_CDR_DATA2_MASK (0xffff << 16) +#define ADC_CDR_DATA2_SHIFT 16 + +#define ADC_CDR_DATA1_MASK (0xffff << 0) +#define ADC_CDR_DATA1_SHIFT 0 + +BEGIN_DECLS + +void adc_power_on(u32 adc); +void adc_off(u32 adc); +void adc_enable_analog_watchdog_regular(u32 adc); +void adc_disable_analog_watchdog_regular(u32 adc); +void adc_enable_analog_watchdog_injected(u32 adc); +void adc_disable_analog_watchdog_injected(u32 adc); +void adc_enable_discontinuous_mode_regular(u32 adc, u8 length); +void adc_disable_discontinuous_mode_regular(u32 adc); +void adc_enable_discontinuous_mode_injected(u32 adc); +void adc_disable_discontinuous_mode_injected(u32 adc); +void adc_enable_automatic_injected_group_conversion(u32 adc); +void adc_disable_automatic_injected_group_conversion(u32 adc); +void adc_enable_analog_watchdog_on_all_channels(u32 adc); +void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel); +void adc_enable_scan_mode(u32 adc); +void adc_disable_scan_mode(u32 adc); +void adc_enable_eoc_interrupt_injected(u32 adc); +void adc_disable_eoc_interrupt_injected(u32 adc); +void adc_enable_awd_interrupt(u32 adc); +void adc_disable_awd_interrupt(u32 adc); +void adc_enable_eoc_interrupt(u32 adc); +void adc_disable_eoc_interrupt(u32 adc); +void adc_start_conversion_regular(u32 adc); +void adc_start_conversion_injected(u32 adc); +void adc_disable_external_trigger_regular(u32 adc); +void adc_disable_external_trigger_injected(u32 adc); +void adc_set_left_aligned(u32 adc); +void adc_set_right_aligned(u32 adc); +void adc_enable_dma(u32 adc); +void adc_disable_dma(u32 adc); +void adc_set_continuous_conversion_mode(u32 adc); +void adc_set_single_conversion_mode(u32 adc); +void adc_set_sample_time(u32 adc, u8 channel, u8 time); +void adc_set_sample_time_on_all_channels(u32 adc, u8 time); +void adc_set_watchdog_high_threshold(u32 adc, u16 threshold); +void adc_set_watchdog_low_threshold(u32 adc, u16 threshold); +void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]); +void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]); +bool adc_eoc(u32 adc); +bool adc_eoc_injected(u32 adc); +u32 adc_read_regular(u32 adc); +u32 adc_read_injected(u32 adc, u8 reg); +void adc_set_injected_offset(u32 adc, u8 reg, u32 offset); + +void adc_set_clk_prescale(u32 prescaler); +void adc_set_multi_mode(u32 mode); +void adc_enable_external_trigger_regular(u32 adc, u32 trigger, u32 polarity); +void adc_enable_external_trigger_injected(u32 adc, u32 trigger, u32 polarity); +void adc_set_resolution(u32 adc, u16 resolution); +void adc_enable_overrun_interrupt(u32 adc); +void adc_disable_overrun_interrupt(u32 adc); +bool adc_get_overrun_flag(u32 adc); +void adc_clear_overrun_flag(u32 adc); +bool adc_awd(u32 adc); +void adc_eoc_after_each(u32 adc); +void adc_eoc_after_group(u32 adc); +void adc_set_dma_continue(u32 adc); +void adc_set_dma_terminate(u32 adc); +void adc_enable_temperature_sensor(void); +void adc_disable_temperature_sensor(void); + +END_DECLS + +/**@}*/ + +#endif diff --git a/include/libopencm3/stm32/f4/dma.h b/include/libopencm3/stm32/f4/dma.h new file mode 100644 index 00000000..c765a799 --- /dev/null +++ b/include/libopencm3/stm32/f4/dma.h @@ -0,0 +1,693 @@ +/** @defgroup STM32F4xx_dma_defines DMA Defines + +@ingroup STM32F4xx_defines + +@brief Defined Constants and Types for the STM32F4xx DMA Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net> + +@date 18 October 2012 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies <ksarkies@internode.on.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/**@{*/ + +#ifndef LIBOPENCM3_DMA_H +#define LIBOPENCM3_DMA_H + +#include <libopencm3/stm32/memorymap.h> +#include <libopencm3/cm3/common.h> + +/* --- Convenience macros -------------------------------------------------- */ + +/* DMA register base adresses (for convenience) */ +#define DMA1 DMA1_BASE +#define DMA2 DMA2_BASE + +/* --- DMA registers ------------------------------------------------------- */ + +/* DMA low interrupt status register (DMAx_ISR) */ +#define DMA_LISR(dma_base) MMIO32(dma_base + 0x00) +#define DMA1_LISR DMA_ISR(DMA1) +#define DMA2_LISR DMA_ISR(DMA2) + +/* DMA high interrupt status register (DMAx_ISR) */ +#define DMA_HISR(dma_base) MMIO32(dma_base + 0x04) +#define DMA1_HISR DMA_ISR(DMA1) +#define DMA2_HISR DMA_ISR(DMA2) + +/* DMA low interrupt flag clear register (DMAx_IFCR) */ +#define DMA_LIFCR(dma_base) MMIO32(dma_base + 0x08) +#define DMA1_LIFCR DMA_IFCR(DMA1) +#define DMA2_LIFCR DMA_IFCR(DMA2) + +/* DMA high interrupt flag clear register (DMAx_IFCR) */ +#define DMA_HIFCR(dma_base) MMIO32(dma_base + 0x0C) +#define DMA1_HIFCR DMA_IFCR(DMA1) +#define DMA2_HIFCR DMA_IFCR(DMA2) + +/* DMA stream configuration register (DMAx_SyCR) */ +#define DMA_SCR(dma_base, stream) MMIO32(dma_base + 0x10 + \ + (0x18 * (stream))) + +#define DMA1_SCR(stream) DMA_SCR(DMA1, stream) +#define DMA1_S0CR DMA1_SCR(DMA_STREAM0) +#define DMA1_S1CR DMA1_SCR(DMA_STREAM1) +#define DMA1_S2CR DMA1_SCR(DMA_STREAM2) +#define DMA1_S3CR DMA1_SCR(DMA_STREAM3) +#define DMA1_S4CR DMA1_SCR(DMA_STREAM4) +#define DMA1_S5CR DMA1_SCR(DMA_STREAM5) +#define DMA1_S6CR DMA1_SCR(DMA_STREAM6) +#define DMA1_S7CR DMA1_SCR(DMA_STREAM7) + +#define DMA2_SCR(stream) DMA_SCR(DMA2, stream) +#define DMA2_S0CR DMA2_SCR(DMA_STREAM0) +#define DMA2_S1CR DMA2_SCR(DMA_STREAM1) +#define DMA2_S2CR DMA2_SCR(DMA_STREAM2) +#define DMA2_S3CR DMA2_SCR(DMA_STREAM3) +#define DMA2_S4CR DMA2_SCR(DMA_STREAM4) +#define DMA2_S5CR DMA2_SCR(DMA_STREAM5) +#define DMA2_S6CR DMA2_SCR(DMA_STREAM6) +#define DMA2_S7CR DMA2_SCR(DMA_STREAM7) + +/* DMA number of data register (DMAx_SyNDTR) */ +#define DMA_SNDTR(dma_base, stream) MMIO32(dma_base + 0x14 + \ + (0x18 * (stream))) + +#define DMA1_SNDTR(stream) DMA_SNDTR(DMA1, stream) +#define DMA1_S0NDTR DMA1_SNDTR(DMA_STREAM0) +#define DMA1_S1NDTR DMA1_SNDTR(DMA_STREAM1) +#define DMA1_S2NDTR DMA1_SNDTR(DMA_STREAM2) +#define DMA1_S3NDTR DMA1_SNDTR(DMA_STREAM3) +#define DMA1_S4NDTR DMA1_SNDTR(DMA_STREAM4) +#define DMA1_S5NDTR DMA1_SNDTR(DMA_STREAM5) +#define DMA1_S6NDTR DMA1_SNDTR(DMA_STREAM6) +#define DMA1_S7NDTR DMA1_SNDTR(DMA_STREAM7) + +#define DMA2_SNDTR(stream) DMA_CNDTR(DMA2, stream) +#define DMA2_S0NDTR DMA2_SNDTR(DMA_STREAM0) +#define DMA2_S1NDTR DMA2_SNDTR(DMA_STREAM1) +#define DMA2_S2NDTR DMA2_SNDTR(DMA_STREAM2) +#define DMA2_S3NDTR DMA2_SNDTR(DMA_STREAM3) +#define DMA2_S4NDTR DMA2_SNDTR(DMA_STREAM4) +#define DMA2_S5NDTR DMA2_SNDTR(DMA_STREAM5) +#define DMA2_S6NDTR DMA2_SNDTR(DMA_STREAM6) +#define DMA2_S7NDTR DMA2_SNDTR(DMA_STREAM7) + +/* DMA peripheral address register (DMAx_SyPAR) */ +#define DMA_SPAR(dma_base, stream) MMIO32(dma_base + 0x18 + \ + (0x18 * (stream))) + +#define DMA1_SPAR(stream) DMA_SPAR(DMA1, stream) +#define DMA1_S0PAR DMA1_SPAR(DMA_STREAM0) +#define DMA1_S1PAR DMA1_SPAR(DMA_STREAM1) +#define DMA1_S2PAR DMA1_SPAR(DMA_STREAM2) +#define DMA1_S3PAR DMA1_SPAR(DMA_STREAM3) +#define DMA1_S4PAR DMA1_SPAR(DMA_STREAM4) +#define DMA1_S5PAR DMA1_SPAR(DMA_STREAM5) +#define DMA1_S6PAR DMA1_SPAR(DMA_STREAM6) +#define DMA1_S7PAR DMA1_SPAR(DMA_STREAM7) + +#define DMA2_SPAR(stream) DMA_SPAR(DMA2, stream) +#define DMA2_S0PAR DMA2_SPAR(DMA_STREAM0) +#define DMA2_S1PAR DMA2_SPAR(DMA_STREAM1) +#define DMA2_S2PAR DMA2_SPAR(DMA_STREAM2) +#define DMA2_S3PAR DMA2_SPAR(DMA_STREAM3) +#define DMA2_S4PAR DMA2_SPAR(DMA_STREAM4) +#define DMA2_S5PAR DMA2_SPAR(DMA_STREAM5) +#define DMA2_S6PAR DMA2_SPAR(DMA_STREAM6) +#define DMA2_S7PAR DMA2_SPAR(DMA_STREAM7) + +/* DMA memory 0 address register (DMAx_SyM0AR) */ + +#define DMA_SM0AR(dma_base, stream) MMIO32(dma_base + 0x1C + \ + (0x18 * (stream))) + +#define DMA1_SM0AR(stream) DMA_SM0AR(DMA1, stream) +#define DMA1_S0M0AR DMA1_SM0AR(DMA_STREAM0) +#define DMA1_S1M0AR DMA1_SM0AR(DMA_STREAM1) +#define DMA1_S2M0AR DMA1_SM0AR(DMA_STREAM2) +#define DMA1_S3M0AR DMA1_SM0AR(DMA_STREAM3) +#define DMA1_S4M0AR DMA1_SM0AR(DMA_STREAM4) +#define DMA1_S5M0AR DMA1_SM0AR(DMA_STREAM5) +#define DMA1_S6M0AR DMA1_SM0AR(DMA_STREAM6) +#define DMA1_S7M0AR DMA1_SM0AR(DMA_STREAM7) + +#define DMA2_SM0AR(stream) DMA_CM0AR(DMA2, stream) +#define DMA2_S0M0AR DMA2_SM0AR(DMA_STREAM0) +#define DMA2_S1M0AR DMA2_SM0AR(DMA_STREAM1) +#define DMA2_S2M0AR DMA2_SM0AR(DMA_STREAM2) +#define DMA2_S3M0AR DMA2_SM0AR(DMA_STREAM3) +#define DMA2_S4M0AR DMA2_SM0AR(DMA_STREAM4) +#define DMA2_S5M0AR DMA2_SM0AR(DMA_STREAM5) +#define DMA2_S6M0AR DMA2_SM0AR(DMA_STREAM6) +#define DMA2_S7M0AR DMA2_SM0AR(DMA_STREAM7) + +/* DMA memory 1 address register (DMAx_SyM1AR) */ + +#define DMA_SM1AR(dma_base, stream) MMIO32(dma_base + 0x20 + \ + (0x18 * (stream))) + +#define DMA1_SM1AR(stream) DMA_SM1AR(DMA1, stream) +#define DMA1_S0M1AR DMA1_SM1AR(DMA_STREAM0) +#define DMA1_S1M1AR DMA1_SM1AR(DMA_STREAM1) +#define DMA1_S2M1AR DMA1_SM1AR(DMA_STREAM2) +#define DMA1_S3M1AR DMA1_SM1AR(DMA_STREAM3) +#define DMA1_S4M1AR DMA1_SM1AR(DMA_STREAM4) +#define DMA1_S5M1AR DMA1_SM1AR(DMA_STREAM5) +#define DMA1_S6M1AR DMA1_SM1AR(DMA_STREAM6) +#define DMA1_S7M1AR DMA1_SM1AR(DMA_STREAM7) + +#define DMA2_SM1AR(stream) DMA_CM1AR(DMA2, stream) +#define DMA2_S0M1AR DMA2_SM1AR(DMA_STREAM0) +#define DMA2_S1M1AR DMA2_SM1AR(DMA_STREAM1) +#define DMA2_S2M1AR DMA2_SM1AR(DMA_STREAM2) +#define DMA2_S3M1AR DMA2_SM1AR(DMA_STREAM3) +#define DMA2_S4M1AR DMA2_SM1AR(DMA_STREAM4) +#define DMA2_S5M1AR DMA2_SM1AR(DMA_STREAM5) +#define DMA2_S6M1AR DMA2_SM1AR(DMA_STREAM6) +#define DMA2_S7M1AR DMA2_SM1AR(DMA_STREAM7) + +/* DMA FIFO Control Register register (DMAx_SyFCR) */ + +#define DMA_SFCR(dma_base, stream) MMIO32(dma_base + 0x24 + \ + (0x18 * (stream))) + +#define DMA1_SFCR(stream) DMA_SFCR(DMA1, stream) +#define DMA1_S0FCR DMA1_SFCR(DMA_STREAM0) +#define DMA1_S1FCR DMA1_SFCR(DMA_STREAM1) +#define DMA1_S2FCR DMA1_SFCR(DMA_STREAM2) +#define DMA1_S3FCR DMA1_SFCR(DMA_STREAM3) +#define DMA1_S4FCR DMA1_SFCR(DMA_STREAM4) +#define DMA1_S5FCR DMA1_SFCR(DMA_STREAM5) +#define DMA1_S6FCR DMA1_SFCR(DMA_STREAM6) +#define DMA1_S7FCR DMA1_SFCR(DMA_STREAM7) + +#define DMA2_SFCR(stream) DMA_CFCR(DMA2, stream) +#define DMA2_S0FCR DMA2_SFCR(DMA_STREAM0) +#define DMA2_S1FCR DMA2_SFCR(DMA_STREAM1) +#define DMA2_S2FCR DMA2_SFCR(DMA_STREAM2) +#define DMA2_S3FCR DMA2_SFCR(DMA_STREAM3) +#define DMA2_S4FCR DMA2_SFCR(DMA_STREAM4) +#define DMA2_S5FCR DMA2_SFCR(DMA_STREAM5) +#define DMA2_S6FCR DMA2_SFCR(DMA_STREAM6) +#define DMA2_S7FCR DMA2_SFCR(DMA_STREAM7) + +/* --- DMA Interrupt Flag offset values ------------------------------------- */ +/* These are based on every interrupt flag and flag clear being at the same relative location */ +/** @defgroup dma_if_offset DMA Interrupt Flag Offsets within stream flag group. +@ingroup STM32F4xx_dma_defines + +@{*/ +/** Transfer Complete Interrupt Flag */ +#define DMA_ISR_TCIF (1 << 5) +/** Half Transfer Interrupt Flag */ +#define DMA_ISR_HTIF (1 << 4) +/** Transfer Error Interrupt Flag */ +#define DMA_ISR_TEIF (1 << 3) +/** Direct Mode Error Interrupt Flag */ +#define DMA_ISR_DMEIF (1 << 2) +/** FIFO Error Interrupt Flag */ +#define DMA_ISR_FEIF (1 << 0) +/**@}*/ + +/* Offset within interrupt status register to start of stream interrupt flag field */ +#define DMA_ISR_OFFSET(stream) (6*(stream & 0x01)+16*((stream & 0x02) >> 1)) +#define DMA_ISR_FLAGS (DMA_ISR_TCIF | DMA_ISR_HTIF | DMA_ISR_TEIF | DMA_ISR_DMEIF | DMA_ISR_FEIF) +#define DMA_ISR_MASK(stream) DMA_ISR_FLAGS << DMA_ISR_OFFSET(stream) + +/* --- DMA_LISR values ------------------------------------------------------ */ + +/* TCIF: Transfer complete interrupt flag, streams 0-3 only */ +#define DMA_LISR_TCIF_BIT DMA_ISR_TCIF +#define DMA_LISR_TCIF(stream) (DMA_LISR_TCIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LISR_TCIF0 DMA_LISR_TCIF(DMA_STREAM0) +#define DMA_LISR_TCIF1 DMA_LISR_TCIF(DMA_STREAM1) +#define DMA_LISR_TCIF2 DMA_LISR_TCIF(DMA_STREAM2) +#define DMA_LISR_TCIF3 DMA_LISR_TCIF(DMA_STREAM3) + +/* HTIF: Half transfer interrupt flag, streams 0-3 only */ +#define DMA_LISR_HTIF_BIT DMA_ISR_HTIF +#define DMA_LISR_HTIF(stream) (DMA_LISR_HTIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LISR_HTIF0 DMA_LISR_HTIF(DMA_STREAM0) +#define DMA_LISR_HTIF1 DMA_LISR_HTIF(DMA_STREAM1) +#define DMA_LISR_HTIF2 DMA_LISR_HTIF(DMA_STREAM2) +#define DMA_LISR_HTIF3 DMA_LISR_HTIF(DMA_STREAM3) + +/* TEIF: Transfer error interrupt flag, streams 0-3 only */ +#define DMA_LISR_TEIF_BIT DMA_ISR_TEIF +#define DMA_LISR_TEIF(stream) (DMA_LISR_TEIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LISR_TEIF0 DMA_LISR_TEIF(DMA_STREAM0) +#define DMA_LISR_TEIF1 DMA_LISR_TEIF(DMA_STREAM1) +#define DMA_LISR_TEIF2 DMA_LISR_TEIF(DMA_STREAM2) +#define DMA_LISR_TEIF3 DMA_LISR_TEIF(DMA_STREAM3) + +/* DMEIF: Direct Mode Error interrupt flag, streams 0-3 only */ +#define DMA_LISR_DMEIF_BIT DMA_ISR_DMEIF +#define DMA_LISR_DMEIF(stream) (DMA_LISR_DMEIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LISR_DMEIF0 DMA_LISR_DMEIF(DMA_STREAM0) +#define DMA_LISR_DMEIF1 DMA_LISR_DMEIF(DMA_STREAM1) +#define DMA_LISR_DMEIF2 DMA_LISR_DMEIF(DMA_STREAM2) +#define DMA_LISR_DMEIF3 DMA_LISR_DMEIF(DMA_STREAM3) + +/* Interrupt #1 is reserved */ + +/* FEIF: FIFO Error interrupt flag, streams 0-3 only */ +#define DMA_LISR_FEIF_BIT DMA_ISR_FEIF +#define DMA_LISR_FEIF(stream) (DMA_LISR_FEIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LISR_FEIF0 DMA_LISR_FEIF(DMA_STREAM0) +#define DMA_LISR_FEIF1 DMA_LISR_FEIF(DMA_STREAM1) +#define DMA_LISR_FEIF2 DMA_LISR_FEIF(DMA_STREAM2) +#define DMA_LISR_FEIF3 DMA_LISR_FEIF(DMA_STREAM3) + +/* --- DMA_HISR values ------------------------------------------------------ */ + +/* TCIF: Transfer complete interrupt flag, streams 4-7 only */ +#define DMA_HISR_TCIF_BIT DMA_ISR_TCIF +#define DMA_HISR_TCIF(stream) (DMA_HISR_TCIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HISR_TCIF4 DMA_HISR_TCIF(DMA_STREAM4) +#define DMA_HISR_TCIF5 DMA_HISR_TCIF(DMA_STREAM5) +#define DMA_HISR_TCIF6 DMA_HISR_TCIF(DMA_STREAM6) +#define DMA_HISR_TCIF7 DMA_HISR_TCIF(DMA_STREAM7) + +/* HTIF: Half transfer interrupt flag, streams 4-7 only */ +#define DMA_HISR_HTIF_BIT DMA_ISR_HTIF +#define DMA_HISR_HTIF(stream) (DMA_HISR_HTIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HISR_HTIF4 DMA_HISR_HTIF(DMA_STREAM4) +#define DMA_HISR_HTIF5 DMA_HISR_HTIF(DMA_STREAM5) +#define DMA_HISR_HTIF6 DMA_HISR_HTIF(DMA_STREAM6) +#define DMA_HISR_HTIF7 DMA_HISR_HTIF(DMA_STREAM7) + +/* TEIF: Transfer error interrupt flag, streams 4-7 only */ +#define DMA_HISR_TEIF_BIT DMA_ISR_TEIF +#define DMA_HISR_TEIF(stream) (DMA_HISR_TEIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HISR_TEIF4 DMA_HISR_TEIF(DMA_STREAM4) +#define DMA_HISR_TEIF5 DMA_HISR_TEIF(DMA_STREAM5) +#define DMA_HISR_TEIF6 DMA_HISR_TEIF(DMA_STREAM6) +#define DMA_HISR_TEIF7 DMA_HISR_TEIF(DMA_STREAM7) + +/* DMEIF: Direct Mode Error interrupt flag, streams 4-7 only */ +#define DMA_HISR_DMEIF_BIT DMA_ISR_DMEIF +#define DMA_HISR_DMEIF(stream) (DMA_HISR_DMEIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HISR_DMEIF4 DMA_HISR_DMEIF(DMA_STREAM4) +#define DMA_HISR_DMEIF5 DMA_HISR_DMEIF(DMA_STREAM5) +#define DMA_HISR_DMEIF6 DMA_HISR_DMEIF(DMA_STREAM6) +#define DMA_HISR_DMEIF7 DMA_HISR_DMEIF(DMA_STREAM7) + +/* Interrupt #1 is reserved */ + +/* FEIF: FIFO Error interrupt flag, streams 4-7 only */ +#define DMA_HISR_FEIF_BIT DMA_ISR_FEIF +#define DMA_HISR_FEIF(stream) (DMA_HISR_FEIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HISR_FEIF4 DMA_HISR_FEIF(DMA_STREAM4) +#define DMA_HISR_FEIF5 DMA_HISR_FEIF(DMA_STREAM5) +#define DMA_HISR_FEIF6 DMA_HISR_FEIF(DMA_STREAM6) +#define DMA_HISR_FEIF7 DMA_HISR_FEIF(DMA_STREAM7) + +/* --- DMA_LIFCR values ------------------------------------------------------ */ + +/* TCIF: Transfer complete interrupt flag, streams 0-3 only */ +#define DMA_LIFCR_CTCIF_BIT DMA_ISR_TCIF +#define DMA_LIFCR_CTCIF(stream) (DMA_LIFCR_CTCIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LIFCR_CTCIF0 DMA_LIFCR_CTCIF(DMA_STREAM0) +#define DMA_LIFCR_CTCIF1 DMA_LIFCR_CTCIF(DMA_STREAM1) +#define DMA_LIFCR_CTCIF2 DMA_LIFCR_CTCIF(DMA_STREAM2) +#define DMA_LIFCR_CTCIF3 DMA_LIFCR_CTCIF(DMA_STREAM3) + +/* HTIF: Half transfer interrupt flag, streams 0-3 only */ +#define DMA_LIFCR_CHTIF_BIT DMA_ISR_HTIF +#define DMA_LIFCR_CHTIF(stream) (DMA_LIFCR_CHTIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LIFCR_CHTIF0 DMA_LIFCR_CHTIF(DMA_STREAM0) +#define DMA_LIFCR_CHTIF1 DMA_LIFCR_CHTIF(DMA_STREAM1) +#define DMA_LIFCR_CHTIF2 DMA_LIFCR_CHTIF(DMA_STREAM2) +#define DMA_LIFCR_CHTIF3 DMA_LIFCR_CHTIF(DMA_STREAM3) + +/* TEIF: Transfer error interrupt flag, streams 0-3 only */ +#define DMA_LIFCR_CTEIF_BIT DMA_ISR_TEIF +#define DMA_LIFCR_CTEIF(stream) (DMA_LIFCR_CTEIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LIFCR_CTEIF0 DMA_LIFCR_CTEIF(DMA_STREAM0) +#define DMA_LIFCR_CTEIF1 DMA_LIFCR_CTEIF(DMA_STREAM1) +#define DMA_LIFCR_CTEIF2 DMA_LIFCR_CTEIF(DMA_STREAM2) +#define DMA_LIFCR_CTEIF3 DMA_LIFCR_CTEIF(DMA_STREAM3) + +/* DMEIF: Direct Mode Error interrupt flag, streams 0-3 only */ +#define DMA_LIFCR_CDMEIF_BIT DMA_ISR_DMEIF +#define DMA_LIFCR_CDMEIF(stream) (DMA_LIFCR_CDMEIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LIFCR_CDMEIF0 DMA_LIFCR_CDMEIF(DMA_STREAM0) +#define DMA_LIFCR_CDMEIF1 DMA_LIFCR_CDMEIF(DMA_STREAM1) +#define DMA_LIFCR_CDMEIF2 DMA_LIFCR_CDMEIF(DMA_STREAM2) +#define DMA_LIFCR_CDMEIF3 DMA_LIFCR_CDMEIF(DMA_STREAM3) + +/* Interrupt #1 is reserved */ + +/* FEIF: FIFO Error interrupt flag, streams 0-3 only */ +#define DMA_LIFCR_CFEIF_BIT DMA_ISR_FEIF +#define DMA_LIFCR_CFEIF(stream) (DMA_LIFCR_CFEIF_BIT << DMA_ISR_OFFSET(stream)) + +#define DMA_LIFCR_CFEIF0 DMA_LIFCR_CFEIF(DMA_STREAM0) +#define DMA_LIFCR_CFEIF1 DMA_LIFCR_CFEIF(DMA_STREAM1) +#define DMA_LIFCR_CFEIF2 DMA_LIFCR_CFEIF(DMA_STREAM2) +#define DMA_LIFCR_CFEIF3 DMA_LIFCR_CFEIF(DMA_STREAM3) + +/* --- DMA_HIFCR values ------------------------------------------------------ */ + +/* TCIF: Transfer complete interrupt flag, streams 4-7 only */ +#define DMA_HIFCR_CTCIF_BIT DMA_ISR_TCIF +#define DMA_HIFCR_CTCIF(stream) (DMA_HIFCR_CTCIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HIFCR_CTCIF4 DMA_HIFCR_CTCIF(DMA_STREAM4) +#define DMA_HIFCR_CTCIF5 DMA_HIFCR_CTCIF(DMA_STREAM5) +#define DMA_HIFCR_CTCIF6 DMA_HIFCR_CTCIF(DMA_STREAM6) +#define DMA_HIFCR_CTCIF7 DMA_HIFCR_CTCIF(DMA_STREAM7) + +/* HTIF: Half transfer interrupt flag, streams 4-7 only */ +#define DMA_HIFCR_CHTIF_BIT DMA_ISR_HTIF +#define DMA_HIFCR_CHTIF(stream) (DMA_HIFCR_CHTIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HIFCR_CHTIF4 DMA_HIFCR_CHTIF(DMA_STREAM4) +#define DMA_HIFCR_CHTIF5 DMA_HIFCR_CHTIF(DMA_STREAM5) +#define DMA_HIFCR_CHTIF6 DMA_HIFCR_CHTIF(DMA_STREAM6) +#define DMA_HIFCR_CHTIF7 DMA_HIFCR_CHTIF(DMA_STREAM7) + +/* TEIF: Transfer error interrupt flag, streams 4-7 only */ +#define DMA_HIFCR_CTEIF_BIT DMA_ISR_TEIF +#define DMA_HIFCR_CTEIF(stream) (DMA_HIFCR_CTEIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HIFCR_CTEIF4 DMA_HIFCR_CTEIF(DMA_STREAM4) +#define DMA_HIFCR_CTEIF5 DMA_HIFCR_CTEIF(DMA_STREAM5) +#define DMA_HIFCR_CTEIF6 DMA_HIFCR_CTEIF(DMA_STREAM6) +#define DMA_HIFCR_CTEIF7 DMA_HIFCR_CTEIF(DMA_STREAM7) + +/* DMEIF: Direct Mode Error interrupt flag, streams 4-7 only */ +#define DMA_HIFCR_CDMEIF_BIT DMA_ISR_DMEIF +#define DMA_HIFCR_CDMEIF(stream) (DMA_HIFCR_CDMEIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HIFCR_CDMEIF4 DMA_HIFCR_CDMEIF(DMA_STREAM4) +#define DMA_HIFCR_CDMEIF5 DMA_HIFCR_CDMEIF(DMA_STREAM5) +#define DMA_HIFCR_CDMEIF6 DMA_HIFCR_CDMEIF(DMA_STREAM6) +#define DMA_HIFCR_CDMEIF7 DMA_HIFCR_CDMEIF(DMA_STREAM7) + +/* Interrupt #1 is reserved */ + +/* FEIF: FIFO Error interrupt flag, streams 4-7 only */ +#define DMA_HIFCR_CFEIF_BIT DMA_ISR_FEIF +#define DMA_HIFCR_CFEIF(stream) (DMA_HIFCR_CFEIF_BIT << (DMA_ISR_OFFSET(stream - 4)) + +#define DMA_HIFCR_CFEIF4 DMA_HIFCR_CFEIF(DMA_STREAM4) +#define DMA_HIFCR_CFEIF5 DMA_HIFCR_CFEIF(DMA_STREAM5) +#define DMA_HIFCR_CFEIF6 DMA_HIFCR_CFEIF(DMA_STREAM6) +#define DMA_HIFCR_CFEIF7 DMA_HIFCR_CFEIF(DMA_STREAM7) + +/* --- DMA_SxCR generic values --------------------------------------------- */ + +/* Reserved [31:28] */ + +/* CHSEL[13:12]: Channel Select */ +/** @defgroup dma_ch_sel DMA Channel Select +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SCR_CHSEL_0 (0x0 << 25) +#define DMA_SCR_CHSEL_1 (0x1 << 25) +#define DMA_SCR_CHSEL_2 (0x2 << 25) +#define DMA_SCR_CHSEL_3 (0x3 << 25) +#define DMA_SCR_CHSEL_4 (0x4 << 25) +#define DMA_SCR_CHSEL_5 (0x5 << 25) +#define DMA_SCR_CHSEL_6 (0x6 << 25) +#define DMA_SCR_CHSEL_7 (0x7 << 25) +/**@}*/ +#define DMA_SCR_CHSEL_MASK (0x7 << 25) +#define DMA_SCR_CHSEL_SHIFT 25 + +/* MBURST[13:12]: Memory Burst Configuration */ +/** @defgroup dma_mburst DMA Memory Burst Length +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SCR_MBURST_INCR0 (0x0 << 23) +#define DMA_SCR_MBURST_INCR4 (0x1 << 23) +#define DMA_SCR_MBURST_INCR8 (0x2 << 23) +#define DMA_SCR_MBURST_INCR16 (0x3 << 23) +/**@}*/ +#define DMA_SCR_MBURST_MASK (0x3 << 23) +#define DMA_SCR_MBURST_SHIFT 23 + +/* PBURST[13:12]: Peripheral Burst Configuration */ +/** @defgroup dma_pburst DMA Peripheral Burst Length +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SCR_PBURST_INCR0 (0x0 << 21) +#define DMA_SCR_PBURST_INCR4 (0x1 << 21) +#define DMA_SCR_PBURST_INCR8 (0x2 << 21) +#define DMA_SCR_PBURST_INCR16 (0x3 << 21) +/**@}*/ +#define DMA_SCR_PBURST_MASK (0x3 << 21) +#define DMA_SCR_PBURST_SHIFT 21 + +/* Bit 20 reserved */ + +/* CT: Current target (in double buffered mode) */ +#define DMA_SCR_CT (1 << 19) + +/* DBM: Double buffered mode */ +#define DMA_SCR_DBM (1 << 18) + +/* PL[17:16]: Stream priority level */ +/** @defgroup dma_st_pri DMA Stream Priority Levels +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SCR_PL_LOW (0x0 << 16) +#define DMA_SCR_PL_MEDIUM (0x1 << 16) +#define DMA_SCR_PL_HIGH (0x2 << 16) +#define DMA_SCR_PL_VERY_HIGH (0x3 << 16) +/**@}*/ +#define DMA_SCR_PL_MASK (0x3 << 16) +#define DMA_SCR_PL_SHIFT 16 + +/* PINCOS: Peripheral increment offset size */ +#define DMA_SCR_PINCOS (1 << 15) + +/* MSIZE[14:13]: Memory size */ +/** @defgroup dma_st_memwidth DMA Stream Memory Word Width +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SCR_MSIZE_8BIT (0x0 << 13) +#define DMA_SCR_MSIZE_16BIT (0x1 << 13) +#define DMA_SCR_MSIZE_32BIT (0x2 << 13) +/**@}*/ +#define DMA_SCR_MSIZE_MASK (0x3 << 13) +#define DMA_SCR_MSIZE_SHIFT 13 + +/* PSIZE[12:11]: Peripheral size */ +/** @defgroup dma_st_perwidth DMA Stream Peripheral Word Width +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SCR_PSIZE_8BIT (0x0 << 11) +#define DMA_SCR_PSIZE_16BIT (0x1 << 11) +#define DMA_SCR_PSIZE_32BIT (0x2 << 11) +/**@}*/ +#define DMA_SCR_PSIZE_MASK (0x3 << 11) +#define DMA_SCR_PSIZE_SHIFT 11 + +/* MINC: Memory increment mode */ +#define DMA_SCR_MINC (1 << 10) + +/* PINC: Peripheral increment mode */ +#define DMA_SCR_PINC (1 << 9) + +/* CIRC: Circular mode */ +#define DMA_SCR_CIRC (1 << 8) + +/* DIR[7:6]: Data transfer direction */ +/** @defgroup dma_st_dir DMA Stream Data transfer direction +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_SCR_DIR_PER2MEM (0x0 << 6) +#define DMA_SCR_DIR_MEM2PER (0x1 << 6) +#define DMA_SCR_DIR_MEM2MEM (0x2 << 6) +/**@}*/ +#define DMA_SCR_DIR_MASK (0x3 << 6) +#define DMA_SCR_DIR_SHIFT 6 + +/* PFCTRL: Peripheral Flow Controller */ +#define DMA_SCR_PFCTRL (1 << 5) + +/* TCIE: Transfer complete interrupt enable */ +#define DMA_SCR_TCIE (1 << 4) + +/* HTIE: Half transfer interrupt enable */ +#define DMA_SCR_HTIE (1 << 3) + +/* TEIE: Transfer error interrupt enable */ +#define DMA_SCR_TEIE (1 << 2) + +/* DMEIE: Direct Mode error interrupt enable */ +#define DMA_SCR_DMEIE (1 << 1) + +/* EN: Stream enable */ +#define DMA_SCR_EN (1 << 0) + +/* --- DMA_SxNDTR values --------------------------------------------------- */ + +/* NDT[15:0]: Number of data to transfer */ + +/* --- DMA_SxPAR values ---------------------------------------------------- */ + +/* PA[31:0]: Peripheral address */ + +/* --- DMA_SxM0AR values ---------------------------------------------------- */ + +/* M0A[31:0]: Memory address */ + +/* --- DMA_SxM1AR values ---------------------------------------------------- */ + +/* M1A[31:0]: Memory address */ + +/* --- DMA_SxFCR generic values --------------------------------------------- */ + +/* Reserved [31:8] */ + +/* FEIE: FIFO error interrupt enable */ +#define DMA_FCR_FEIE (1 << 7) + +/* Bit 6 reserved */ + +/* FS[5:3]: FIFO Status */ +/** @defgroup dma_fifo_status FIFO Status +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_FCR_FS_LOW (0x0 << 3) +#define DMA_FCR_FS_UNDER_HALF (0x1 << 3) +#define DMA_FCR_FS_MEDIUM (0x2 << 3) +#define DMA_FCR_FS_HIGH (0x3 << 3) +#define DMA_FCR_FS_EMPTY (0x4 << 3) +#define DMA_FCR_FS_FULL (0x5 << 3) +/**@}*/ +#define DMA_FCR_FS_MASK (0x7 << 3) +#define DMA_FCR_FS_SHIFT 3 + +/* DMDIS: Direct Mode disable */ +#define DMA_FCR_DMDIS (1 << 2) + +/* FTH[1:0]: FIFO Threshold selection */ +/** @defgroup dma_fifo_thresh FIFO Threshold selection +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_FCR_FTH_LOW (0x0 << 0) +#define DMA_FCR_FTH_HALF (0x1 << 0) +#define DMA_FCR_FTH_MEDIUM (0x2 << 0) +#define DMA_FCR_FTH_FULL (0x3 << 0) +/**@}*/ +#define DMA_FCR_FTH_MASK (0x3 << 0) +#define DMA_FCR_FTH_SHIFT 3 + +/* --- Generic values ------------------------------------------------------ */ + +/** @defgroup dma_st_number DMA Stream Number +@ingroup STM32F4xx_dma_defines + +@{*/ +#define DMA_STREAM0 0 +#define DMA_STREAM1 1 +#define DMA_STREAM2 2 +#define DMA_STREAM3 3 +#define DMA_STREAM4 4 +#define DMA_STREAM5 5 +#define DMA_STREAM6 6 +#define DMA_STREAM7 7 +/**@}*/ + +/* --- function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void dma_stream_reset(u32 dma, u8 stream); +void dma_clear_interrupt_flags(u32 dma, u8 stream, u32 interrupts); +bool dma_get_interrupt_flag(u32 dma, u8 stream, u32 interrupt); +void dma_set_transfer_mode(u32 dma, u8 stream, u32 direction); +void dma_set_priority(u32 dma, u8 stream, u32 prio); +void dma_set_memory_size(u32 dma, u8 stream, u32 mem_size); +void dma_set_peripheral_size(u32 dma, u8 stream, u32 peripheral_size); +void dma_enable_memory_increment_mode(u32 dma, u8 stream); +void dma_disable_memory_increment_mode(u32 dma, u8 channel); +void dma_enable_peripheral_increment_mode(u32 dma, u8 stream); +void dma_disable_peripheral_increment_mode(u32 dma, u8 channel); +void dma_enable_fixed_peripheral_increment_mode(u32 dma, u8 stream); +void dma_enable_circular_mode(u32 dma, u8 stream); +void dma_channel_select(u32 dma, u8 stream, u32 channel); +void dma_channel_select(u32 dma, u8 stream, u32 channel); +void dma_set_memory_burst(u32 dma, u8 stream, u32 burst); +void dma_set_peripheral_burst(u32 dma, u8 stream, u32 burst); +void dma_set_initial_target(u32 dma, u8 stream, u8 memory); +u8 dma_get_target(u32 dma, u8 stream); +void dma_enable_double_buffer_mode(u32 dma, u8 stream); +void dma_set_peripheral_flow_control(u32 dma, u8 stream); +void dma_set_dma_flow_control(u32 dma, u8 stream); +void dma_enable_transfer_error_interrupt(u32 dma, u8 stream); +void dma_disable_transfer_error_interrupt(u32 dma, u8 stream); +void dma_enable_half_transfer_interrupt(u32 dma, u8 stream); +void dma_disable_half_transfer_interrupt(u32 dma, u8 stream); +void dma_enable_transfer_complete_interrupt(u32 dma, u8 stream); +void dma_disable_transfer_complete_interrupt(u32 dma, u8 stream); +u32 dma_fifo_status(u32 dma, u8 stream); +void dma_enable_direct_mode_error_interrupt(u32 dma, u8 stream); +void dma_disable_direct_mode_error_interrupt(u32 dma, u8 stream); +void dma_enable_fifo_error_interrupt(u32 dma, u8 stream); +void dma_disable_fifo_error_interrupt(u32 dma, u8 stream); +void dma_enable_direct_mode(u32 dma, u8 stream); +void dma_enable_fifo_mode(u32 dma, u8 stream); +void dma_set_fifo_threshold(u32 dma, u8 stream, u32 threshold); +void dma_enable_stream(u32 dma, u8 stream); +void dma_disable_stream(u32 dma, u8 stream); +void dma_set_peripheral_address(u32 dma, u8 stream, u32 address); +void dma_set_memory_address(u32 dma, u8 stream, u32 address); +void dma_set_memory_address_1(u32 dma, u8 stream, u32 address); +void dma_set_number_of_data(u32 dma, u8 stream, u16 number); + +END_DECLS + +#endif +/**@}*/ + diff --git a/include/libopencm3/stm32/f4/irq.yaml b/include/libopencm3/stm32/f4/irq.yaml new file mode 100644 index 00000000..2d4bae9e --- /dev/null +++ b/include/libopencm3/stm32/f4/irq.yaml @@ -0,0 +1,85 @@ +includeguard: LIBOPENCM3_STM32_F4_NVIC_H +partname_humanreadable: STM32 F4 series +partname_doxygen: STM32F4 +irqs: + - nvic_wwdg + - pvd + - tamp_stamp + - rtc_wkup + - flash + - rcc + - exti0 + - exti1 + - exti2 + - exti3 + - exti4 + - dma1_stream0 + - dma1_stream1 + - dma1_stream2 + - dma1_stream3 + - dma1_stream4 + - dma1_stream5 + - dma1_stream6 + - adc + - can1_tx + - can1_rx0 + - can1_rx1 + - can1_sce + - exti9_5 + - tim1_brk_tim9 + - tim1_up_tim10 + - tim1_trg_com_tim11 + - tim1_cc + - tim2 + - tim3 + - tim4 + - i2c1_ev + - i2c1_er + - i2c2_ev + - i2c2_er + - spi1 + - spi2 + - usart1 + - usart2 + - usart3 + - exti15_10 + - rtc_alarm + - usb_fs_wkup + - tim8_brk_tim12 + - tim8_up_tim13 + - tim8_trg_com_tim14 + - tim8_cc + - dma1_stream7 + - fsmc + - sdio + - tim5 + - spi3 + - uart4 + - uart5 + - tim6_dac + - tim7 + - dma2_stream0 + - dma2_stream1 + - dma2_stream2 + - dma2_stream3 + - dma2_stream4 + - eth + - eth_wkup + - can2_tx + - can2_rx0 + - can2_rx1 + - can2_sce + - otg_fs + - dma2_stream5 + - dma2_stream6 + - dma2_stream7 + - usart6 + - i2c3_ev + - i2c3_er + - otg_hs_ep1_out + - otg_hs_ep1_in + - otg_hs_wkup + - otg_hs + - dcmi + - cryp + - hash_rng diff --git a/include/libopencm3/stm32/f4/nvic_f4.h b/include/libopencm3/stm32/f4/nvic_f4.h deleted file mode 100644 index 91b6c251..00000000 --- a/include/libopencm3/stm32/f4/nvic_f4.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LIBOPENCM3_NVIC_F4_H -#define LIBOPENCM3_NVIC_F4_H - -/* --- IRQ channel numbers-------------------------------------------------- */ - -/* Note: These F4 specific user interrupt definitions supplement the - * general NVIC definitions in ../nvic.h - */ - -/* User Interrupts */ -#define NVIC_NVIC_WWDG_IRQ 0 -#define NVIC_PVD_IRQ 1 -#define NVIC_TAMP_STAMP_IRQ 2 -#define NVIC_RTC_WKUP_IRQ 3 -#define NVIC_FLASH_IRQ 4 -#define NVIC_RCC_IRQ 5 -#define NVIC_EXTI0_IRQ 6 -#define NVIC_EXTI1_IRQ 7 -#define NVIC_EXTI2_IRQ 8 -#define NVIC_EXTI3_IRQ 9 -#define NVIC_EXTI4_IRQ 10 -#define NVIC_DMA1_STREAM0_IRQ 11 -#define NVIC_DMA1_STREAM1_IRQ 12 -#define NVIC_DMA1_STREAM2_IRQ 13 -#define NVIC_DMA1_STREAM3_IRQ 14 -#define NVIC_DMA1_STREAM4_IRQ 15 -#define NVIC_DMA1_STREAM5_IRQ 16 -#define NVIC_DMA1_STREAM6_IRQ 17 -#define NVIC_ADC_IRQ 18 -#define NVIC_CAN1_TX_IRQ 19 -#define NVIC_CAN1_RX0_IRQ 20 -#define NVIC_CAN1_RX1_IRQ 21 -#define NVIC_CAN1_SCE_IRQ 22 -#define NVIC_EXTI9_5_IRQ 23 -#define NVIC_TIM1_BRK_TIM9_IRQ 24 -#define NVIC_TIM1_UP_TIM10_IRQ 25 -#define NVIC_TIM1_TRG_COM_TIM11_IRQ 26 -#define NVIC_TIM1_CC_IRQ 27 -#define NVIC_TIM2_IRQ 28 -#define NVIC_TIM3_IRQ 29 -#define NVIC_TIM4_IRQ 30 -#define NVIC_I2C1_EV_IRQ 31 -#define NVIC_I2C1_ER_IRQ 32 -#define NVIC_I2C2_EV_IRQ 33 -#define NVIC_I2C2_ER_IRQ 34 -#define NVIC_SPI1_IRQ 35 -#define NVIC_SPI2_IRQ 36 -#define NVIC_USART1_IRQ 37 -#define NVIC_USART2_IRQ 38 -#define NVIC_USART3_IRQ 39 -#define NVIC_EXTI15_10_IRQ 40 -#define NVIC_RTC_ALARM_IRQ 41 -#define NVIC_USB_FS_WKUP_IRQ 42 -#define NVIC_TIM8_BRK_TIM12_IRQ 43 -#define NVIC_TIM8_UP_TIM13_IRQ 44 -#define NVIC_TIM8_TRG_COM_TIM14_IRQ 45 -#define NVIC_TIM8_CC_IRQ 46 -#define NVIC_DMA1_STREAM7_IRQ 47 -#define NVIC_FSMC_IRQ 48 -#define NVIC_SDIO_IRQ 49 -#define NVIC_TIM5_IRQ 50 -#define NVIC_SPI3_IRQ 51 -#define NVIC_UART4_IRQ 52 -#define NVIC_UART5_IRQ 53 -#define NVIC_TIM6_DAC_IRQ 54 -#define NVIC_TIM7_IRQ 55 -#define NVIC_DMA2_STREAM0_IRQ 56 -#define NVIC_DMA2_STREAM1_IRQ 57 -#define NVIC_DMA2_STREAM2_IRQ 58 -#define NVIC_DMA2_STREAM3_IRQ 59 -#define NVIC_DMA2_STREAM4_IRQ 60 -#define NVIC_ETH_IRQ 61 -#define NVIC_ETH_WKUP_IRQ 62 -#define NVIC_CAN2_TX_IRQ 63 -#define NVIC_CAN2_RX0_IRQ 64 -#define NVIC_CAN2_RX1_IRQ 65 -#define NVIC_CAN2_SCE_IRQ 66 -#define NVIC_OTG_FS_IRQ 67 -#define NVIC_DMA2_STREAM5_IRQ 68 -#define NVIC_DMA2_STREAM6_IRQ 69 -#define NVIC_DMA2_STREAM7_IRQ 70 -#define NVIC_USART6_IRQ 71 -#define NVIC_I2C3_EV_IRQ 72 -#define NVIC_I2C3_ER_IRQ 73 -#define NVIC_OTG_HS_EP1_OUT_IRQ 74 -#define NVIC_OTG_HS_EP1_IN_IRQ 75 -#define NVIC_OTG_HS_WKUP_IRQ 76 -#define NVIC_OTG_HS_IRQ 77 -#define NVIC_DCMI_IRQ 78 -#define NVIC_CRYP_IRQ 79 -#define NVIC_HASH_RNG_IRQ 80 - -#endif diff --git a/include/libopencm3/stm32/f4/syscfg.h b/include/libopencm3/stm32/f4/syscfg.h deleted file mode 100644 index 7426f16c..00000000 --- a/include/libopencm3/stm32/f4/syscfg.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LIBOPENCM3_SYSCFG_H -#define LIBOPENCM3_SYSCFG_H - -#include <libopencm3/stm32/memorymap.h> - -/* --- SYSCFG registers ------------------------------------------------------ */ - -#define SYSCFG_MEMRM MMIO32(SYSCFG_BASE + 0x00) - -#define SYSCFG_PMC MMIO32(SYSCFG_BASE + 0x04) - -/* External interrupt configuration register 1 (SYSCFG_EXTICR1) */ -#define SYSCFG_EXTICR1 MMIO32(SYSCFG_BASE + 0x08) - -/* External interrupt configuration register 2 (SYSCFG_EXTICR2) */ -#define SYSCFG_EXTICR2 MMIO32(SYSCFG_BASE + 0x0c) - -/* External interrupt configuration register 3 (SYSCFG_EXTICR3) */ -#define SYSCFG_EXTICR3 MMIO32(SYSCFG_BASE + 0x10) - -/* External interrupt configuration register 4 (SYSCFG_EXTICR4) */ -#define SYSCFG_EXTICR4 MMIO32(SYSCFG_BASE + 0x14) - -#define SYSCFG_CMPCR MMIO32(SYSCFG_BASE + 0x20) - -#endif - diff --git a/include/libopencm3/stm32/i2c.h b/include/libopencm3/stm32/i2c.h index 05a4d168..1b2dc0ee 100644 --- a/include/libopencm3/stm32/i2c.h +++ b/include/libopencm3/stm32/i2c.h @@ -321,9 +321,15 @@ LGPL License Terms @ref lgpl_license #define I2C_CCR_FS (1 << 15) /* DUTY: Fast Mode Duty Cycle */ +/** @defgroup i2c_duty_cycle I2C peripheral clock duty cycles +@ingroup i2c_defines + +@{*/ #define I2C_CCR_DUTY (1 << 14) #define I2C_CCR_DUTY_DIV2 0 #define I2C_CCR_DUTY_16_DIV_9 1 +/**@}*/ + /* Note: Bits [13:12] are reserved, and forced to 0 by hardware. */ /* diff --git a/include/libopencm3/stm32/l1/gpio.h b/include/libopencm3/stm32/l1/gpio.h new file mode 100644 index 00000000..a39c9f6e --- /dev/null +++ b/include/libopencm3/stm32/l1/gpio.h @@ -0,0 +1,241 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * Copyright (C) 2012 Piotr Esden-Tempski <piotr@esden.net> + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include <libopencm3/stm32/memorymap.h> +#include <libopencm3/cm3/common.h> + +/* --- Convenience macros -------------------------------------------------- */ + +/* GPIO port base addresses (for convenience) */ +#define GPIOA GPIO_PORT_A_BASE +#define GPIOB GPIO_PORT_B_BASE +#define GPIOC GPIO_PORT_C_BASE +#define GPIOD GPIO_PORT_D_BASE +#define GPIOE GPIO_PORT_E_BASE +#define GPIOH GPIO_PORT_H_BASE + +/* GPIO number definitions (for convenience) */ +#define GPIO0 (1 << 0) +#define GPIO1 (1 << 1) +#define GPIO2 (1 << 2) +#define GPIO3 (1 << 3) +#define GPIO4 (1 << 4) +#define GPIO5 (1 << 5) +#define GPIO6 (1 << 6) +#define GPIO7 (1 << 7) +#define GPIO8 (1 << 8) +#define GPIO9 (1 << 9) +#define GPIO10 (1 << 10) +#define GPIO11 (1 << 11) +#define GPIO12 (1 << 12) +#define GPIO13 (1 << 13) +#define GPIO14 (1 << 14) +#define GPIO15 (1 << 15) +#define GPIO_ALL 0xffff + +/* --- GPIO registers ------------------------------------------------------ */ + +/* Port mode register (GPIOx_MODER) */ +#define GPIO_MODER(port) MMIO32(port + 0x00) +#define GPIOA_MODER GPIO_MODER(GPIOA) +#define GPIOB_MODER GPIO_MODER(GPIOB) +#define GPIOC_MODER GPIO_MODER(GPIOC) +#define GPIOD_MODER GPIO_MODER(GPIOD) +#define GPIOE_MODER GPIO_MODER(GPIOE) +#define GPIOH_MODER GPIO_MODER(GPIOH) + +/* Port output type register (GPIOx_OTYPER) */ +#define GPIO_OTYPER(port) MMIO32(port + 0x04) +#define GPIOA_OTYPER GPIO_OTYPER(GPIOA) +#define GPIOB_OTYPER GPIO_OTYPER(GPIOB) +#define GPIOC_OTYPER GPIO_OTYPER(GPIOC) +#define GPIOD_OTYPER GPIO_OTYPER(GPIOD) +#define GPIOE_OTYPER GPIO_OTYPER(GPIOE) +#define GPIOH_OTYPER GPIO_OTYPER(GPIOH) + +/* Port output speed register (GPIOx_OSPEEDR) */ +#define GPIO_OSPEEDR(port) MMIO32(port + 0x08) +#define GPIOA_OSPEEDR GPIO_OSPEEDR(GPIOA) +#define GPIOB_OSPEEDR GPIO_OSPEEDR(GPIOB) +#define GPIOC_OSPEEDR GPIO_OSPEEDR(GPIOC) +#define GPIOD_OSPEEDR GPIO_OSPEEDR(GPIOD) +#define GPIOE_OSPEEDR GPIO_OSPEEDR(GPIOE) +#define GPIOH_OSPEEDR GPIO_OSPEEDR(GPIOH) + +/* Port pull-up/pull-down register (GPIOx_PUPDR) */ +#define GPIO_PUPDR(port) MMIO32(port + 0x0c) +#define GPIOA_PUPDR GPIO_PUPDR(GPIOA) +#define GPIOB_PUPDR GPIO_PUPDR(GPIOB) +#define GPIOC_PUPDR GPIO_PUPDR(GPIOC) +#define GPIOD_PUPDR GPIO_PUPDR(GPIOD) +#define GPIOE_PUPDR GPIO_PUPDR(GPIOE) +#define GPIOH_PUPDR GPIO_PUPDR(GPIOH) + +/* Port input data register (GPIOx_IDR) */ +#define GPIO_IDR(port) MMIO32(port + 0x10) +#define GPIOA_IDR GPIO_IDR(GPIOA) +#define GPIOB_IDR GPIO_IDR(GPIOB) +#define GPIOC_IDR GPIO_IDR(GPIOC) +#define GPIOD_IDR GPIO_IDR(GPIOD) +#define GPIOE_IDR GPIO_IDR(GPIOE) +#define GPIOH_IDR GPIO_IDR(GPIOH) + +/* Port output data register (GPIOx_ODR) */ +#define GPIO_ODR(port) MMIO32(port + 0x14) +#define GPIOA_ODR GPIO_ODR(GPIOA) +#define GPIOB_ODR GPIO_ODR(GPIOB) +#define GPIOC_ODR GPIO_ODR(GPIOC) +#define GPIOD_ODR GPIO_ODR(GPIOD) +#define GPIOE_ODR GPIO_ODR(GPIOE) +#define GPIOH_ODR GPIO_ODR(GPIOH) + +/* Port bit set/reset register (GPIOx_BSRR) */ +#define GPIO_BSRR(port) MMIO32(port + 0x18) +#define GPIOA_BSRR GPIO_BSRR(GPIOA) +#define GPIOB_BSRR GPIO_BSRR(GPIOB) +#define GPIOC_BSRR GPIO_BSRR(GPIOC) +#define GPIOD_BSRR GPIO_BSRR(GPIOD) +#define GPIOE_BSRR GPIO_BSRR(GPIOE) +#define GPIOH_BSRR GPIO_BSRR(GPIOH) + +/* Port configuration lock register (GPIOx_LCKR) */ +#define GPIO_LCKR(port) MMIO32(port + 0x1C) +#define GPIOA_LCKR GPIO_LCKR(GPIOA) +#define GPIOB_LCKR GPIO_LCKR(GPIOB) +#define GPIOC_LCKR GPIO_LCKR(GPIOC) +#define GPIOD_LCKR GPIO_LCKR(GPIOD) +#define GPIOE_LCKR GPIO_LCKR(GPIOE) +#define GPIOH_LCKR GPIO_LCKR(GPIOH) + +/* Alternate function low register (GPIOx_AFRL) */ +#define GPIO_AFRL(port) MMIO32(port + 0x20) +#define GPIOA_AFRL GPIO_AFRL(GPIOA) +#define GPIOB_AFRL GPIO_AFRL(GPIOB) +#define GPIOC_AFRL GPIO_AFRL(GPIOC) +#define GPIOD_AFRL GPIO_AFRL(GPIOD) +#define GPIOE_AFRL GPIO_AFRL(GPIOE) +#define GPIOH_AFRL GPIO_AFRL(GPIOH) + +/* Alternate function high register (GPIOx_AFRH) */ +#define GPIO_AFRH(port) MMIO32(port + 0x24) +#define GPIOA_AFRH GPIO_AFRH(GPIOA) +#define GPIOB_AFRH GPIO_AFRH(GPIOB) +#define GPIOC_AFRH GPIO_AFRH(GPIOC) +#define GPIOD_AFRH GPIO_AFRH(GPIOD) +#define GPIOE_AFRH GPIO_AFRH(GPIOE) +#define GPIOH_AFRH GPIO_AFRH(GPIOH) + +/* --- GPIOx_MODER values-------------------------------------------- */ + +#define GPIO_MODE(n, mode) (mode << (2 * (n))) +#define GPIO_MODE_MASK(n) (0x3 << (2 * (n))) +#define GPIO_MODE_INPUT 0x00 /* Default */ +#define GPIO_MODE_OUTPUT 0x01 +#define GPIO_MODE_AF 0x02 +#define GPIO_MODE_ANALOG 0x03 + +/* --- GPIOx_OTYPER values -------------------------------------------- */ +/* Output type (OTx values) */ +#define GPIO_OTYPE_PP 0x0 +#define GPIO_OTYPE_OD 0x1 + +/* Output speed values */ +#define GPIO_OSPEED(n, speed) (speed << (2 * (n))) +#define GPIO_OSPEED_MASK(n) (0x3 << (2 * (n))) +#define GPIO_OSPEED_400KHZ 0x0 +#define GPIO_OSPEED_2MHZ 0x1 +#define GPIO_OSPEED_10MHZ 0x2 +#define GPIO_OSPEED_40MHZ 0x3 + +/* --- GPIOx_PUPDR values ------------------------------------------- */ + +#define GPIO_PUPD(n, pupd) (pupd << (2 * (n))) +#define GPIO_PUPD_MASK(n) (0x3 << (2 * (n))) +#define GPIO_PUPD_NONE 0x0 +#define GPIO_PUPD_PULLUP 0x1 +#define GPIO_PUPD_PULLDOWN 0x2 + +/* --- GPIO_IDR values ----------------------------------------------------- */ + +/* GPIO_IDR[15:0]: IDRy[15:0]: Port input data (y = 0..15) */ + +/* --- GPIO_ODR values ----------------------------------------------------- */ + +/* GPIO_ODR[15:0]: ODRy[15:0]: Port output data (y = 0..15) */ + +/* --- GPIO_BSRR values ---------------------------------------------------- */ + +/* GPIO_BSRR[31:16]: BRy: Port x reset bit y (y = 0..15) */ +/* GPIO_BSRR[15:0]: BSy: Port x set bit y (y = 0..15) */ + +/* --- GPIO_LCKR values ---------------------------------------------------- */ + +#define GPIO_LCKK (1 << 16) +/* GPIO_LCKR[15:0]: LCKy: Port x lock bit y (y = 0..15) */ + +/* --- GPIOx_AFRL/H values ------------------------------------------------- */ + +/* Note: AFRL is used for bits 0..7, AFRH is used for 8..15 */ +/* See datasheet table 5, page 35 for the definitions */ + +#define GPIO_AFR(n, af) (af << ((n) * 4)) +#define GPIO_AFR_MASK(n) (0xf << ((n) * 4)) +#define GPIO_AF0 0x0 +#define GPIO_AF1 0x1 +#define GPIO_AF2 0x2 +#define GPIO_AF3 0x3 +#define GPIO_AF4 0x4 +#define GPIO_AF5 0x5 +#define GPIO_AF6 0x6 +#define GPIO_AF7 0x7 +#define GPIO_AF8 0x8 +#define GPIO_AF9 0x9 +#define GPIO_AF10 0xa +#define GPIO_AF11 0xb +#define GPIO_AF12 0xc +#define GPIO_AF13 0xd +#define GPIO_AF14 0xe +#define GPIO_AF15 0xf + +/* --- Function prototypes ------------------------------------------------- */ + +/* + * L1, like F2 and F4, has the "new" GPIO peripheral, so use that style + * TODO: this should all really be moved to a "common" gpio header + */ + +void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios); +void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios); +void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios); + +/* F1 compatible api */ +void gpio_set(u32 gpioport, u16 gpios); +void gpio_clear(u32 gpioport, u16 gpios); +u16 gpio_get(u32 gpioport, u16 gpios); +void gpio_toggle(u32 gpioport, u16 gpios); +u16 gpio_port_read(u32 gpioport); +void gpio_port_write(u32 gpioport, u16 data); +void gpio_port_config_lock(u32 gpioport, u16 gpios); + +#endif diff --git a/include/libopencm3/stm32/l1/irq.yaml b/include/libopencm3/stm32/l1/irq.yaml new file mode 100644 index 00000000..c2f118f7 --- /dev/null +++ b/include/libopencm3/stm32/l1/irq.yaml @@ -0,0 +1,49 @@ +includeguard: LIBOPENCM3_STM32_L1_NVIC_H +partname_humanreadable: STM32 L1 series +partname_doxygen: STM32L1 +irqs: + - wwdg + - pvd + - tamper + - rtc + - flash + - rcc + - exti0 + - exti1 + - exti2 + - exti3 + - exti4 + - dma1_channel1 + - dma1_channel2 + - dma1_channel3 + - dma1_channel4 + - dma1_channel5 + - dma1_channel6 + - dma1_channel7 + - adc1 + - usb_hp + - usb_lp + - dac + - comp + - exti9_5 + - lcd + - tim9 + - tim10 + - tim11 + - tim2 + - tim3 + - tim4 + - i2c1_ev + - i2c1_er + - i2c2_ev + - i2c2_er + - spi1 + - spi2 + - usart1 + - usart2 + - usart3 + - exti15_10 + - rtc_alarm + - usb_wakeup + - tim6 + - tim7 diff --git a/include/libopencm3/stm32/l1/memorymap.h b/include/libopencm3/stm32/l1/memorymap.h new file mode 100644 index 00000000..950dd18f --- /dev/null +++ b/include/libopencm3/stm32/l1/memorymap.h @@ -0,0 +1,108 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include <libopencm3/cm3/memorymap.h> + +/* --- STM32 specific peripheral definitions ------------------------------- */ + +/* Memory map for all busses */ +#define PERIPH_BASE ((u32)0x40000000) +#define INFO_BASE ((u32)0x1ff00000) +#define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) +#define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) +#define PERIPH_BASE_AHB (PERIPH_BASE + 0x20000) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB1 + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB1 + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB1 + 0x0800) +#define TIM5_BASE (PERIPH_BASE_APB1 + 0x0c00) +#define TIM6_BASE (PERIPH_BASE_APB1 + 0x1000) +#define TIM7_BASE (PERIPH_BASE_APB1 + 0x1400) +#define LCD_BASE (PERIPH_BASE_APB1 + 0x2400) +#define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) +/* PERIPH_BASE_APB1 + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ +#define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) +// datasheet has an error? here +#define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) +/* PERIPH_BASE_APB1 + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */ +#define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) +#define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) +#define USART4_BASE (PERIPH_BASE_APB1 + 0x4c00) +#define USART5_BASE (PERIPH_BASE_APB1 + 0x5000) +#define I2C1_BASE (PERIPH_BASE_APB1 + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB1 + 0x5800) +#define USB_DEV_FS_BASE (PERIPH_BASE_APB1 + 0x5c00) +#define USB_SRAM_BASE (PERIPH_BASE_APB1 + 0x6000) +/* gap */ +#define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define COMP_BASE (PERIPH_BASE_APB1 + 0x7c00) +#define ROUTING_BASE (PERIPH_BASE_APB1 + 0x7c04) + +/* APB2 */ +#define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x0000) +#define EXTI_BASE (PERIPH_BASE_APB2 + 0x0400) +#define TIM9_BASE (PERIPH_BASE_APB2 + 0x0800) +#define TIM10_BASE (PERIPH_BASE_APB2 + 0x0c00) +#define TIM11_BASE (PERIPH_BASE_APB2 + 0x1000) +/* gap */ +#define ADC_BASE (PERIPH_BASE_APB2 + 0x2400) +/* gap */ +#define SDIO_BASE (PERIPH_BASE_APB2 + 0x2c00) +#define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) +/* gap */ +#define USART1_BASE (PERIPH_BASE_APB2 + 0x3800) + +/* AHB */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB + 0x00000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB + 0x00400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB + 0x00800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB + 0x00c00) +#define GPIO_PORT_E_BASE (PERIPH_BASE_AHB + 0x01000) +#define GPIO_PORT_H_BASE (PERIPH_BASE_AHB + 0x01400) +/* gap */ +#define CRC_BASE (PERIPH_BASE_AHB + 0x03000) +/* gap */ +#define RCC_BASE (PERIPH_BASE_AHB + 0x03800) +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB + 0x03c00) +/* gap */ +#define DMA_BASE (PERIPH_BASE_AHB + 0x06000) + +/* PPIB */ +#define DBGMCU_BASE (PPBI_BASE + 0x00042000) + +/* FSMC */ +#define FSMC_BASE (PERIPH_BASE + 0x60000000) +/* AES */ +#define AES_BASE (PERIPH_BASE + 0x10000000) + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x8004C) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x80050) + +#endif diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h new file mode 100644 index 00000000..209d24f6 --- /dev/null +++ b/include/libopencm3/stm32/l1/rcc.h @@ -0,0 +1,408 @@ +/** @file + +@ingroup STM32L1xx + +@brief <b>libopencm3 STM32L1xx Reset and Clock Control</b> + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Federico Ruiz-Ugalde \<memeruiz at gmail dot com\> +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann <uwe@hermann-uwe.de> +@author @htmlonly © @endhtmlonly 2012 Karl Palsson <karlp@tweak.net.au> + +@date 18 May 2012 + +LGPL License Terms @ref lgpl_license + */ +/** @defgroup STM32L1xx_rcc_defines + +@brief Defined Constants and Types for the STM32L1xx Reset and Clock Control + +@ingroup STM32L1xx_defines + +LGPL License Terms @ref lgpl_license + + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * Copyright (C) 2009 Federico Ruiz-Ugalde <memeruiz at gmail dot com> + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Originally based on the F1 code, as it seemed most similar to the L1 + * TODO: very incomplete still! + */ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +#include <libopencm3/stm32/memorymap.h> +#include <libopencm3/cm3/common.h> + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_ICSCR MMIO32(RCC_BASE + 0x04) +#define RCC_CFGR MMIO32(RCC_BASE + 0x08) +#define RCC_CIR MMIO32(RCC_BASE + 0x0c) +#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x10) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x14) +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x18) +#define RCC_AHBENR MMIO32(RCC_BASE + 0x1c) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x20) +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x24) +#define RCC_AHBLPENR MMIO32(RCC_BASE + 0x28) +#define RCC_APB2LPENR MMIO32(RCC_BASE + 0x2c) +#define RCC_APB1LPENR MMIO32(RCC_BASE + 0x30) +#define RCC_CSR MMIO32(RCC_BASE + 0x34) + +/* --- RCC_CR values ------------------------------------------------------- */ + +/* RTCPRE[1:0] at 30:29 */ +#define RCC_CR_CSSON (1 << 28) +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_MSIRDY (1 << 9) +#define RCC_CR_MSION (1 << 8) +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +#define RCC_CR_RTCPRE_DIV2 0 +#define RCC_CR_RTCPRE_DIV4 1 +#define RCC_CR_RTCPRE_DIV8 2 +#define RCC_CR_RTCPRE_DIV18 3 + +/* --- RCC_ICSCR values ---------------------------------------------------- */ + +// TODO + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +/* MCOPRE */ +#define RCC_CFGR_MCOPRE_DIV1 0 +#define RCC_CFGR_MCOPRE_DIV2 1 +#define RCC_CFGR_MCOPRE_DIV4 2 +#define RCC_CFGR_MCOPRE_DIV8 3 +#define RCC_CFGR_MCOPRE_DIV16 4 + +/* MCO: Microcontroller clock output */ +#define RCC_CFGR_MCO_NOCLK 0x0 +#define RCC_CFGR_MCO_SYSCLK 0x1 +#define RCC_CFGR_MCO_HSICLK 0x2 +#define RCC_CFGR_MCO_MSICLK 0x3 +#define RCC_CFGR_MCO_HSECLK 0x4 +#define RCC_CFGR_MCO_PLLCLK 0x5 +#define RCC_CFGR_MCO_LSICLK 0x6 +#define RCC_CFGR_MCO_LSECLK 0x7 + +/* PLL Output division selection */ +#define RCC_CFGR_PLLDIV_DIV2 0x1 +#define RCC_CFGR_PLLDIV_DIV3 0x2 +#define RCC_CFGR_PLLDIV_DIV4 0x3 + +/* PLLMUL: PLL multiplication factor */ +#define RCC_CFGR_PLLMUL_MUL3 0x0 +#define RCC_CFGR_PLLMUL_MUL4 0x1 +#define RCC_CFGR_PLLMUL_MUL6 0x2 +#define RCC_CFGR_PLLMUL_MUL8 0x3 +#define RCC_CFGR_PLLMUL_MUL12 0x4 +#define RCC_CFGR_PLLMUL_MUL16 0x5 +#define RCC_CFGR_PLLMUL_MUL24 0x6 +#define RCC_CFGR_PLLMUL_MUL32 0x7 +#define RCC_CFGR_PLLMUL_MUL48 0x8 + +/* PLLSRC: PLL entry clock source */ +#define RCC_CFGR_PLLSRC_HSI_CLK 0x0 +#define RCC_CFGR_PLLSRC_HSE_CLK 0x1 + +/* PPRE2: APB high-speed prescaler (APB2) */ +#define RCC_CFGR_PPRE2_HCLK_NODIV 0x0 +#define RCC_CFGR_PPRE2_HCLK_DIV2 0x4 +#define RCC_CFGR_PPRE2_HCLK_DIV4 0x5 +#define RCC_CFGR_PPRE2_HCLK_DIV8 0x6 +#define RCC_CFGR_PPRE2_HCLK_DIV16 0x7 + +/* PPRE1: APB low-speed prescaler (APB1) */ +#define RCC_CFGR_PPRE1_HCLK_NODIV 0x0 +#define RCC_CFGR_PPRE1_HCLK_DIV2 0x4 +#define RCC_CFGR_PPRE1_HCLK_DIV4 0x5 +#define RCC_CFGR_PPRE1_HCLK_DIV8 0x6 +#define RCC_CFGR_PPRE1_HCLK_DIV16 0x7 + +/* HPRE: AHB prescaler */ +#define RCC_CFGR_HPRE_SYSCLK_NODIV 0x0 +#define RCC_CFGR_HPRE_SYSCLK_DIV2 0x8 +#define RCC_CFGR_HPRE_SYSCLK_DIV4 0x9 +#define RCC_CFGR_HPRE_SYSCLK_DIV8 0xa +#define RCC_CFGR_HPRE_SYSCLK_DIV16 0xb +#define RCC_CFGR_HPRE_SYSCLK_DIV64 0xc +#define RCC_CFGR_HPRE_SYSCLK_DIV128 0xd +#define RCC_CFGR_HPRE_SYSCLK_DIV256 0xe +#define RCC_CFGR_HPRE_SYSCLK_DIV512 0xf + +/* SWS: System clock switch status */ +#define RCC_CFGR_SWS_SYSCLKSEL_MSICLK 0x0 +#define RCC_CFGR_SWS_SYSCLKSEL_HSICLK 0x1 +#define RCC_CFGR_SWS_SYSCLKSEL_HSECLK 0x2 +#define RCC_CFGR_SWS_SYSCLKSEL_PLLCLK 0x3 + +/* SW: System clock switch */ +#define RCC_CFGR_SW_SYSCLKSEL_MSICLK 0x0 +#define RCC_CFGR_SW_SYSCLKSEL_HSICLK 0x1 +#define RCC_CFGR_SW_SYSCLKSEL_HSECLK 0x2 +#define RCC_CFGR_SW_SYSCLKSEL_PLLCLK 0x3 + +/* --- RCC_CIR values ------------------------------------------------------ */ + +/* Clock security system interrupt clear bit */ +#define RCC_CIR_CSSC (1 << 23) + +/* OSC ready interrupt clear bits */ +#define RCC_CIR_MSIRDYC (1 << 21) +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) + +/* OSC ready interrupt enable bits */ +#define RCC_CIR_MSIRDYIE (1 << 13) +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) + +/* Clock security system interrupt flag bit */ +#define RCC_CIR_CSSF (1 << 7) + +/* OSC ready interrupt flag bits */ +#define RCC_CIR_MSIRDYF (1 << 5) /* (**) */ +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_AHBRSTR values ------------------------------------------------- */ +#define RCC_AHBRSTR_DMA1RST (1 << 24) +#define RCC_AHBRSTR_FLITFRST (1 << 15) +#define RCC_AHBRSTR_CRCRST (1 << 12) +#define RCC_AHBRSTR_GPIOHRST (1 << 5) +#define RCC_AHBRSTR_GPIOERST (1 << 4) +#define RCC_AHBRSTR_GPIODRST (1 << 3) +#define RCC_AHBRSTR_GPIOCRST (1 << 2) +#define RCC_AHBRSTR_GPIOBRST (1 << 1) +#define RCC_AHBRSTR_GPIOARST (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_USART1RST (1 << 14) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_ADC1RST (1 << 9) +#define RCC_APB2RSTR_TIM11RST (1 << 4) +#define RCC_APB2RSTR_TIM10RST (1 << 3) +#define RCC_APB2RSTR_TIM9RST (1 << 2) +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_COMPRST (1 << 31) +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_USBRST (1 << 23) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_USART3RST (1 << 18) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_LCDRST (1 << 9) +#define RCC_APB1RSTR_TIM7RST (1 << 5) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM4RST (1 << 2) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_AHBENR values --------------------------------------------------- */ + +/** @defgroup rcc_ahbenr_en RCC_AHBENR enable values +@ingroup STM32L1xx_rcc_defines + +@{*/ +#define RCC_AHBENR_DMA1EN (1 << 24) +#define RCC_AHBENR_FLITFEN (1 << 15) +#define RCC_AHBENR_CRCEN (1 << 12) +#define RCC_AHBENR_GPIOHEN (1 << 5) +#define RCC_AHBENR_GPIOEEN (1 << 4) +#define RCC_AHBENR_GPIODEN (1 << 3) +#define RCC_AHBENR_GPIOCEN (1 << 2) +#define RCC_AHBENR_GPIOBEN (1 << 1) +#define RCC_AHBENR_GPIOAEN (1 << 0) +/*@}*/ + +/* --- RCC_APB2ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values +@ingroup STM32L1xx_rcc_defines + +@{*/ +#define RCC_APB2ENR_USART1EN (1 << 14) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_ADC1EN (1 << 9) +#define RCC_APB2ENR_TIM11EN (1 << 4) +#define RCC_APB2ENR_TIM10EN (1 << 3) +#define RCC_APB2ENR_TIM9EN (1 << 2) +#define RCC_APB2ENR_SYSCFGEN (1 << 0) +/*@}*/ + +/* --- RCC_APB1ENR values -------------------------------------------------- */ + +/** @defgroup rcc_apb1enr_en RCC_APB1ENR enable values +@ingroup STM32L1xx_rcc_defines + +@{*/ +#define RCC_APB1ENR_COMPEN (1 << 31) +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_USBEN (1 << 23) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_USART3EN (1 << 18) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_LCDEN (1 << 9) +#define RCC_APB1ENR_TIM7EN (1 << 5) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM4EN (1 << 2) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) +/*@}*/ + +/* --- RCC_AHBLPENR -------------------------------------------------------- */ +#define RCC_AHBLPENR_DMA1LPEN (1 << 24) +#define RCC_AHBLPENR_SRAMLPEN (1 << 16) +#define RCC_AHBLPENR_FLITFLPEN (1 << 15) +#define RCC_AHBLPENR_CRCLPEN (1 << 12) +#define RCC_AHBLPENR_GPIOHLPEN (1 << 5) +#define RCC_AHBLPENR_GPIOELPEN (1 << 4) +#define RCC_AHBLPENR_GPIODLPEN (1 << 3) +#define RCC_AHBLPENR_GPIOCLPEN (1 << 2) +#define RCC_AHBLPENR_GPIOBLPEN (1 << 1) +#define RCC_AHBLPENR_GPIOALPEN (1 << 0) + +#define RCC_APB2LPENR_USART1LPEN (1 << 14) +#define RCC_APB2LPENR_SPI1LPEN (1 << 12) +#define RCC_APB2LPENR_ADC1LPEN (1 << 9) +#define RCC_APB2LPENR_TIM11LPEN (1 << 4) +#define RCC_APB2LPENR_TIM10LPEN (1 << 3) +#define RCC_APB2LPENR_TIM9LPEN (1 << 2) +#define RCC_APB2LPENR_SYSCFGLPEN (1 << 0) + +#define RCC_APB1LPENR_COMPLPEN (1 << 31) +#define RCC_APB1LPENR_DACLPEN (1 << 29) +#define RCC_APB1LPENR_PWRLPEN (1 << 28) +#define RCC_APB1LPENR_USBLPEN (1 << 23) +#define RCC_APB1LPENR_I2C2LPEN (1 << 22) +#define RCC_APB1LPENR_I2C1LPEN (1 << 21) +#define RCC_APB1LPENR_USART3LPEN (1 << 18) +#define RCC_APB1LPENR_USART2LPEN (1 << 17) +#define RCC_APB1LPENR_SPI2LPEN (1 << 14) +#define RCC_APB1LPENR_WWDGLPEN (1 << 11) +#define RCC_APB1LPENR_LCDLPEN (1 << 9) +#define RCC_APB1LPENR_TIM7LPEN (1 << 5) +#define RCC_APB1LPENR_TIM6LPEN (1 << 4) +#define RCC_APB1LPENR_TIM4LPEN (1 << 2) +#define RCC_APB1LPENR_TIM3LPEN (1 << 1) +#define RCC_APB1LPENR_TIM2LPEN (1 << 0) + + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_OBLRSTF (1 << 25) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_RTCRST (1 << 23) +#define RCC_CSR_RTCEN (1 << 22) +/* RTCSEL[1:0] */ +#define RCC_CSR_LSEBYP (1 << 10) +#define RCC_CSR_LSERDY (1 << 9) +#define RCC_CSR_LSEON (1 << 8) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + + +/* --- Variable definitions ------------------------------------------------ */ +extern u32 rcc_ppre1_frequency; +extern u32 rcc_ppre2_frequency; + +/* --- Function prototypes ------------------------------------------------- */ + +typedef enum { + PLL, HSE, HSI, MSI, LSE, LSI +} osc_t; + +void rcc_osc_ready_int_clear(osc_t osc); +void rcc_osc_ready_int_enable(osc_t osc); +void rcc_osc_ready_int_disable(osc_t osc); +int rcc_osc_ready_int_flag(osc_t osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_wait_for_osc_ready(osc_t osc); +void rcc_osc_on(osc_t osc); +void rcc_osc_off(osc_t osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_osc_bypass_enable(osc_t osc); +void rcc_osc_bypass_disable(osc_t osc); +void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en); +void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en); +void rcc_peripheral_reset(volatile u32 *reg, u32 reset); +void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset); +void rcc_set_sysclk_source(u32 clk); +void rcc_set_pll_multiplication_factor(u32 mul); +void rcc_set_pll_source(u32 pllsrc); +void rcc_set_pllxtpre(u32 pllxtpre); +void rcc_set_adcpre(u32 adcpre); +void rcc_set_ppre2(u32 ppre2); +void rcc_set_ppre1(u32 ppre1); +void rcc_set_hpre(u32 hpre); +void rcc_set_usbpre(u32 usbpre); +u32 rcc_get_system_clock_source(int i); +void rcc_clock_setup_in_hsi_out_64mhz(void); +void rcc_clock_setup_in_hsi_out_48mhz(void); + +/** + * Maximum speed possible for F100 (Value Line) on HSI + */ +void rcc_clock_setup_in_hsi_out_24mhz(void); +void rcc_clock_setup_in_hse_8mhz_out_24mhz(void); +void rcc_clock_setup_in_hse_8mhz_out_72mhz(void); +void rcc_clock_setup_in_hse_12mhz_out_72mhz(void); +void rcc_clock_setup_in_hse_16mhz_out_72mhz(void); +void rcc_backupdomain_reset(void); + +#endif diff --git a/include/libopencm3/stm32/memorymap.h b/include/libopencm3/stm32/memorymap.h index 6f213daa..9b757cee 100644 --- a/include/libopencm3/stm32/memorymap.h +++ b/include/libopencm3/stm32/memorymap.h @@ -26,6 +26,8 @@ # include <libopencm3/stm32/f2/memorymap.h> #elif defined(STM32F4) # include <libopencm3/stm32/f4/memorymap.h> +#elif defined(STM32L1) +# include <libopencm3/stm32/l1/memorymap.h> #else # error "stm32 family not defined." #endif diff --git a/include/libopencm3/stm32/otg_fs.h b/include/libopencm3/stm32/otg_fs.h index 5680e432..d8ee3938 100644 --- a/include/libopencm3/stm32/otg_fs.h +++ b/include/libopencm3/stm32/otg_fs.h @@ -24,7 +24,7 @@ #include <libopencm3/cm3/common.h> /* Core Global Control and Status Registers */ -#define OTG_FS_OTGCTL MMIO32(USB_OTG_FS_BASE + 0x000) +#define OTG_FS_GOTGCTL MMIO32(USB_OTG_FS_BASE + 0x000) #define OTG_FS_GOTGINT MMIO32(USB_OTG_FS_BASE + 0x004) #define OTG_FS_GAHBCFG MMIO32(USB_OTG_FS_BASE + 0x008) #define OTG_FS_GUSBCFG MMIO32(USB_OTG_FS_BASE + 0x00C) @@ -42,40 +42,40 @@ #define OTG_FS_DIEPTXF(x) MMIO32(USB_OTG_FS_BASE + 0x104 + 4*(x-1)) /* Host-mode Control and Status Registers */ -#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400) -#define OTG_FS_HFIR MMIO32(USB_OTG_FS_BASE + 0x404) -#define OTG_FS_HFNUM MMIO32(USB_OTG_FS_BASE + 0x408) -#define OTG_FS_HPTXSTS MMIO32(USB_OTG_FS_BASE + 0x410) -#define OTG_FS_HAINT MMIO32(USB_OTG_FS_BASE + 0x414) -#define OTG_FS_HAINTMSK MMIO32(USB_OTG_FS_BASE + 0x418) -#define OTG_FS_HPRT MMIO32(USB_OTG_FS_BASE + 0x440) -#define OTG_FS_HCCHARx MMIO32(USB_OTG_FS_BASE + 0x500) -#define OTG_FS_HCINTx MMIO32(USB_OTG_FS_BASE + 0x508) -#define OTG_FS_HCINTMSKx MMIO32(USB_OTG_FS_BASE + 0x50C) -#define OTG_FS_HCTSIZx MMIO32(USB_OTG_FS_BASE + 0x510) +#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400) +#define OTG_FS_HFIR MMIO32(USB_OTG_FS_BASE + 0x404) +#define OTG_FS_HFNUM MMIO32(USB_OTG_FS_BASE + 0x408) +#define OTG_FS_HPTXSTS MMIO32(USB_OTG_FS_BASE + 0x410) +#define OTG_FS_HAINT MMIO32(USB_OTG_FS_BASE + 0x414) +#define OTG_FS_HAINTMSK MMIO32(USB_OTG_FS_BASE + 0x418) +#define OTG_FS_HPRT MMIO32(USB_OTG_FS_BASE + 0x440) +#define OTG_FS_HCCHARx MMIO32(USB_OTG_FS_BASE + 0x500) +#define OTG_FS_HCINTx MMIO32(USB_OTG_FS_BASE + 0x508) +#define OTG_FS_HCINTMSKx MMIO32(USB_OTG_FS_BASE + 0x50C) +#define OTG_FS_HCTSIZx MMIO32(USB_OTG_FS_BASE + 0x510) /* Device-mode Control and Status Registers */ -#define OTG_FS_DCFG MMIO32(USB_OTG_FS_BASE + 0x800) -#define OTG_FS_DCTL MMIO32(USB_OTG_FS_BASE + 0x804) -#define OTG_FS_DSTS MMIO32(USB_OTG_FS_BASE + 0x808) -#define OTG_FS_DIEPMSK MMIO32(USB_OTG_FS_BASE + 0x810) -#define OTG_FS_DOEPMSK MMIO32(USB_OTG_FS_BASE + 0x814) -#define OTG_FS_DAINT MMIO32(USB_OTG_FS_BASE + 0x818) -#define OTG_FS_DAINTMSK MMIO32(USB_OTG_FS_BASE + 0x81C) -#define OTG_FS_DVBUSDIS MMIO32(USB_OTG_FS_BASE + 0x828) -#define OTG_FS_DVBUSPULSE MMIO32(USB_OTG_FS_BASE + 0x82C) -#define OTG_FS_DIEPEMPMSK MMIO32(USB_OTG_FS_BASE + 0x834) -#define OTG_FS_DIEPCTL0 MMIO32(USB_OTG_FS_BASE + 0x900) -#define OTG_FS_DIEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0x900 + 0x20*(x)) -#define OTG_FS_DOEPCTL0 MMIO32(USB_OTG_FS_BASE + 0xB00) -#define OTG_FS_DOEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0xB00 + 0x20*(x)) -#define OTG_FS_DIEPINT(x) MMIO32(USB_OTG_FS_BASE + 0x908 + 0x20*(x)) -#define OTG_FS_DOEPINT(x) MMIO32(USB_OTG_FS_BASE + 0xB08 + 0x20*(x)) -#define OTG_FS_DIEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0x910) -#define OTG_FS_DOEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0xB10) -#define OTG_FS_DIEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0x910 + 0x20*(x)) -#define OTG_FS_DTXFSTS(x) MMIO32(USB_OTG_FS_BASE + 0x918 + 0x20*(x)) -#define OTG_FS_DOEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0xB10 + 0x20*(x)) +#define OTG_FS_DCFG MMIO32(USB_OTG_FS_BASE + 0x800) +#define OTG_FS_DCTL MMIO32(USB_OTG_FS_BASE + 0x804) +#define OTG_FS_DSTS MMIO32(USB_OTG_FS_BASE + 0x808) +#define OTG_FS_DIEPMSK MMIO32(USB_OTG_FS_BASE + 0x810) +#define OTG_FS_DOEPMSK MMIO32(USB_OTG_FS_BASE + 0x814) +#define OTG_FS_DAINT MMIO32(USB_OTG_FS_BASE + 0x818) +#define OTG_FS_DAINTMSK MMIO32(USB_OTG_FS_BASE + 0x81C) +#define OTG_FS_DVBUSDIS MMIO32(USB_OTG_FS_BASE + 0x828) +#define OTG_FS_DVBUSPULSE MMIO32(USB_OTG_FS_BASE + 0x82C) +#define OTG_FS_DIEPEMPMSK MMIO32(USB_OTG_FS_BASE + 0x834) +#define OTG_FS_DIEPCTL0 MMIO32(USB_OTG_FS_BASE + 0x900) +#define OTG_FS_DIEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0x900 + 0x20*(x)) +#define OTG_FS_DOEPCTL0 MMIO32(USB_OTG_FS_BASE + 0xB00) +#define OTG_FS_DOEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0xB00 + 0x20*(x)) +#define OTG_FS_DIEPINT(x) MMIO32(USB_OTG_FS_BASE + 0x908 + 0x20*(x)) +#define OTG_FS_DOEPINT(x) MMIO32(USB_OTG_FS_BASE + 0xB08 + 0x20*(x)) +#define OTG_FS_DIEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0x910) +#define OTG_FS_DOEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0xB10) +#define OTG_FS_DIEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0x910 + 0x20*(x)) +#define OTG_FS_DTXFSTS(x) MMIO32(USB_OTG_FS_BASE + 0x918 + 0x20*(x)) +#define OTG_FS_DOEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0xB10 + 0x20*(x)) /* Power and clock gating control and status register */ #define OTG_FS_PCGCCTL MMIO32(USB_OTG_FS_BASE + 0xE00) @@ -84,6 +84,18 @@ #define OTG_FS_FIFO(x) ((volatile u32*)(USB_OTG_FS_BASE + (((x) + 1) << 12))) /* Global CSRs */ +/* OTG_FS USB control registers (OTG_HS_GOTGCTL) */ +#define OTG_FS_GOTGCTL_BSVLD (1 << 19) +#define OTG_FS_GOTGCTL_ASVLD (1 << 18) +#define OTG_FS_GOTGCTL_DBCT (1 << 17) +#define OTG_FS_GOTGCTL_CIDSTS (1 << 16) +#define OTG_FS_GOTGCTL_DHNPEN (1 << 11) +#define OTG_FS_GOTGCTL_HSHNPEN (1 << 10) +#define OTG_FS_GOTGCTL_HNPRQ (1 << 9) +#define OTG_FS_GOTGCTL_HNGSCS (1 << 8) +#define OTG_FS_GOTGCTL_SRQ (1 << 1) +#define OTG_FS_GOTGCTL_SRQSCS (1 << 0) + /* OTG_FS AHB configuration register (OTG_FS_GAHBCFG) */ #define OTG_FS_GAHBCFG_GINT 0x0001 #define OTG_FS_GAHBCFG_TXFELVL 0x0080 @@ -175,20 +187,20 @@ /* OTG_FS Receive Status Pop Register (OTG_FS_GRXSTSP) */ /* Bits 31:25 - Reserved */ -#define OTG_FS_GRXSTSP_FRMNUM_MASK (0xf << 21) -#define OTG_FS_GRXSTSP_PKTSTS_MASK (0xf << 17) -#define OTG_FS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17) -#define OTG_FS_GRXSTSP_PKTSTS_OUT (0x2 << 17) -#define OTG_FS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17) +#define OTG_FS_GRXSTSP_FRMNUM_MASK (0xf << 21) +#define OTG_FS_GRXSTSP_PKTSTS_MASK (0xf << 17) +#define OTG_FS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17) +#define OTG_FS_GRXSTSP_PKTSTS_OUT (0x2 << 17) +#define OTG_FS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17) #define OTG_FS_GRXSTSP_PKTSTS_SETUP_COMP (0x4 << 17) -#define OTG_FS_GRXSTSP_PKTSTS_SETUP (0x6 << 17) -#define OTG_FS_GRXSTSP_DPID_MASK (0x3 << 15) -#define OTG_FS_GRXSTSP_DPID_DATA0 (0x0 << 15) -#define OTG_FS_GRXSTSP_DPID_DATA1 (0x2 << 15) -#define OTG_FS_GRXSTSP_DPID_DATA2 (0x1 << 15) -#define OTG_FS_GRXSTSP_DPID_MDATA (0x3 << 15) -#define OTG_FS_GRXSTSP_BCNT_MASK (0x7ff << 4) -#define OTG_FS_GRXSTSP_EPNUM_MASK (0xf << 0) +#define OTG_FS_GRXSTSP_PKTSTS_SETUP (0x6 << 17) +#define OTG_FS_GRXSTSP_DPID_MASK (0x3 << 15) +#define OTG_FS_GRXSTSP_DPID_DATA0 (0x0 << 15) +#define OTG_FS_GRXSTSP_DPID_DATA1 (0x2 << 15) +#define OTG_FS_GRXSTSP_DPID_DATA2 (0x1 << 15) +#define OTG_FS_GRXSTSP_DPID_MDATA (0x3 << 15) +#define OTG_FS_GRXSTSP_BCNT_MASK (0x7ff << 4) +#define OTG_FS_GRXSTSP_EPNUM_MASK (0xf << 0) /* OTG_FS general core configuration register (OTG_FS_GCCFG) */ /* Bits 31:21 - Reserved */ @@ -320,4 +332,3 @@ #define OTG_FS_DIEPSIZ0_XFRSIZ_MASK (0x7f << 0) #endif - diff --git a/include/libopencm3/stm32/otg_hs.h b/include/libopencm3/stm32/otg_hs.h new file mode 100644 index 00000000..2f59ddd9 --- /dev/null +++ b/include/libopencm3/stm32/otg_hs.h @@ -0,0 +1,396 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBOPENCM3_OTG_HS_H +#define LIBOPENCM3_OTG_HS_H + +#include <libopencm3/stm32/memorymap.h> +#include <libopencm3/cm3/common.h> + +/* Core Global Control and Status Registers */ +#define OTG_GOTGCTL 0x000 +#define OTG_GOTGIN 0x004 +#define OTG_GAHBCFG 0x008 +#define OTG_GUSBCFG 0x00C +#define OTG_GRSTCTL 0x010 +#define OTG_GINTSTS 0x014 +#define OTG_GINTMSK 0x018 +#define OTG_GRXSTSR 0x01C +#define OTG_GRXSTSP 0x020 +#define OTG_GRXFSIZ 0x024 +#define OTG_GNPTXFSIZ 0x028 +#define OTG_GNPTXSTS 0x02C +#define OTG_GCCFG 0x038 +#define OTG_CID 0x03C +#define OTG_HPTXFSIZ 0x100 +#define OTG_DIEPTXF(x) (0x104 + 4*(x-1)) + +/* Host-mode Control and Status Registers */ +#define OTG_HCFG 0x400 +#define OTG_HFIR 0x404 +#define OTG_HFNUM 0x408 +#define OTG_HPTXSTS 0x410 +#define OTG_HAINT 0x414 +#define OTG_HAINTMSK 0x418 +#define OTG_HPRT 0x440 +#define OTG_HCCHARx 0x500 +#define OTG_HCINTx 0x508 +#define OTG_HCINTMSKx 0x50C +#define OTG_HCTSIZx 0x510 + +/* Device-mode Control and Status Registers */ +#define OTG_DCFG 0x800 +#define OTG_DCTL 0x804 +#define OTG_DSTS 0x808 +#define OTG_DIEPMSK 0x810 +#define OTG_DOEPMSK 0x814 +#define OTG_DAINT 0x818 +#define OTG_DAINTMSK 0x81C +#define OTG_DVBUSDIS 0x828 +#define OTG_DVBUSPULSE 0x82C +#define OTG_DIEPEMPMSK 0x834 +#define OTG_DIEPCTL0 0x900 +#define OTG_DIEPCTL(x) (0x900 + 0x20*(x)) +#define OTG_DOEPCTL0 0xB00 +#define OTG_DOEPCTL(x) (0xB00 + 0x20*(x)) +#define OTG_DIEPINT(x) (0x908 + 0x20*(x)) +#define OTG_DOEPINT(x) (0xB08 + 0x20*(x)) +#define OTG_DIEPTSIZ0 0x910 +#define OTG_DOEPTSIZ0 0xB10 +#define OTG_DIEPTSIZ(x) (0x910 + 0x20*(x)) +#define OTG_DTXFSTS(x) (0x918 + 0x20*(x)) +#define OTG_DOEPTSIZ(x) (0xB10 + 0x20*(x)) + +/* Power and clock gating control and status register */ +#define OTG_PCGCCTL 0xE00 + +/* Data FIFO */ +#define OTG_FIFO(x) (((x) + 1) << 12) + +/***********************************************************************/ + +/* Core Global Control and Status Registers */ +#define OTG_HS_GOTGCTL MMIO32(USB_OTG_HS_BASE + OTG_GOTGCTL) +#define OTG_HS_GOTGINT MMIO32(USB_OTG_HS_BASE + OTG_GOTGINT) +#define OTG_HS_GAHBCFG MMIO32(USB_OTG_HS_BASE + OTG_GAHBCFG) +#define OTG_HS_GUSBCFG MMIO32(USB_OTG_HS_BASE + OTG_GUSBCFG) +#define OTG_HS_GRSTCTL MMIO32(USB_OTG_HS_BASE + OTG_GRSTCTL) +#define OTG_HS_GINTSTS MMIO32(USB_OTG_HS_BASE + OTG_GINTSTS) +#define OTG_HS_GINTMSK MMIO32(USB_OTG_HS_BASE + OTG_GINTMSK) +#define OTG_HS_GRXSTSR MMIO32(USB_OTG_HS_BASE + OTG_GRXSTSR) +#define OTG_HS_GRXSTSP MMIO32(USB_OTG_HS_BASE + OTG_GRXSTSP) +#define OTG_HS_GRXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_GRXFSIZ) +#define OTG_HS_GNPTXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_GNPTXFSIZ) +#define OTG_HS_GNPTXSTS MMIO32(USB_OTG_HS_BASE + OTG_GNPTXSTS) +#define OTG_HS_GCCFG MMIO32(USB_OTG_HS_BASE + OTG_GCCFG) +#define OTG_HS_CID MMIO32(USB_OTG_HS_BASE + OTG_CID) +#define OTG_HS_HPTXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_HPTXFSIZ) +#define OTG_HS_DIEPTXF(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPTXF(x)) + +/* Host-mode Control and Status Registers */ +#define OTG_HS_HCFG MMIO32(USB_OTG_HS_BASE + OTG_HCFG) +#define OTG_HS_HFIR MMIO32(USB_OTG_HS_BASE + OTG_HFIR) +#define OTG_HS_HFNUM MMIO32(USB_OTG_HS_BASE + OTG_HFNUM) +#define OTG_HS_HPTXSTS MMIO32(USB_OTG_HS_BASE + OTG_HPTXSTS) +#define OTG_HS_HAINT MMIO32(USB_OTG_HS_BASE + OTG_HAINT) +#define OTG_HS_HAINTMSK MMIO32(USB_OTG_HS_BASE + OTG_HAINTMSK) +#define OTG_HS_HPRT MMIO32(USB_OTG_HS_BASE + OTG_HPRT) +#define OTG_HS_HCCHARx MMIO32(USB_OTG_HS_BASE + OTG_HCCHARx) +#define OTG_HS_HCINTx MMIO32(USB_OTG_HS_BASE + OTG_HCINTx) +#define OTG_HS_HCINTMSKx MMIO32(USB_OTG_HS_BASE + OTG_HCINTMSKx) +#define OTG_HS_HCTSIZx MMIO32(USB_OTG_HS_BASE + OTG_HCTSIZx) + +/* Device-mode Control and Status Registers */ +#define OTG_HS_DCFG MMIO32(USB_OTG_HS_BASE + OTG_DCFG) +#define OTG_HS_DCTL MMIO32(USB_OTG_HS_BASE + OTG_DCTL) +#define OTG_HS_DSTS MMIO32(USB_OTG_HS_BASE + OTG_DSTS) +#define OTG_HS_DIEPMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPMSK) +#define OTG_HS_DOEPMSK MMIO32(USB_OTG_HS_BASE + OTG_DOEPMSK) +#define OTG_HS_DAINT MMIO32(USB_OTG_HS_BASE + OTG_DAINT) +#define OTG_HS_DAINTMSK MMIO32(USB_OTG_HS_BASE + OTG_DAINTMSK) +#define OTG_HS_DVBUSDIS MMIO32(USB_OTG_HS_BASE + OTG_DVBUSDIS) +#define OTG_HS_DVBUSPULSE MMIO32(USB_OTG_HS_BASE + OTG_DVBUSPULSE) +#define OTG_HS_DIEPEMPMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPEMPMSK) +#define OTG_HS_DIEPCTL0 MMIO32(USB_OTG_HS_BASE + OTG_DIEPCTL0) +#define OTG_HS_DIEPCTL(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPCTL(x)) +#define OTG_HS_DOEPCTL0 MMIO32(USB_OTG_HS_BASE + OTG_DOEPCTL0) +#define OTG_HS_DOEPCTL(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPCTL(x)) +#define OTG_HS_DIEPINT(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPINT(x)) +#define OTG_HS_DOEPINT(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPINT(x)) +#define OTG_HS_DIEPTSIZ0 MMIO32(USB_OTG_HS_BASE + OTG_DIEPTSIZ0) +#define OTG_HS_DOEPTSIZ0 MMIO32(USB_OTG_HS_BASE + OTG_DOEPTSIZ0) +#define OTG_HS_DIEPTSIZ(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPTSIZ(x))) +#define OTG_HS_DTXFSTS(x) MMIO32(USB_OTG_HS_BASE + OTG_DTXFSTS(x)) +#define OTG_HS_DOEPTSIZ(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPTSIZ(x)) + +/* Power and clock gating control and status register */ +#define OTG_HS_PCGCCTL MMIO32(USB_OTG_HS_BASE + OTG_PCGCCTL) + +/* Data FIFO */ +#define OTG_HS_FIFO(x) ((volatile u32*)(USB_OTG_HS_BASE + OTG_FIFO(x))) + +/* Global CSRs */ +/* OTG_HS USB control registers (OTG_FS_GOTGCTL) */ +#define OTG_HS_GOTGCTL_BSVLD (1 << 19) +#define OTG_HS_GOTGCTL_ASVLD (1 << 18) +#define OTG_HS_GOTGCTL_DBCT (1 << 17) +#define OTG_HS_GOTGCTL_CIDSTS (1 << 16) +#define OTG_HS_GOTGCTL_DHNPEN (1 << 11) +#define OTG_HS_GOTGCTL_HSHNPEN (1 << 10) +#define OTG_HS_GOTGCTL_HNPRQ (1 << 9) +#define OTG_HS_GOTGCTL_HNGSCS (1 << 8) +#define OTG_HS_GOTGCTL_SRQ (1 << 1) +#define OTG_HS_GOTGCTL_SRQSCS (1 << 0) + +/* OTG_FS AHB configuration register (OTG_HS_GAHBCFG) */ +#define OTG_HS_GAHBCFG_GINT 0x0001 +#define OTG_HS_GAHBCFG_TXFELVL 0x0080 +#define OTG_HS_GAHBCFG_PTXFELVL 0x0100 + +/* OTG_FS USB configuration register (OTG_HS_GUSBCFG) */ +#define OTG_HS_GUSBCFG_TOCAL 0x00000003 +#define OTG_HS_GUSBCFG_SRPCAP 0x00000100 +#define OTG_HS_GUSBCFG_HNPCAP 0x00000200 +#define OTG_HS_GUSBCFG_TRDT_MASK (0xf << 10) +#define OTG_HS_GUSBCFG_TRDT_16BIT (0x5 << 10) +#define OTG_HS_GUSBCFG_TRDT_8BIT (0x9 << 10) +#define OTG_HS_GUSBCFG_NPTXRWEN 0x00004000 +#define OTG_HS_GUSBCFG_FHMOD 0x20000000 +#define OTG_HS_GUSBCFG_FDMOD 0x40000000 +#define OTG_HS_GUSBCFG_CTXPKT 0x80000000 +#define OTG_HS_GUSBCFG_PHYSEL (1 << 6) + +/* OTG_FS reset register (OTG_HS_GRSTCTL) */ +#define OTG_HS_GRSTCTL_AHBIDL (1 << 31) +/* Bits 30:11 - Reserved */ +#define OTG_HS_GRSTCTL_TXFNUM_MASK (0x1f << 6) +#define OTG_HS_GRSTCTL_TXFFLSH (1 << 5) +#define OTG_HS_GRSTCTL_RXFFLSH (1 << 4) +/* Bit 3 - Reserved */ +#define OTG_HS_GRSTCTL_FCRST (1 << 2) +#define OTG_HS_GRSTCTL_HSRST (1 << 1) +#define OTG_HS_GRSTCTL_CSRST (1 << 0) + +/* OTG_FS interrupt status register (OTG_HS_GINTSTS) */ +#define OTG_HS_GINTSTS_WKUPINT (1 << 31) +#define OTG_HS_GINTSTS_SRQINT (1 << 30) +#define OTG_HS_GINTSTS_DISCINT (1 << 29) +#define OTG_HS_GINTSTS_CIDSCHG (1 << 28) +/* Bit 27 - Reserved */ +#define OTG_HS_GINTSTS_PTXFE (1 << 26) +#define OTG_HS_GINTSTS_HCINT (1 << 25) +#define OTG_HS_GINTSTS_HPRTINT (1 << 24) +/* Bits 23:22 - Reserved */ +#define OTG_HS_GINTSTS_IPXFR (1 << 21) +#define OTG_HS_GINTSTS_INCOMPISOOUT (1 << 21) +#define OTG_HS_GINTSTS_IISOIXFR (1 << 20) +#define OTG_HS_GINTSTS_OEPINT (1 << 19) +#define OTG_HS_GINTSTS_IEPINT (1 << 18) +/* Bits 17:16 - Reserved */ +#define OTG_HS_GINTSTS_EOPF (1 << 15) +#define OTG_HS_GINTSTS_ISOODRP (1 << 14) +#define OTG_HS_GINTSTS_ENUMDNE (1 << 13) +#define OTG_HS_GINTSTS_USBRST (1 << 12) +#define OTG_HS_GINTSTS_USBSUSP (1 << 11) +#define OTG_HS_GINTSTS_ESUSP (1 << 10) +/* Bits 9:8 - Reserved */ +#define OTG_HS_GINTSTS_GONAKEFF (1 << 7) +#define OTG_HS_GINTSTS_GINAKEFF (1 << 6) +#define OTG_HS_GINTSTS_NPTXFE (1 << 5) +#define OTG_HS_GINTSTS_RXFLVL (1 << 4) +#define OTG_HS_GINTSTS_SOF (1 << 3) +#define OTG_HS_GINTSTS_OTGINT (1 << 2) +#define OTG_HS_GINTSTS_MMIS (1 << 1) +#define OTG_HS_GINTSTS_CMOD (1 << 0) + +/* OTG_FS interrupt mask register (OTG_HS_GINTMSK) */ +#define OTG_HS_GINTMSK_MMISM 0x00000002 +#define OTG_HS_GINTMSK_OTGINT 0x00000004 +#define OTG_HS_GINTMSK_SOFM 0x00000008 +#define OTG_HS_GINTMSK_RXFLVLM 0x00000010 +#define OTG_HS_GINTMSK_NPTXFEM 0x00000020 +#define OTG_HS_GINTMSK_GINAKEFFM 0x00000040 +#define OTG_HS_GINTMSK_GONAKEFFM 0x00000080 +#define OTG_HS_GINTMSK_ESUSPM 0x00000400 +#define OTG_HS_GINTMSK_USBSUSPM 0x00000800 +#define OTG_HS_GINTMSK_USBRST 0x00001000 +#define OTG_HS_GINTMSK_ENUMDNEM 0x00002000 +#define OTG_HS_GINTMSK_ISOODRPM 0x00004000 +#define OTG_HS_GINTMSK_EOPFM 0x00008000 +#define OTG_HS_GINTMSK_EPMISM 0x00020000 +#define OTG_HS_GINTMSK_IEPINT 0x00040000 +#define OTG_HS_GINTMSK_OEPINT 0x00080000 +#define OTG_HS_GINTMSK_IISOIXFRM 0x00100000 +#define OTG_HS_GINTMSK_IISOOXFRM 0x00200000 +#define OTG_HS_GINTMSK_IPXFRM 0x00200000 +#define OTG_HS_GINTMSK_PRTIM 0x01000000 +#define OTG_HS_GINTMSK_HCIM 0x02000000 +#define OTG_HS_GINTMSK_PTXFEM 0x04000000 +#define OTG_HS_GINTMSK_CIDSCHGM 0x10000000 +#define OTG_HS_GINTMSK_DISCINT 0x20000000 +#define OTG_HS_GINTMSK_SRQIM 0x40000000 +#define OTG_HS_GINTMSK_WUIM 0x80000000 + +/* OTG_FS Receive Status Pop Register (OTG_HS_GRXSTSP) */ +/* Bits 31:25 - Reserved */ +#define OTG_HS_GRXSTSP_FRMNUM_MASK (0xf << 21) +#define OTG_HS_GRXSTSP_PKTSTS_MASK (0xf << 17) +#define OTG_HS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17) +#define OTG_HS_GRXSTSP_PKTSTS_OUT (0x2 << 17) +#define OTG_HS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17) +#define OTG_HS_GRXSTSP_PKTSTS_SETUP_COMP (0x4 << 17) +#define OTG_HS_GRXSTSP_PKTSTS_SETUP (0x6 << 17) +#define OTG_HS_GRXSTSP_DPID_MASK (0x3 << 15) +#define OTG_HS_GRXSTSP_DPID_DATA0 (0x0 << 15) +#define OTG_HS_GRXSTSP_DPID_DATA1 (0x2 << 15) +#define OTG_HS_GRXSTSP_DPID_DATA2 (0x1 << 15) +#define OTG_HS_GRXSTSP_DPID_MDATA (0x3 << 15) +#define OTG_HS_GRXSTSP_BCNT_MASK (0x7ff << 4) +#define OTG_HS_GRXSTSP_EPNUM_MASK (0xf << 0) + +/* OTG_FS general core configuration register (OTG_HS_GCCFG) */ +/* Bits 31:21 - Reserved */ +#define OTG_HS_GCCFG_SOFOUTEN (1 << 20) +#define OTG_HS_GCCFG_VBUSBSEN (1 << 19) +#define OTG_HS_GCCFG_VBUSASEN (1 << 18) +/* Bit 17 - Reserved */ +#define OTG_HS_GCCFG_PWRDWN (1 << 16) +/* Bits 15:0 - Reserved */ + + +/* Device-mode CSRs */ +/* OTG_FS device control register (OTG_HS_DCTL) */ +/* Bits 31:12 - Reserved */ +#define OTG_HS_DCTL_POPRGDNE (1 << 11) +#define OTG_HS_DCTL_CGONAK (1 << 10) +#define OTG_HS_DCTL_SGONAK (1 << 9) +#define OTG_HS_DCTL_SGINAK (1 << 8) +#define OTG_HS_DCTL_TCTL_MASK (7 << 4) +#define OTG_HS_DCTL_GONSTS (1 << 3) +#define OTG_HS_DCTL_GINSTS (1 << 2) +#define OTG_HS_DCTL_SDIS (1 << 1) +#define OTG_HS_DCTL_RWUSIG (1 << 0) + +/* OTG_FS device configuration register (OTG_HS_DCFG) */ +#define OTG_HS_DCFG_DSPD 0x0003 +#define OTG_HS_DCFG_NZLSOHSK 0x0004 +#define OTG_HS_DCFG_DAD 0x07F0 +#define OTG_HS_DCFG_PFIVL 0x1800 + +/* OTG_FS Device IN Endpoint Common Interrupt Mask Register (OTG_HS_DIEPMSK) */ +/* Bits 31:10 - Reserved */ +#define OTG_HS_DIEPMSK_BIM (1 << 9) +#define OTG_HS_DIEPMSK_TXFURM (1 << 8) +/* Bit 7 - Reserved */ +#define OTG_HS_DIEPMSK_INEPNEM (1 << 6) +#define OTG_HS_DIEPMSK_INEPNMM (1 << 5) +#define OTG_HS_DIEPMSK_ITTXFEMSK (1 << 4) +#define OTG_HS_DIEPMSK_TOM (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_HS_DIEPMSK_EPDM (1 << 1) +#define OTG_HS_DIEPMSK_XFRCM (1 << 0) + +/* OTG_FS Device OUT Endpoint Common Interrupt Mask Register (OTG_HS_DOEPMSK) */ +/* Bits 31:10 - Reserved */ +#define OTG_HS_DOEPMSK_BOIM (1 << 9) +#define OTG_HS_DOEPMSK_OPEM (1 << 8) +/* Bit 7 - Reserved */ +#define OTG_HS_DOEPMSK_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_HS_DOEPMSK_OTEPDM (1 << 4) +#define OTG_HS_DOEPMSK_STUPM (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_HS_DOEPMSK_EPDM (1 << 1) +#define OTG_HS_DOEPMSK_XFRCM (1 << 0) + +/* OTG_FS Device Control IN Endpoint 0 Control Register (OTG_HS_DIEPCTL0) */ +#define OTG_HS_DIEPCTL0_EPENA (1 << 31) +#define OTG_HS_DIEPCTL0_EPDIS (1 << 30) +/* Bits 29:28 - Reserved */ +#define OTG_HS_DIEPCTLX_SD0PID (1 << 28) +#define OTG_HS_DIEPCTL0_SNAK (1 << 27) +#define OTG_HS_DIEPCTL0_CNAK (1 << 26) +#define OTG_HS_DIEPCTL0_TXFNUM_MASK (0xf << 22) +#define OTG_HS_DIEPCTL0_STALL (1 << 21) +/* Bit 20 - Reserved */ +#define OTG_HS_DIEPCTL0_EPTYP_MASK (0x3 << 18) +#define OTG_HS_DIEPCTL0_NAKSTS (1 << 17) +/* Bit 16 - Reserved */ +#define OTG_HS_DIEPCTL0_USBAEP (1 << 15) +/* Bits 14:2 - Reserved */ +#define OTG_HS_DIEPCTL0_MPSIZ_MASK (0x3 << 0) +#define OTG_HS_DIEPCTL0_MPSIZ_64 (0x0 << 0) +#define OTG_HS_DIEPCTL0_MPSIZ_32 (0x1 << 0) +#define OTG_HS_DIEPCTL0_MPSIZ_16 (0x2 << 0) +#define OTG_HS_DIEPCTL0_MPSIZ_8 (0x3 << 0) + +/* OTG_FS Device Control OUT Endpoint 0 Control Register (OTG_HS_DOEPCTL0) */ +#define OTG_HS_DOEPCTL0_EPENA (1 << 31) +#define OTG_HS_DOEPCTL0_EPDIS (1 << 30) +/* Bits 29:28 - Reserved */ +#define OTG_HS_DOEPCTLX_SD0PID (1 << 28) +#define OTG_HS_DOEPCTL0_SNAK (1 << 27) +#define OTG_HS_DOEPCTL0_CNAK (1 << 26) +/* Bits 25:22 - Reserved */ +#define OTG_HS_DOEPCTL0_STALL (1 << 21) +#define OTG_HS_DOEPCTL0_SNPM (1 << 20) +#define OTG_HS_DOEPCTL0_EPTYP_MASK (0x3 << 18) +#define OTG_HS_DOEPCTL0_NAKSTS (1 << 17) +/* Bit 16 - Reserved */ +#define OTG_HS_DOEPCTL0_USBAEP (1 << 15) +/* Bits 14:2 - Reserved */ +#define OTG_HS_DOEPCTL0_MPSIZ_MASK (0x3 << 0) +#define OTG_HS_DOEPCTL0_MPSIZ_64 (0x0 << 0) +#define OTG_HS_DOEPCTL0_MPSIZ_32 (0x1 << 0) +#define OTG_HS_DOEPCTL0_MPSIZ_16 (0x2 << 0) +#define OTG_HS_DOEPCTL0_MPSIZ_8 (0x3 << 0) + +/* OTG_FS Device IN Endpoint Interrupt Register (OTG_HS_DIEPINTx) */ +/* Bits 31:8 - Reserved */ +#define OTG_HS_DIEPINTX_TXFE (1 << 7) +#define OTG_HS_DIEPINTX_INEPNE (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_HS_DIEPINTX_ITTXFE (1 << 4) +#define OTG_HS_DIEPINTX_TOC (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_HS_DIEPINTX_EPDISD (1 << 1) +#define OTG_HS_DIEPINTX_XFRC (1 << 0) + +/* OTG_FS Device IN Endpoint Interrupt Register (OTG_HS_DOEPINTx) */ +/* Bits 31:7 - Reserved */ +#define OTG_HS_DOEPINTX_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_HS_DOEPINTX_OTEPDIS (1 << 4) +#define OTG_HS_DOEPINTX_STUP (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_HS_DOEPINTX_EPDISD (1 << 1) +#define OTG_HS_DOEPINTX_XFRC (1 << 0) + +/* OTG_FS Device OUT Endpoint 0 Transfer Size Regsiter (OTG_HS_DOEPTSIZ0) */ +/* Bit 31 - Reserved */ +#define OTG_HS_DIEPSIZ0_STUPCNT_1 (0x1 << 29) +#define OTG_HS_DIEPSIZ0_STUPCNT_2 (0x2 << 29) +#define OTG_HS_DIEPSIZ0_STUPCNT_3 (0x3 << 29) +#define OTG_HS_DIEPSIZ0_STUPCNT_MASK (0x3 << 29) +/* Bits 28:20 - Reserved */ +#define OTG_HS_DIEPSIZ0_PKTCNT (1 << 19) +/* Bits 18:7 - Reserved */ +#define OTG_HS_DIEPSIZ0_XFRSIZ_MASK (0x7f << 0) + +#endif diff --git a/include/libopencm3/stm32/f2/syscfg.h b/include/libopencm3/stm32/syscfg.h index 7426f16c..7426f16c 100644 --- a/include/libopencm3/stm32/f2/syscfg.h +++ b/include/libopencm3/stm32/syscfg.h diff --git a/include/libopencm3/usb/cdc.h b/include/libopencm3/usb/cdc.h index 4b549613..5036411f 100644 --- a/include/libopencm3/usb/cdc.h +++ b/include/libopencm3/usb/cdc.h @@ -112,7 +112,7 @@ struct usb_cdc_line_coding { /* Table 30: Class-Specific Notification Codes for PSTN subclasses */ /* ... */ -#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 /* ... */ /* Notification Structure */ diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index e4b35785..2e5b7fbb 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -24,10 +24,21 @@ BEGIN_DECLS + +enum usbd_request_return_codes { + USBD_REQ_NOTSUPP = 0, + USBD_REQ_HANDLED = 1, + USBD_REQ_NEXT_CALLBACK = 2, +}; + typedef struct _usbd_driver usbd_driver; +typedef struct _usbd_device usbd_device; + extern const usbd_driver stm32f103_usb_driver; extern const usbd_driver stm32f107_usb_driver; +extern const usbd_driver stm32f207_usb_driver; #define otgfs_usb_driver stm32f107_usb_driver +#define otghs_usb_driver stm32f207_usb_driver /* Static buffer for control transactions: * This is defined as weak in the library, applicaiton @@ -35,45 +46,56 @@ extern const usbd_driver stm32f107_usb_driver; extern u8 usbd_control_buffer[]; /* <usb.c> */ -extern int usbd_init(const usbd_driver *driver, - const struct usb_device_descriptor *dev, - const struct usb_config_descriptor *conf, - const char **strings); -extern void usbd_set_control_buffer_size(u16 size); - -extern void usbd_register_reset_callback(void (*callback)(void)); -extern void usbd_register_suspend_callback(void (*callback)(void)); -extern void usbd_register_resume_callback(void (*callback)(void)); -extern void usbd_register_sof_callback(void (*callback)(void)); - -typedef int (*usbd_control_callback)(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)); +extern usbd_device *usbd_init(const usbd_driver *driver, + const struct usb_device_descriptor *dev, + const struct usb_config_descriptor *conf, + const char **strings, int num_strings); + +extern void usbd_set_control_buffer_size(usbd_device *usbd_dev, u16 size); + +extern void usbd_register_reset_callback(usbd_device *usbd_dev, + void (*callback)(void)); +extern void usbd_register_suspend_callback(usbd_device *usbd_dev, + void (*callback)(void)); +extern void usbd_register_resume_callback(usbd_device *usbd_dev, + void (*callback)(void)); +extern void usbd_register_sof_callback(usbd_device *usbd_dev, + void (*callback)(void)); + +typedef int (*usbd_control_callback)(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, + struct usb_setup_data *req)); /* <usb_control.c> */ -extern int usbd_register_control_callback(u8 type, u8 type_mask, - usbd_control_callback callback); +extern int usbd_register_control_callback(usbd_device *usbd_dev, u8 type, + u8 type_mask, + usbd_control_callback callback); /* <usb_standard.c> */ -extern void usbd_register_set_config_callback(void (*callback)(u16 wValue)); +extern void usbd_register_set_config_callback(usbd_device *usbd_dev, + void (*callback)(usbd_device *usbd_dev, u16 wValue)); /* Functions to be provided by the hardware abstraction layer */ -extern void usbd_poll(void); -extern void usbd_disconnect(bool disconnected); +extern void usbd_poll(usbd_device *usbd_dev); +extern void usbd_disconnect(usbd_device *usbd_dev, bool disconnected); -extern void usbd_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback)(u8 ep)); +extern void usbd_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*callback)(usbd_device *usbd_dev, u8 ep)); -extern u16 usbd_ep_write_packet(u8 addr, const void *buf, u16 len); +extern u16 usbd_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len); -extern u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len); +extern u16 usbd_ep_read_packet(usbd_device *usbd_dev, u8 addr, + void *buf, u16 len); -extern void usbd_ep_stall_set(u8 addr, u8 stall); -extern u8 usbd_ep_stall_get(u8 addr); +extern void usbd_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall); +extern u8 usbd_ep_stall_get(usbd_device *usbd_dev, u8 addr); -extern void usbd_ep_nak_set(u8 addr, u8 nak); +extern void usbd_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak); /* Optional */ -extern void usbd_cable_connect(u8 on); +extern void usbd_cable_connect(usbd_device *usbd_dev, u8 on); END_DECLS diff --git a/include/libopencm3/usb/usbstd.h b/include/libopencm3/usb/usbstd.h index 8610fdbc..79082806 100644 --- a/include/libopencm3/usb/usbstd.h +++ b/include/libopencm3/usb/usbstd.h @@ -38,6 +38,9 @@ struct usb_setup_data { u16 wLength; } __attribute__((packed)); +/* Class Definition */ +#define USB_CLASS_VENDOR 0xFF + /* bmRequestType bit definitions */ #define USB_REQ_TYPE_IN 0x80 #define USB_REQ_TYPE_STANDARD 0x00 @@ -220,4 +223,7 @@ struct usb_iface_assoc_descriptor { #define USB_DT_INTERFACE_ASSOCIATION_SIZE \ sizeof(struct usb_iface_assoc_descriptor) +enum usb_language_id { + USB_LANGID_ENGLISH_US = 0x409, +}; #endif diff --git a/include/libopencmsis/core_cm3.h b/include/libopencmsis/core_cm3.h new file mode 100644 index 00000000..0a89381d --- /dev/null +++ b/include/libopencmsis/core_cm3.h @@ -0,0 +1,177 @@ +/* big fat FIXME: this should use a consistent structure, and reference + * functionality from libopencm3 instead of copypasting. + * + * particularly unimplemented features are FIXME'd extra + * */ + +/* the original core_cm3.h is nonfree by arm; this provides libopencm3 variant of the symbols efm32lib needs of CMSIS. */ + +#ifndef OPENCMSIS_CORECM3_H +#define OPENCMSIS_CORECM3_H + +#include <libopencm3/cm3/common.h> +#include <libopencm3/cm3/memorymap.h> +#include <libopencm3/cm3/systick.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/scb.h> + +/* needed by system_efm32.h:196, guessing */ +#define __INLINE inline +/* new since emlib 3.0 */ +#define __STATIC_INLINE static inline + +/* needed around efm32tg840f32.h:229. comparing the efm32lib definitions to the + * libopencm3 ones, "volatile" is all that's missing. */ +#define __IO volatile +#define __O volatile +#define __I volatile + +/* -> style access for what is defined in libopencm3/stm32/f1/scb.h / + * cm3/memorymap.h, as it's needed by efm32lib/inc/efm32_emu.h */ + +/* from cm3/scb.h */ +#define SCB_SCR_SLEEPDEEP_Msk SCB_SCR_SLEEPDEEP + +/* structure as in, for example, + * DeviceSupport/EnergyMicro/EFM32/efm32tg840f32.h, data from + * libopencm3/cm3/scb.h. FIXME incomplete. */ +typedef struct +{ + __IO uint32_t CPUID; + __IO uint32_t ICSR; + __IO uint32_t VTOR; + __IO uint32_t AIRCR; + __IO uint32_t SCR; + __IO uint32_t CCR; + __IO uint8_t SHPR[12]; /* FIXME: how is this properly indexed? */ + __IO uint32_t SHCSR; +} SCB_TypeDef; +#define SCB ((SCB_TypeDef *) SCB_BASE) + +/* needed by efm32_emu.h, guessing and taking the implementation used in + * lightswitch-interrupt.c */ +#define __WFI() __asm__("wfi") + +/* needed by efm32_cmu.h, probably it's just what gcc provides anyway */ +#define __CLZ(div) __builtin_clz(div) + +/* needed by efm32_aes.c. __builtin_bswap32 does the same thing as the rev instruction according to https://bugzilla.mozilla.org/show_bug.cgi?id=600106 */ +#define __REV(x) __builtin_bswap32(x) + +/* stubs for efm32_dbg.h */ +typedef struct +{ + uint32_t DHCSR; + uint32_t DEMCR; /* needed by efm32tg stk trace.c */ +} CoreDebug_TypeDef; +/* FIXME let's just hope writes to flash are protected */ +#define CoreDebug ((CoreDebug_TypeDef *) 0) +#define CoreDebug_DHCSR_C_DEBUGEN_Msk 0 +#define CoreDebug_DEMCR_TRCENA_Msk 0 + +/* stubs for efm32_dma */ + +static inline void NVIC_ClearPendingIRQ(uint8_t irqn) +{ + nvic_clear_pending_irq(irqn); +} +static inline void NVIC_EnableIRQ(uint8_t irqn) +{ + nvic_enable_irq(irqn); +} +static inline void NVIC_DisableIRQ(uint8_t irqn) +{ + nvic_disable_irq(irqn); +} + +/* stubs for efm32_int. FIXME: how do they do that? nvic documentation in the + * efm32 core manual doesn't tell anything of a global on/off switch */ + +#define __enable_irq() 1 +#define __disable_irq() 1 + +/* stubs for efm32_mpu FIXME */ + +#define SCB_SHCSR_MEMFAULTENA_Msk 0 + +typedef struct +{ + uint32_t CTRL; + uint32_t RNR; + uint32_t RBAR; + uint32_t RASR; +} MPU_TypeDef; +/* FIXME struct at NULL */ +#define MPU ((MPU_TypeDef *) 0) +#define MPU_CTRL_ENABLE_Msk 0 +#define MPU_RASR_XN_Pos 0 +#define MPU_RASR_AP_Pos 0 +#define MPU_RASR_TEX_Pos 0 +#define MPU_RASR_S_Pos 0 +#define MPU_RASR_C_Pos 0 +#define MPU_RASR_B_Pos 0 +#define MPU_RASR_SRD_Pos 0 +#define MPU_RASR_SIZE_Pos 0 +#define MPU_RASR_ENABLE_Pos 0 + +/* required for the blink example */ + +/* if if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1) ; + * configures the sys ticks to 1ms, then the argument to SysTick_Config + * describes how many cycles to wait between two systicks. + * + * the endless loop part looks like an "if it returns an error condition, + * rather loop here than continue"; every other solution would involve things + * that are dark magic to my understanding. + * + * implementation more or less copypasted from lib/stm32/systick.c, FIXME until + * the generic cm3 functionality is moved out from stm32 and can be used here + * easily (systick_set_reload, systick_interrupt_enable, systick_counter_enable + * and systick_set_clocksource). + * + * modified for CMSIS style array as the powertest example needs it. + * */ + +/* from d0002_efm32_cortex-m3_reference_manual.pdf section 4.4 */ +typedef struct +{ + uint32_t CTRL; + uint32_t LOAD; + uint32_t VAL; + uint32_t CALIB; +} SysTick_TypeDef; +#define SysTick ((SysTick_TypeDef *) SYS_TICK_BASE) + +static inline uint32_t SysTick_Config(uint32_t n_ticks) +{ + /* constant from systick_set_reload -- as this returns something that's + * not void, this is the only possible error condition */ + if (n_ticks & ~0x00FFFFFF) return 1; + + systick_set_reload(n_ticks); + systick_set_clocksource(true); + systick_interrupt_enable(); + systick_counter_enable(); + + return 0; +} + +/* stubs for efm32tg stk trace.c */ +typedef struct +{ + uint32_t LAR; + uint32_t TCR; +} ITM_TypeDef; +/* FIXME struct at NULL */ +#define ITM ((ITM_TypeDef *) 0) + +/* blink.h expects the isr for systicks to be named SysTick_Handler. with this, + * its Systick_Handler function gets renamed to the weak symbol exported by + * vector.c */ + +#define SysTick_Handler sys_tick_handler +/* FIXME: this needs to be done for all of the 14 hard vectors */ + +#include <libopencmsis/dispatch/irqhandlers.h> + +#endif diff --git a/include/libopencmsis/dispatch/irqhandlers.h b/include/libopencmsis/dispatch/irqhandlers.h new file mode 100644 index 00000000..65e071d7 --- /dev/null +++ b/include/libopencmsis/dispatch/irqhandlers.h @@ -0,0 +1,23 @@ +#if defined(STM32F1) +# include <libopencmsis/stm32/f1/irqhandlers.h> +#elif defined(STM32F2) +# include <libopencmsis/stm32/f2/irqhandlers.h> +#elif defined(STM32F4) +# include <libopencmsis/stm32/f4/irqhandlers.h> + +#elif defined(EFM32TG) +# include <libopencmsis/efm32/efm32tg/irqhandlers.h> +#elif defined(EFM32G) +# include <libopencmsis/efm32/efm32g/irqhandlers.h> +#elif defined(EFM32LG) +# include <libopencmsis/efm32/efm32lg/irqhandlers.h> +#elif defined(EFM32GG) +# include <libopencmsis/efm32/efm32gg/irqhandlers.h> + +#elif defined(LPC43XX) +# include <libopencmsis/lpc43xx/irqhandlers.h> + +#else +# warning"no chipset defined; user interrupts are not redirected" + +#endif diff --git a/lib/Makefile.include b/lib/Makefile.include index 9fbea244..6c25069d 100644 --- a/lib/Makefile.include +++ b/lib/Makefile.include @@ -23,6 +23,9 @@ ifneq ($(V),1) Q := @ endif +# common objects +OBJS += vector.o systick.o scb.o nvic.o assert.o + all: $(SRCLIBDIR)/$(LIBNAME).a $(SRCLIBDIR)/$(LIBNAME).a: $(SRCLIBDIR)/$(LIBNAME).ld $(OBJS) diff --git a/lib/stm32/nvic.c b/lib/cm3/nvic.c index 84fa6749..db187b36 100644 --- a/lib/stm32/nvic.c +++ b/lib/cm3/nvic.c @@ -1,31 +1,9 @@ -/** @defgroup STM32F_nvic_file NVIC - -@ingroup STM32F_files - -@brief <b>libopencm3 STM32F Nested Vectored Interrupt Controller</b> - -@version 1.0.0 - -@author @htmlonly © @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org> -@author @htmlonly © @endhtmlonly 2012 Fergus Noble <fergusnoble@gmail.com> - -@date 18 August 2012 - -The STM32F series provides up to 68 maskable user interrupts for the STM32F10x -series, and 87 for the STM32F2xx and STM32F4xx series. - -The NVIC registers are defined by the ARM standards but the STM32F series have some -additional limitations -@see Cortex-M3 Devices Generic User Guide -@see STM32F10xxx Cortex-M3 programming manual - -LGPL License Terms @ref lgpl_license -*/ /* * This file is part of the libopencm3 project. * * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> * Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com> + * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com> * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -40,10 +18,32 @@ LGPL License Terms @ref lgpl_license * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ +/** @defgroup CM3_nvic_file NVIC +@ingroup CM3_files + +@brief <b>libopencm3 Cortex Nested Vectored Interrupt Controller</b> + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org> +@author @htmlonly © @endhtmlonly 2012 Fergus Noble <fergusnoble@gmail.com> + +@date 18 August 2012 + +Cortex processors provide 14 cortex-defined interrupts (NMI, usage faults, +systicks etc.) and varying numbers of implementation defined interrupts +(typically peripherial interrupts and DMA). + +@see Cortex-M3 Devices Generic User Guide +@see STM32F10xxx Cortex-M3 programming manual + +LGPL License Terms @ref lgpl_license +*/ /**@{*/ -#include <libopencm3/stm32/nvic.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/cm3/scs.h> /*-----------------------------------------------------------------------------*/ /** @brief NVIC Enable Interrupt @@ -153,7 +153,18 @@ Control Register (SCB_AIRCR), as done in @ref scb_set_priority_grouping. void nvic_set_priority(u8 irqn, u8 priority) { - NVIC_IPR(irqn) = priority; + /* code from lpc43xx/nvic.c -- this is quite a hack and alludes to the + * negative interrupt numbers assigned to the system interrupts. better + * handling would mean signed integers. */ + if(irqn>=NVIC_IRQ_COUNT) + { + /* Cortex-M system interrupts */ + SCS_SHPR( (irqn&0xF)-4 ) = priority; + }else + { + /* Device specific interrupts */ + NVIC_IPR(irqn) = priority; + } } /*-----------------------------------------------------------------------------*/ @@ -171,4 +182,3 @@ void nvic_generate_software_interrupt(u16 irqn) NVIC_STIR |= irqn; } /**@}*/ - diff --git a/lib/stm32/f1/scb.c b/lib/cm3/scb.c index e59134e8..904bd7c1 100644 --- a/lib/stm32/f1/scb.c +++ b/lib/cm3/scb.c @@ -17,7 +17,7 @@ * along with this library. If not, see <http://www.gnu.org/licenses/>. */ -#include <libopencm3/stm32/f1/scb.h> +#include <libopencm3/cm3/scb.h> void scb_reset_core(void) { diff --git a/lib/stm32/systick.c b/lib/cm3/systick.c index 36077cc9..325ffff4 100644 --- a/lib/stm32/systick.c +++ b/lib/cm3/systick.c @@ -1,27 +1,8 @@ -/** @defgroup STM32F_systick_file SysTick - -@ingroup STM32F_files - -@brief <b>libopencm3 STM32Fxx System Tick Timer</b> - -@version 1.0.0 - -@author @htmlonly © @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org> - -@date 19 August 2012 - -This library supports the System Tick timer in the -STM32F series of ARM Cortex Microcontrollers by ST Microelectronics. - -The System Tick timer is part of the ARM Cortex core. It is a 24 bit -down counter that can be configured with an automatical reload value. - -LGPL License Terms @ref lgpl_license - */ /* * This file is part of the libopencm3 project. * * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> + * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com> * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -36,9 +17,28 @@ LGPL License Terms @ref lgpl_license * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ +/** @defgroup CM3_systick_file SysTick + +@ingroup CM3_files + +@brief <b>libopencm3 Cortex System Tick Timer</b> + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org> + +@date 19 August 2012 + +This library supports the System Tick timer in ARM Cortex Microcontrollers. + +The System Tick timer is part of the ARM Cortex core. It is a 24 bit +down counter that can be configured with an automatical reload value. + +LGPL License Terms @ref lgpl_license + */ /**@{*/ -#include <libopencm3/stm32/systick.h> +#include <libopencm3/cm3/systick.h> /*-----------------------------------------------------------------------------*/ /** @brief SysTick Set the Automatic Reload Value. @@ -135,5 +135,15 @@ u8 systick_get_countflag(void) else return 0; } + +/*-----------------------------------------------------------------------------*/ +/** @brief SysTick Get Calibration Value + +@returns Current calibration value +*/ +u32 systick_get_calib(void) +{ + return (STK_CALIB&0x00FFFFFF); +} /**@}*/ diff --git a/lib/lpc17xx/vector.c b/lib/cm3/vector.c index 518f5621..b049526b 100644 --- a/lib/lpc17xx/vector.c +++ b/lib/cm3/vector.c @@ -1,7 +1,8 @@ /* * This file is part of the libopencm3 project. * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> + * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>, + * Copyright (C) 2012 chrysn <chrysn@fsfe.org> * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -14,19 +15,26 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. + * along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#include <libopencm3/cm3/vector.h> + +/* load optional platform dependent initialization routines */ +#include "../dispatch/vector_chipset.c" +/* load the weak symbols for IRQ_HANDLERS */ +#include "../dispatch/vector_nvic.c" + #define WEAK __attribute__ ((weak)) /* Symbols exported by the linker script(s): */ extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; void main(void); -void reset_handler(void); void blocking_handler(void); void null_handler(void); +void WEAK reset_handler(void); void WEAK nmi_handler(void); void WEAK hard_fault_handler(void); void WEAK mem_manage_handler(void); @@ -37,27 +45,25 @@ void WEAK debug_monitor_handler(void); void WEAK pend_sv_handler(void); void WEAK sys_tick_handler(void); -/* TODO: Interrupt handler prototypes */ - __attribute__ ((section(".vectors"))) -void (*const vector_table[]) (void) = { - (void*)&_stack, /* Addr: 0x0000_0000 */ - reset_handler, /* Addr: 0x0000_0004 */ - nmi_handler, /* Addr: 0x0000_0008 */ - hard_fault_handler, /* Addr: 0x0000_000C */ - mem_manage_handler, /* Addr: 0x0000_0010 */ - bus_fault_handler, /* Addr: 0x0000_0014 */ - usage_fault_handler, /* Addr: 0x0000_0018 */ - 0, 0, 0, 0, /* Reserved Addr: 0x0000_001C - 0x0000_002B */ - sv_call_handler, /* Addr: 0x0000_002C */ - debug_monitor_handler, /* Addr: 0x0000_0030 */ - 0, /* Reserved Addr: 0x0000_00034 */ - pend_sv_handler, /* Addr: 0x0000_0038 */ - sys_tick_handler, /* Addr: 0x0000_003C */ +vector_table_t vector_table = { + .initial_sp_value = &_stack, + .reset = reset_handler, + .nmi = nmi_handler, + .hard_fault = hard_fault_handler, + .memory_manage_fault = mem_manage_handler, + .bus_fault = bus_fault_handler, + .usage_fault = usage_fault_handler, + .debug_monitor = debug_monitor_handler, + .sv_call = sv_call_handler, + .pend_sv = pend_sv_handler, + .systick = sys_tick_handler, + .irq = { + IRQ_HANDLERS + } }; - -void reset_handler(void) +void WEAK reset_handler(void) { volatile unsigned *src, *dest; @@ -69,6 +75,9 @@ void reset_handler(void) while (dest < &_ebss) *dest++ = 0; + /* might be provided by platform specific vector.c */ + pre_main(); + /* Call the application's entry point. */ main(); } @@ -92,4 +101,3 @@ void null_handler(void) #pragma weak debug_monitor_handler = null_handler #pragma weak pend_sv_handler = null_handler #pragma weak sys_tick_handler = null_handler -/* TODO: Interrupt handler weak aliases */ diff --git a/lib/dispatch/vector_chipset.c b/lib/dispatch/vector_chipset.c new file mode 100644 index 00000000..796276c0 --- /dev/null +++ b/lib/dispatch/vector_chipset.c @@ -0,0 +1,11 @@ +#if defined(STM32F4) +# include "../stm32/f4/vector_chipset.c" + +#elif defined(LPC43XX) +# include "../lpc43xx/vector_chipset.c" + +#else + +static void pre_main(void) {} + +#endif diff --git a/lib/dispatch/vector_nvic.c b/lib/dispatch/vector_nvic.c new file mode 100644 index 00000000..33104eb2 --- /dev/null +++ b/lib/dispatch/vector_nvic.c @@ -0,0 +1,34 @@ +#if defined(STM32F1) +# include "../stm32/f1/vector_nvic.c" +#elif defined(STM32F2) +# include "../stm32/f2/vector_nvic.c" +#elif defined(STM32F4) +# include "../stm32/f4/vector_nvic.c" +#elif defined(STM32L1) +# include "../stm32/l1/vector_nvic.c" + +#elif defined(EFM32TG) +# include "../efm32/efm32tg/vector_nvic.c" +#elif defined(EFM32G) +# include "../efm32/efm32g/vector_nvic.c" +#elif defined(EFM32LG) +# include "../efm32/efm32lg/vector_nvic.c" +#elif defined(EFM32GG) +# include "../efm32/efm32gg/vector_nvic.c" + +#elif defined(LPC13XX) +# include "../lpc13xx/vector_nvic.c" +#elif defined(LPC17XX) +# include "../lpc17xx/vector_nvic.c" +#elif defined(LPC43XX) +# include "../lpc43xx/vector_nvic.c" + +#elif defined(LM3S) +# include "../lm3s/vector_nvic.c" + +#else +# warning"no interrupts defined for chipset; not allocating space in the vector table" + +#define IRQ_HANDLERS + +#endif diff --git a/lib/efm32/efm32g/Makefile b/lib/efm32/efm32g/Makefile new file mode 100644 index 00000000..1dd44850 --- /dev/null +++ b/lib/efm32/efm32g/Makefile @@ -0,0 +1,38 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## Copyright (C) 2012 chrysn <chrysn@fsfe.org> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +LIBNAME = libopencm3_efm32g +FAMILY = EFM32G + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -D$(FAMILY) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../:../../cm3 + +include ../../Makefile.include + diff --git a/lib/efm32/efm32g/libopencm3_efm32g.ld b/lib/efm32/efm32g/libopencm3_efm32g.ld new file mode 100644 index 00000000..8ef5e426 --- /dev/null +++ b/lib/efm32/efm32g/libopencm3_efm32g.ld @@ -0,0 +1,79 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>, + * Copyright (C) 2012 chrysn <chrysn@fsfe.org> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + . = ORIGIN(rom); + + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + _etext = .; + } >rom + + . = ORIGIN(ram); + + .data : AT(_etext) { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support - discard it for now. + */ + /DISCARD/ : { *(.ARM.exidx) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/lib/efm32/efm32g/libopencm3_efm32g880f128.ld b/lib/efm32/efm32g/libopencm3_efm32g880f128.ld new file mode 100644 index 00000000..09c6fb0f --- /dev/null +++ b/lib/efm32/efm32g/libopencm3_efm32g880f128.ld @@ -0,0 +1,15 @@ +/* lengths from d011_efm32tg840_datasheet.pdf table 1.1, offset from + * d0034_efm32tg_reference_manual.pdf figure 5.2. + * + * the origins and memory structure are constant over all tinygeckos, but the + * MEMORY section requires the use of constants, and has thus to be duplicated + * over the chip variants. + * */ + +MEMORY +{ + rom (rx) : ORIGIN = 0, LENGTH = 128k + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16k +} + +INCLUDE libopencm3_efm32g.ld; diff --git a/lib/efm32/efm32gg/Makefile b/lib/efm32/efm32gg/Makefile new file mode 100644 index 00000000..24078592 --- /dev/null +++ b/lib/efm32/efm32gg/Makefile @@ -0,0 +1,38 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## Copyright (C) 2012 chrysn <chrysn@fsfe.org> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +LIBNAME = libopencm3_efm32gg +FAMILY = EFM32GG + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -D$(FAMILY) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../:../../cm3 + +include ../../Makefile.include + diff --git a/lib/efm32/efm32gg/libopencm3_efm32gg.ld b/lib/efm32/efm32gg/libopencm3_efm32gg.ld new file mode 100644 index 00000000..8ef5e426 --- /dev/null +++ b/lib/efm32/efm32gg/libopencm3_efm32gg.ld @@ -0,0 +1,79 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>, + * Copyright (C) 2012 chrysn <chrysn@fsfe.org> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + . = ORIGIN(rom); + + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + _etext = .; + } >rom + + . = ORIGIN(ram); + + .data : AT(_etext) { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support - discard it for now. + */ + /DISCARD/ : { *(.ARM.exidx) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/lib/efm32/efm32lg/Makefile b/lib/efm32/efm32lg/Makefile new file mode 100644 index 00000000..9b6343c0 --- /dev/null +++ b/lib/efm32/efm32lg/Makefile @@ -0,0 +1,38 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## Copyright (C) 2012 chrysn <chrysn@fsfe.org> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +LIBNAME = libopencm3_efm32lg +FAMILY = EFM32LG + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -D$(FAMILY) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../:../../cm3 + +include ../../Makefile.include + diff --git a/lib/efm32/efm32lg/libopencm3_efm32lg.ld b/lib/efm32/efm32lg/libopencm3_efm32lg.ld new file mode 100644 index 00000000..8ef5e426 --- /dev/null +++ b/lib/efm32/efm32lg/libopencm3_efm32lg.ld @@ -0,0 +1,79 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>, + * Copyright (C) 2012 chrysn <chrysn@fsfe.org> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + . = ORIGIN(rom); + + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + _etext = .; + } >rom + + . = ORIGIN(ram); + + .data : AT(_etext) { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support - discard it for now. + */ + /DISCARD/ : { *(.ARM.exidx) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/lib/efm32/efm32tg/Makefile b/lib/efm32/efm32tg/Makefile new file mode 100644 index 00000000..605438a0 --- /dev/null +++ b/lib/efm32/efm32tg/Makefile @@ -0,0 +1,38 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## Copyright (C) 2012 chrysn <chrysn@fsfe.org> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +LIBNAME = libopencm3_efm32tg +FAMILY = EFM32TG + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -D$(FAMILY) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../:../../cm3 + +include ../../Makefile.include + diff --git a/lib/efm32/efm32tg/libopencm3_efm32tg.ld b/lib/efm32/efm32tg/libopencm3_efm32tg.ld new file mode 100644 index 00000000..8ef5e426 --- /dev/null +++ b/lib/efm32/efm32tg/libopencm3_efm32tg.ld @@ -0,0 +1,79 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>, + * Copyright (C) 2012 chrysn <chrysn@fsfe.org> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Generic linker script for EFM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + . = ORIGIN(rom); + + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + _etext = .; + } >rom + + . = ORIGIN(ram); + + .data : AT(_etext) { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support - discard it for now. + */ + /DISCARD/ : { *(.ARM.exidx) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/lib/efm32/efm32tg/libopencm3_efm32tg840f32.ld b/lib/efm32/efm32tg/libopencm3_efm32tg840f32.ld new file mode 100644 index 00000000..2cb8daf0 --- /dev/null +++ b/lib/efm32/efm32tg/libopencm3_efm32tg840f32.ld @@ -0,0 +1,15 @@ +/* lengths from d011_efm32tg840_datasheet.pdf table 1.1, offset from + * d0034_efm32tg_reference_manual.pdf figure 5.2. + * + * the origins and memory structure are constant over all tinygeckos, but the + * MEMORY section requires the use of constants, and has thus to be duplicated + * over the chip variants. + * */ + +MEMORY +{ + rom (rx) : ORIGIN = 0, LENGTH = 32k + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4k +} + +INCLUDE libopencm3_efm32tg.ld; diff --git a/lib/lm3s/Makefile b/lib/lm3s/Makefile index e471a001..6fc814d4 100644 --- a/lib/lm3s/Makefile +++ b/lib/lm3s/Makefile @@ -25,7 +25,7 @@ CC = $(PREFIX)-gcc AR = $(PREFIX)-ar CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \ -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ - -ffunction-sections -fdata-sections -MD + -ffunction-sections -fdata-sections -MD -DLM3S # ARFLAGS = rcsv ARFLAGS = rcs OBJS = gpio.o vector.o assert.o diff --git a/lib/lm3s/vector.c b/lib/lm3s/vector.c deleted file mode 100644 index b7c92aef..00000000 --- a/lib/lm3s/vector.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#define WEAK __attribute__ ((weak)) - -/* Symbols exported by the linker script(s): */ -extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; - -void main(void); -void reset_handler(void); -void blocking_handler(void); -void null_handler(void); - -void WEAK nmi_handler(void); -void WEAK hard_fault_handler(void); -void WEAK mem_manage_handler(void); -void WEAK bus_fault_handler(void); -void WEAK usage_fault_handler(void); -void WEAK sv_call_handler(void); -void WEAK debug_monitor_handler(void); -void WEAK pend_sv_handler(void); -void WEAK sys_tick_handler(void); - -void WEAK gpioa_handler(void); -void WEAK gpiob_handler(void); -void WEAK gpioc_handler(void); -void WEAK gpiod_handler(void); -void WEAK gpioe_handler(void); -void WEAK uart0_handler(void); -void WEAK uart1_handler(void); -void WEAK ssi0_handler(void); -void WEAK i2c0_handler(void); -void WEAK pwm0_fault_handler(void); -void WEAK pwm0_0_handler(void); -void WEAK pwm0_1_handler(void); -void WEAK pwm0_2_handler(void); -void WEAK qei0_handler(void); -void WEAK adc0ss0_handler(void); -void WEAK adc0ss1_handler(void); -void WEAK adc0ss2_handler(void); -void WEAK adc0ss3_handler(void); -void WEAK watchdog_handler(void); -void WEAK timer0a_handler(void); -void WEAK timer0b_handler(void); -void WEAK timer1a_handler(void); -void WEAK timer1b_handler(void); -void WEAK timer2a_handler(void); -void WEAK timer2b_handler(void); -void WEAK comp0_handler(void); -void WEAK comp1_handler(void); -void WEAK comp2_handler(void); -void WEAK sysctl_handler(void); -void WEAK flash_handler(void); -void WEAK gpiof_handler(void); -void WEAK gpiog_handler(void); -void WEAK gpioh_handler(void); -void WEAK uart2_handler(void); -void WEAK ssi1_handler(void); -void WEAK timer3a_handler(void); -void WEAK timer3b_handler(void); -void WEAK i2c1_handler(void); -void WEAK qei1_handler(void); -void WEAK can0_handler(void); -void WEAK can1_handler(void); -void WEAK can2_handler(void); -void WEAK eth_handler(void); -void WEAK hibernate_handler(void); -void WEAK usb0_handler(void); -void WEAK pwm0_3_handler(void); -void WEAK udma_handler(void); -void WEAK udmaerr_handler(void); -void WEAK adc1ss0_handler(void); -void WEAK adc1ss1_handler(void); -void WEAK adc1ss2_handler(void); -void WEAK adc1ss3_handler(void); -void WEAK i2s0_handler(void); -void WEAK epi0_handler(void); -void WEAK gpioj_handler(void); -void WEAK gpiok_handler(void); -void WEAK gpiol_handler(void); -void WEAK ssi2_handler(void); -void WEAK ssi3_handler(void); -void WEAK uart3_handler(void); -void WEAK uart4_handler(void); -void WEAK uart5_handler(void); -void WEAK uart6_handler(void); -void WEAK uart7_handler(void); -void WEAK i2c2_handler(void); -void WEAK i2c3_handler(void); -void WEAK timer4a_handler(void); -void WEAK timer4b_handler(void); -void WEAK timer5a_handler(void); -void WEAK timer5b_handler(void); -void WEAK wtimer0a_handler(void); -void WEAK wtimer0b_handler(void); -void WEAK wtimer1a_handler(void); -void WEAK wtimer1b_handler(void); -void WEAK wtimer2a_handler(void); -void WEAK wtimer2b_handler(void); -void WEAK wtimer3a_handler(void); -void WEAK wtimer3b_handler(void); -void WEAK wtimer4a_handler(void); -void WEAK wtimer4b_handler(void); -void WEAK wtimer5a_handler(void); -void WEAK wtimer5b_handler(void); -void WEAK sysexc_handler(void); -void WEAK peci0_handler(void); -void WEAK lpc0_handler(void); -void WEAK i2c4_handler(void); -void WEAK i2c5_handler(void); -void WEAK gpiom_handler(void); -void WEAK gpion_handler(void); -void WEAK fan0_handler(void); -void WEAK gpiop0_handler(void); -void WEAK gpiop1_handler(void); -void WEAK gpiop2_handler(void); -void WEAK gpiop3_handler(void); -void WEAK gpiop4_handler(void); -void WEAK gpiop5_handler(void); -void WEAK gpiop6_handler(void); -void WEAK gpiop7_handler(void); -void WEAK gpioq0_handler(void); -void WEAK gpioq1_handler(void); -void WEAK gpioq2_handler(void); -void WEAK gpioq3_handler(void); -void WEAK gpioq4_handler(void); -void WEAK gpioq5_handler(void); -void WEAK gpioq6_handler(void); -void WEAK gpioq7_handler(void); -void WEAK pwm1_0_handler(void); -void WEAK pwm1_1_handler(void); -void WEAK pwm1_2_handler(void); -void WEAK pwm1_3_handler(void); -void WEAK pwm1_fault_handler(void); - -__attribute__ ((section(".vectors"))) -void (*const vector_table[]) (void) = { - (void *)&_stack, - reset_handler, - nmi_handler, - hard_fault_handler, - mem_manage_handler, - bus_fault_handler, - usage_fault_handler, - 0, 0, 0, 0, /* Reserved */ - sv_call_handler, - debug_monitor_handler, - 0, /* Reserved */ - pend_sv_handler, - sys_tick_handler, - - gpioa_handler, /* 16 */ - gpiob_handler, /* 17 */ - gpioc_handler, /* 18 */ - gpiod_handler, /* 19 */ - gpioe_handler, /* 20 */ - uart0_handler, /* 21 */ - uart1_handler, /* 22 */ - ssi0_handler, /* 23 */ - i2c0_handler, /* 24 */ - pwm0_fault_handler, /* 25 */ - pwm0_0_handler, /* 26 */ - pwm0_1_handler, /* 27 */ - pwm0_2_handler, /* 28 */ - qei0_handler, /* 29 */ - adc0ss0_handler, /* 30 */ - adc0ss1_handler, /* 31 */ - adc0ss2_handler, /* 32 */ - adc0ss3_handler, /* 33 */ - watchdog_handler, /* 34 */ - timer0a_handler, /* 35 */ - timer0b_handler, /* 36 */ - timer1a_handler, /* 37 */ - timer1b_handler, /* 38 */ - timer2a_handler, /* 39 */ - timer2b_handler, /* 40 */ - comp0_handler, /* 41 */ - comp1_handler, /* 42 */ - comp2_handler, /* 43 */ - sysctl_handler, /* 44 */ - flash_handler, /* 45 */ - gpiof_handler, /* 46 */ - gpiog_handler, /* 47 */ - gpioh_handler, /* 48 */ - uart2_handler, /* 49 */ - ssi1_handler, /* 50 */ - timer3a_handler, /* 51 */ - timer3b_handler, /* 52 */ - i2c1_handler, /* 53 */ - qei1_handler, /* 54 */ - can0_handler, /* 55 */ - can1_handler, /* 56 */ - can2_handler, /* 57 */ - eth_handler, /* 58 */ - hibernate_handler, /* 59 */ - usb0_handler, /* 60 */ - pwm0_3_handler, /* 61 */ - udma_handler, /* 62 */ - udmaerr_handler, /* 63 */ - adc1ss0_handler, /* 64 */ - adc1ss1_handler, /* 65 */ - adc1ss2_handler, /* 66 */ - adc1ss3_handler, /* 67 */ - i2s0_handler, /* 68 */ - epi0_handler, /* 69 */ - gpioj_handler, /* 70 */ - gpiok_handler, /* 71 */ - gpiol_handler, /* 72 */ - ssi2_handler, /* 73 */ - ssi3_handler, /* 74 */ - uart3_handler, /* 75 */ - uart4_handler, /* 76 */ - uart5_handler, /* 77 */ - uart6_handler, /* 78 */ - uart7_handler, /* 79 */ - 0, /* 80 */ - 0, /* 81 */ - 0, /* 82 */ - 0, /* 83 */ - i2c2_handler, /* 84 */ - i2c3_handler, /* 85 */ - timer4a_handler, /* 86 */ - timer4b_handler, /* 87 */ - 0, /* 88 */ - 0, /* 89 */ - 0, /* 90 */ - 0, /* 91 */ - 0, /* 92 */ - 0, /* 93 */ - 0, /* 94 */ - 0, /* 95 */ - 0, /* 96 */ - 0, /* 97 */ - 0, /* 98 */ - 0, /* 99 */ - 0, /* 100 */ - 0, /* 101 */ - 0, /* 102 */ - 0, /* 103 */ - 0, /* 104 */ - 0, /* 105 */ - 0, /* 106 */ - 0, /* 107 */ - timer5a_handler, /* 108 */ - timer5b_handler, /* 109 */ - wtimer0a_handler, /* 110 */ - wtimer0b_handler, /* 111 */ - wtimer1a_handler, /* 112 */ - wtimer1b_handler, /* 113 */ - wtimer2a_handler, /* 114 */ - wtimer2b_handler, /* 115 */ - wtimer3a_handler, /* 116 */ - wtimer3b_handler, /* 117 */ - wtimer4a_handler, /* 118 */ - wtimer4b_handler, /* 119 */ - wtimer5a_handler, /* 120 */ - wtimer5b_handler, /* 121 */ - sysexc_handler, /* 122 */ - peci0_handler, /* 123 */ - lpc0_handler, /* 124 */ - i2c4_handler, /* 125 */ - i2c5_handler, /* 126 */ - gpiom_handler, /* 127 */ - gpion_handler, /* 128 */ - 0, /* 129 */ - fan0_handler, /* 130 */ - 0, /* 131 */ - gpiop0_handler, /* 132 */ - gpiop1_handler, /* 133 */ - gpiop2_handler, /* 134 */ - gpiop3_handler, /* 135 */ - gpiop4_handler, /* 136 */ - gpiop5_handler, /* 137 */ - gpiop6_handler, /* 138 */ - gpiop7_handler, /* 139 */ - gpioq0_handler, /* 140 */ - gpioq1_handler, /* 141 */ - gpioq2_handler, /* 142 */ - gpioq3_handler, /* 143 */ - gpioq4_handler, /* 144 */ - gpioq5_handler, /* 145 */ - gpioq6_handler, /* 146 */ - gpioq7_handler, /* 147 */ - 0, /* 148 */ - 0, /* 149 */ - pwm1_0_handler, /* 150 */ - pwm1_1_handler, /* 151 */ - pwm1_2_handler, /* 152 */ - pwm1_3_handler, /* 153 */ - pwm1_fault_handler, /* 154 */ -}; - -void reset_handler(void) -{ - volatile unsigned *src, *dest; - - __asm__("MSR msp, %0" : : "r"(&_stack)); - - for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) - *dest = *src; - - while (dest < &_ebss) - *dest++ = 0; - - /* Call the application's entry point. */ - main(); -} - -void blocking_handler(void) -{ - while (1) ; -} - -void null_handler(void) -{ - /* Do nothing. */ -} - -#pragma weak nmi_handler = null_handler -#pragma weak hard_fault_handler = blocking_handler -#pragma weak mem_manage_handler = blocking_handler -#pragma weak bus_fault_handler = blocking_handler -#pragma weak usage_fault_handler = blocking_handler -#pragma weak sv_call_handler = null_handler -#pragma weak debug_monitor_handler = null_handler -#pragma weak pend_sv_handler = null_handler -#pragma weak sys_tick_handler = null_handler -#pragma weak gpioa_handler = null_handler -#pragma weak gpiob_handler = null_handler -#pragma weak gpioc_handler = null_handler -#pragma weak gpiod_handler = null_handler -#pragma weak gpioe_handler = null_handler -#pragma weak uart0_handler = null_handler -#pragma weak uart1_handler = null_handler -#pragma weak ssi0_handler = null_handler -#pragma weak i2c0_handler = null_handler -#pragma weak pwm0_fault_handler = null_handler -#pragma weak pwm0_0_handler = null_handler -#pragma weak pwm0_1_handler = null_handler -#pragma weak pwm0_2_handler = null_handler -#pragma weak qei0_handler = null_handler -#pragma weak adc0ss0_handler = null_handler -#pragma weak adc0ss1_handler = null_handler -#pragma weak adc0ss2_handler = null_handler -#pragma weak adc0ss3_handler = null_handler -#pragma weak watchdog_handler = null_handler -#pragma weak timer0a_handler = null_handler -#pragma weak timer0b_handler = null_handler -#pragma weak timer1a_handler = null_handler -#pragma weak timer1b_handler = null_handler -#pragma weak timer2a_handler = null_handler -#pragma weak timer2b_handler = null_handler -#pragma weak comp0_handler = null_handler -#pragma weak comp1_handler = null_handler -#pragma weak comp2_handler = null_handler -#pragma weak sysctl_handler = null_handler -#pragma weak flash_handler = null_handler -#pragma weak gpiof_handler = null_handler -#pragma weak gpiog_handler = null_handler -#pragma weak gpioh_handler = null_handler -#pragma weak uart2_handler = null_handler -#pragma weak ssi1_handler = null_handler -#pragma weak timer3a_handler = null_handler -#pragma weak timer3b_handler = null_handler -#pragma weak i2c1_handler = null_handler -#pragma weak qei1_handler = null_handler -#pragma weak can0_handler = null_handler -#pragma weak can1_handler = null_handler -#pragma weak can2_handler = null_handler -#pragma weak eth_handler = null_handler -#pragma weak hibernate_handler = null_handler -#pragma weak usb0_handler = null_handler -#pragma weak pwm0_3_handler = null_handler -#pragma weak udma_handler = null_handler -#pragma weak udmaerr_handler = null_handler -#pragma weak adc1ss0_handler = null_handler -#pragma weak adc1ss1_handler = null_handler -#pragma weak adc1ss2_handler = null_handler -#pragma weak adc1ss3_handler = null_handler -#pragma weak i2s0_handler = null_handler -#pragma weak epi0_handler = null_handler -#pragma weak gpioj_handler = null_handler -#pragma weak gpiok_handler = null_handler -#pragma weak gpiol_handler = null_handler -#pragma weak ssi2_handler = null_handler -#pragma weak ssi3_handler = null_handler -#pragma weak uart3_handler = null_handler -#pragma weak uart4_handler = null_handler -#pragma weak uart5_handler = null_handler -#pragma weak uart6_handler = null_handler -#pragma weak uart7_handler = null_handler -#pragma weak i2c2_handler = null_handler -#pragma weak i2c3_handler = null_handler -#pragma weak timer4a_handler = null_handler -#pragma weak timer4b_handler = null_handler -#pragma weak timer5a_handler = null_handler -#pragma weak timer5b_handler = null_handler -#pragma weak wtimer0a_handler = null_handler -#pragma weak wtimer0b_handler = null_handler -#pragma weak wtimer1a_handler = null_handler -#pragma weak wtimer1b_handler = null_handler -#pragma weak wtimer2a_handler = null_handler -#pragma weak wtimer2b_handler = null_handler -#pragma weak wtimer3a_handler = null_handler -#pragma weak wtimer3b_handler = null_handler -#pragma weak wtimer4a_handler = null_handler -#pragma weak wtimer4b_handler = null_handler -#pragma weak wtimer5a_handler = null_handler -#pragma weak wtimer5b_handler = null_handler -#pragma weak sysexc_handler = null_handler -#pragma weak peci0_handler = null_handler -#pragma weak lpc0_handler = null_handler -#pragma weak i2c4_handler = null_handler -#pragma weak i2c5_handler = null_handler -#pragma weak gpiom_handler = null_handler -#pragma weak gpion_handler = null_handler -#pragma weak fan0_handler = null_handler -#pragma weak gpiop0_handler = null_handler -#pragma weak gpiop1_handler = null_handler -#pragma weak gpiop2_handler = null_handler -#pragma weak gpiop3_handler = null_handler -#pragma weak gpiop4_handler = null_handler -#pragma weak gpiop5_handler = null_handler -#pragma weak gpiop6_handler = null_handler -#pragma weak gpiop7_handler = null_handler -#pragma weak gpioq0_handler = null_handler -#pragma weak gpioq1_handler = null_handler -#pragma weak gpioq2_handler = null_handler -#pragma weak gpioq3_handler = null_handler -#pragma weak gpioq4_handler = null_handler -#pragma weak gpioq5_handler = null_handler -#pragma weak gpioq6_handler = null_handler -#pragma weak gpioq7_handler = null_handler -#pragma weak pwm1_0_handler = null_handler -#pragma weak pwm1_1_handler = null_handler -#pragma weak pwm1_2_handler = null_handler -#pragma weak pwm1_3_handler = null_handler -#pragma weak pwm1_fault_handler = null_handler diff --git a/lib/lpc13xx/Makefile b/lib/lpc13xx/Makefile index e1e69f7b..15bc6868 100644 --- a/lib/lpc13xx/Makefile +++ b/lib/lpc13xx/Makefile @@ -25,10 +25,10 @@ CC = $(PREFIX)-gcc AR = $(PREFIX)-ar CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \ -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ - -ffunction-sections -fdata-sections -MD + -ffunction-sections -fdata-sections -MD -DLPC13XX # ARFLAGS = rcsv ARFLAGS = rcs -OBJS = gpio.o assert.o +OBJS = gpio.o VPATH += ../cm3 diff --git a/lib/lpc17xx/Makefile b/lib/lpc17xx/Makefile index d1da64af..19fc1529 100644 --- a/lib/lpc17xx/Makefile +++ b/lib/lpc17xx/Makefile @@ -25,10 +25,10 @@ CC = $(PREFIX)-gcc AR = $(PREFIX)-ar CFLAGS = -O0 -g -Wall -Wextra -I../../include -fno-common \ -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ - -ffunction-sections -fdata-sections -MD + -ffunction-sections -fdata-sections -MD -DLPC17XX # ARFLAGS = rcsv ARFLAGS = rcs -OBJS = gpio.o vector.o assert.o +OBJS = gpio.o VPATH += ../cm3 diff --git a/lib/lpc43xx/Makefile b/lib/lpc43xx/Makefile index 6e08ea0e..efbba0dd 100644 --- a/lib/lpc43xx/Makefile +++ b/lib/lpc43xx/Makefile @@ -28,11 +28,10 @@ AR = $(PREFIX)-ar CFLAGS = -O2 -g3 -Wall -Wextra -I../../include -fno-common \ -mcpu=cortex-m4 -mthumb -Wstrict-prototypes \ -ffunction-sections -fdata-sections -MD \ - -mfloat-abi=hard -mfpu=fpv4-sp-d16 + -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX # ARFLAGS = rcsv ARFLAGS = rcs -OBJS = gpio.o vector.o scu.o i2c.o ssp.o nvic.o systick.o \ - assert.o +OBJS = gpio.o scu.o i2c.o ssp.o VPATH += ../cm3 diff --git a/lib/lpc43xx/nvic.c b/lib/lpc43xx/nvic.c deleted file mode 100644 index 47933127..00000000 --- a/lib/lpc43xx/nvic.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> - * Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com> - * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ -#include <libopencm3/cm3/scs.h> -#include <libopencm3/lpc43xx/nvic.h> - -void nvic_enable_irq(u8 irqn) -{ - NVIC_ISER(irqn / 32) = (1 << (irqn % 32)); -} - -void nvic_disable_irq(u8 irqn) -{ - NVIC_ICER(irqn / 32) = (1 << (irqn % 32)); -} - -u8 nvic_get_pending_irq(u8 irqn) -{ - return NVIC_ISPR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; -} - -void nvic_set_pending_irq(u8 irqn) -{ - NVIC_ISPR(irqn / 32) = (1 << (irqn % 32)); -} - -void nvic_clear_pending_irq(u8 irqn) -{ - NVIC_ICPR(irqn / 32) = (1 << (irqn % 32)); -} - -u8 nvic_get_active_irq(u8 irqn) -{ - return NVIC_IABR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; -} - -u8 nvic_get_irq_enabled(u8 irqn) -{ - return NVIC_ISER(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; -} - -void nvic_set_priority(u8 irqn, u8 priority) -{ - if(irqn>NVIC_M4_QEI_IRQ) - { - /* Cortex-M system interrupts */ - SCS_SHPR( (irqn&0xF)-4 ) = priority; - }else - { - /* Device specific interrupts */ - NVIC_IPR(irqn) = priority; - } -} - -void nvic_generate_software_interrupt(u8 irqn) -{ - if (irqn <= 239) - NVIC_STIR |= irqn; -} diff --git a/lib/lpc43xx/systick.c b/lib/lpc43xx/systick.c deleted file mode 100644 index 82345a92..00000000 --- a/lib/lpc43xx/systick.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> - * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <libopencm3/lpc43xx/systick.h> - -void systick_set_reload(u32 value) -{ - STK_LOAD = (value & 0x00FFFFFF); -} - -u32 systick_get_value(void) -{ - return STK_VAL; -} - -void systick_set_clocksource(u8 clocksource) -{ - STK_CTRL |= clocksource; -} - -void systick_interrupt_enable(void) -{ - STK_CTRL |= STK_CTRL_TICKINT; -} - -void systick_interrupt_disable(void) -{ - STK_CTRL &= ~STK_CTRL_TICKINT; -} - -void systick_counter_enable(void) -{ - STK_CTRL |= STK_CTRL_ENABLE; -} - -void systick_counter_disable(void) -{ - STK_CTRL &= ~STK_CTRL_ENABLE; -} - -u8 systick_get_countflag(void) -{ - if (STK_CTRL & STK_CTRL_COUNTFLAG) - return 1; - else - return 0; -} - -u32 systick_get_calib(void) -{ - return (STK_CALIB&0x00FFFFFF); -} diff --git a/lib/lpc43xx/vector.c b/lib/lpc43xx/vector.c deleted file mode 100644 index 23008bc9..00000000 --- a/lib/lpc43xx/vector.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> - * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#define WEAK __attribute__ ((weak)) - -/* Symbols exported by the linker script(s): */ -extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; -extern unsigned _etext_ram, _text_ram, _etext_rom; - -void main(void); -void reset_handler(void); -void blocking_handler(void); -void null_handler(void); - -void WEAK nmi_handler(void); -void WEAK hard_fault_handler(void); -void WEAK mem_manage_handler(void); -void WEAK bus_fault_handler(void); -void WEAK usage_fault_handler(void); -void WEAK sv_call_handler(void); -void WEAK debug_monitor_handler(void); -void WEAK pend_sv_handler(void); -void WEAK sys_tick_handler(void); -void WEAK dac_irqhandler(void); -void WEAK m0core_irqhandler(void); -void WEAK dma_irqhandler(void); -void WEAK ethernet_irqhandler(void); -void WEAK sdio_irqhandler(void); -void WEAK lcd_irqhandler(void); -void WEAK usb0_irqhandler(void); -void WEAK usb1_irqhandler(void); -void WEAK sct_irqhandler(void); -void WEAK ritimer_irqhandler(void); -void WEAK timer0_irqhandler(void); -void WEAK timer1_irqhandler(void); -void WEAK timer2_irqhandler(void); -void WEAK timer3_irqhandler(void); -void WEAK mcpwm_irqhandler(void); -void WEAK adc0_irqhandler(void); -void WEAK i2c0_irqhandler(void); -void WEAK i2c1_irqhandler(void); -void WEAK spi_irqhandler(void); -void WEAK adc1_irqhandler(void); -void WEAK ssp0_irqhandler(void); -void WEAK ssp1_irqhandler(void); -void WEAK usart0_irqhandler(void); -void WEAK uart1_irqhandler(void); -void WEAK usart2_irqhandler(void); -void WEAK usart3_irqhandler(void); -void WEAK i2s0_irqhandler(void); -void WEAK i2s1_irqhandler(void); -void WEAK spifi_irqhandler(void); -void WEAK sgpio_irqhandler(void); -void WEAK pin_int0_irqhandler(void); -void WEAK pin_int1_irqhandler(void); -void WEAK pin_int2_irqhandler(void); -void WEAK pin_int3_irqhandler(void); -void WEAK pin_int4_irqhandler(void); -void WEAK pin_int5_irqhandler(void); -void WEAK pin_int6_irqhandler(void); -void WEAK pin_int7_irqhandler(void); -void WEAK gint0_irqhandler(void); -void WEAK gint1_irqhandler(void); -void WEAK eventrouter_irqhandler(void); -void WEAK c_can1_irqhandler(void); -void WEAK atimer_irqhandler(void); -void WEAK rtc_irqhandler(void); -void WEAK wwdt_irqhandler(void); -void WEAK c_can0_irqhandler(void); -void WEAK qei_irqhandler(void); - -__attribute__ ((section(".vectors"))) -void (*const vector_table[]) (void) = { - /* Cortex-M4 interrupts */ - (void*)&_stack, - reset_handler, - nmi_handler, - hard_fault_handler, - mem_manage_handler, - bus_fault_handler, - usage_fault_handler, - 0, 0, 0, 0, /* reserved */ - sv_call_handler, - debug_monitor_handler, - 0, /* reserved */ - pend_sv_handler, - sys_tick_handler, - - /* LPC43xx interrupts */ - dac_irqhandler, - m0core_irqhandler, - dma_irqhandler, - 0, /* reserved */ - 0, /* reserved */ - ethernet_irqhandler, - sdio_irqhandler, - lcd_irqhandler, - usb0_irqhandler, - usb1_irqhandler, - sct_irqhandler, - ritimer_irqhandler, - timer0_irqhandler, - timer1_irqhandler, - timer2_irqhandler, - timer3_irqhandler, - mcpwm_irqhandler, - adc0_irqhandler, - i2c0_irqhandler, - i2c1_irqhandler, - spi_irqhandler, - adc1_irqhandler, - ssp0_irqhandler, - ssp1_irqhandler, - usart0_irqhandler, - uart1_irqhandler, - usart2_irqhandler, - usart3_irqhandler, - i2s0_irqhandler, - i2s1_irqhandler, - spifi_irqhandler, - sgpio_irqhandler, - pin_int0_irqhandler, - pin_int1_irqhandler, - pin_int2_irqhandler, - pin_int3_irqhandler, - pin_int4_irqhandler, - pin_int5_irqhandler, - pin_int6_irqhandler, - pin_int7_irqhandler, - gint0_irqhandler, - gint1_irqhandler, - eventrouter_irqhandler, - c_can1_irqhandler, - 0, /* reserved */ - 0, /* reserved */ - atimer_irqhandler, - rtc_irqhandler, - 0, /* reserved */ - wwdt_irqhandler, - 0, /* reserved */ - c_can0_irqhandler, - qei_irqhandler, -}; - -#define MMIO32(addr) (*(volatile unsigned long*)(addr)) -#define CREG_M4MEMMAP MMIO32( (0x40043000 + 0x100) ) - -void reset_handler(void) -{ - volatile unsigned *src, *dest; - - __asm__("MSR msp, %0" : : "r"(&_stack)); - - /* Copy the code from ROM to Real RAM (if enabled) */ - if( (&_etext_ram-&_text_ram) > 0 ) - { - src = &_etext_rom-(&_etext_ram-&_text_ram); - /* Change Shadow memory to ROM (for Debug Purpose in case Boot has not set correctly the M4MEMMAP because of debug) */ - CREG_M4MEMMAP = (unsigned long)src; - - for(dest = &_text_ram; dest < &_etext_ram; ) - { - *dest++ = *src++; - } - - /* Change Shadow memory to Real RAM */ - CREG_M4MEMMAP = (unsigned long)&_text_ram; - - /* Continue Execution in RAM */ - } - - for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) - *dest = *src; - - while (dest < &_ebss) - *dest++ = 0; - - /* Call the application's entry point. */ - main(); -} - -void blocking_handler(void) -{ - while (1) ; -} - -void null_handler(void) -{ - /* Do nothing. */ -} - -#pragma weak nmi_handler = null_handler -#pragma weak hard_fault_handler = blocking_handler -#pragma weak mem_manage_handler = blocking_handler -#pragma weak bus_fault_handler = blocking_handler -#pragma weak usage_fault_handler = blocking_handler -#pragma weak sv_call_handler = null_handler -#pragma weak debug_monitor_handler = null_handler -#pragma weak pend_sv_handler = null_handler -#pragma weak sys_tick_handler = null_handler -#pragma weak dac_irqhandler = null_handler -#pragma weak m0core_irqhandler = null_handler -#pragma weak dma_irqhandler = null_handler -#pragma weak ethernet_irqhandler = null_handler -#pragma weak sdio_irqhandler = null_handler -#pragma weak lcd_irqhandler = null_handler -#pragma weak usb0_irqhandler = null_handler -#pragma weak usb1_irqhandler = null_handler -#pragma weak sct_irqhandler = null_handler -#pragma weak ritimer_irqhandler = null_handler -#pragma weak timer0_irqhandler = null_handler -#pragma weak timer1_irqhandler = null_handler -#pragma weak timer2_irqhandler = null_handler -#pragma weak timer3_irqhandler = null_handler -#pragma weak mcpwm_irqhandler = null_handler -#pragma weak adc0_irqhandler = null_handler -#pragma weak i2c0_irqhandler = null_handler -#pragma weak i2c1_irqhandler = null_handler -#pragma weak spi_irqhandler = null_handler -#pragma weak adc1_irqhandler = null_handler -#pragma weak ssp0_irqhandler = null_handler -#pragma weak ssp1_irqhandler = null_handler -#pragma weak usart0_irqhandler = null_handler -#pragma weak uart1_irqhandler = null_handler -#pragma weak usart2_irqhandler = null_handler -#pragma weak usart3_irqhandler = null_handler -#pragma weak i2s0_irqhandler = null_handler -#pragma weak i2s1_irqhandler = null_handler -#pragma weak spifi_irqhandler = null_handler -#pragma weak sgpio_irqhandler = null_handler -#pragma weak pin_int0_irqhandler = null_handler -#pragma weak pin_int1_irqhandler = null_handler -#pragma weak pin_int2_irqhandler = null_handler -#pragma weak pin_int3_irqhandler = null_handler -#pragma weak pin_int4_irqhandler = null_handler -#pragma weak pin_int5_irqhandler = null_handler -#pragma weak pin_int6_irqhandler = null_handler -#pragma weak pin_int7_irqhandler = null_handler -#pragma weak gint0_irqhandler = null_handler -#pragma weak gint1_irqhandler = null_handler -#pragma weak eventrouter_irqhandler = null_handler -#pragma weak c_can1_irqhandler = null_handler -#pragma weak atimer_irqhandler = null_handler -#pragma weak rtc_irqhandler = null_handler -#pragma weak wwdt_irqhandler = null_handler -#pragma weak c_can0_irqhandler = null_handler -#pragma weak qei_irqhandler = null_handler diff --git a/lib/lpc43xx/vector_chipset.c b/lib/lpc43xx/vector_chipset.c new file mode 100644 index 00000000..0463a65c --- /dev/null +++ b/lib/lpc43xx/vector_chipset.c @@ -0,0 +1,48 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> + * Copyright (C) 2012 Michael Ossmann <mike@ossmann.com> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/cm3/common.h> + +extern unsigned _etext_ram, _text_ram, _etext_rom; + +#define CREG_M4MEMMAP MMIO32( (0x40043000 + 0x100) ) + +static void pre_main(void) +{ + volatile unsigned *src, *dest; + + /* Copy the code from ROM to Real RAM (if enabled) */ + if( (&_etext_ram-&_text_ram) > 0 ) + { + src = &_etext_rom-(&_etext_ram-&_text_ram); + /* Change Shadow memory to ROM (for Debug Purpose in case Boot has not set correctly the M4MEMMAP because of debug) */ + CREG_M4MEMMAP = (unsigned long)src; + + for(dest = &_text_ram; dest < &_etext_ram; ) + { + *dest++ = *src++; + } + + /* Change Shadow memory to Real RAM */ + CREG_M4MEMMAP = (unsigned long)&_text_ram; + + /* Continue Execution in RAM */ + } +} diff --git a/lib/stm32/f1/can.c b/lib/stm32/can.c index 9bd23cb3..3ee86c36 100644 --- a/lib/stm32/f1/can.c +++ b/lib/stm32/can.c @@ -18,7 +18,16 @@ */ #include <libopencm3/stm32/can.h> -#include <libopencm3/stm32/f1/rcc.h> + +#if defined(STM32F1) +# include <libopencm3/stm32/f1/rcc.h> +#elif defined(STM32F2) +# include <libopencm3/stm32/f2/rcc.h> +#elif defined(STM32F4) +# include <libopencm3/stm32/f4/rcc.h> +#else +# error "stm32 family not defined." +#endif void can_reset(u32 canport) { @@ -55,6 +64,9 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart, if ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK) return 1; + /* clear can timing bits */ + CAN_BTR(canport) = 0; + /* Set the automatic bus-off management. */ if (ttcm) CAN_MCR(canport) |= CAN_MCR_TTCM; @@ -311,5 +323,10 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext, /* Release the FIFO. */ if (release) - can_fifo_release(CAN1, 0); + can_fifo_release(canport, fifo); +} + +bool can_available_mailbox(u32 canport) +{ + return CAN_TSR(canport) & (CAN_TSR_TME0 | CAN_TSR_TME1 | CAN_TSR_TME2); } diff --git a/lib/stm32/f1/desig.c b/lib/stm32/desig.c index 7ae968e1..ea861aaa 100644 --- a/lib/stm32/f1/desig.c +++ b/lib/stm32/desig.c @@ -17,7 +17,7 @@ * along with this library. If not, see <http://www.gnu.org/licenses/>. */ -#include <libopencm3/stm32/f1/desig.h> +#include <libopencm3/stm32/desig.h> u16 desig_get_flash_size(void) { @@ -35,3 +35,25 @@ void desig_get_unique_id(u32 result[]) result[1] = bits63_32; result[2] = bits31_16 << 16 | bits15_0; } + +void desig_get_unique_id_as_string(char *string, + unsigned int string_len) +{ + int i, len; + u8 device_id[12]; + static const char chars[] = "0123456789ABCDEF"; + + desig_get_unique_id((u32 *)device_id); + + /* Each byte produces two characters */ + len = (2 * sizeof(device_id) < string_len) ? + 2 * sizeof(device_id) : string_len - 1; + + for (i = 0; i < len; i += 2) { + string[i] = chars[(device_id[i / 2] >> 0) & 0x0F]; + string[i + 1] = chars[(device_id[i / 2] >> 4) & 0x0F]; + } + + string[len] = '\0'; +} + diff --git a/lib/stm32/f2/exti.c b/lib/stm32/exti2.c index 5280914e..bea2f4d4 100644 --- a/lib/stm32/f2/exti.c +++ b/lib/stm32/exti2.c @@ -2,6 +2,7 @@ * This file is part of the libopencm3 project. * * Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz> + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -15,11 +16,22 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * This provides the code for the "next gen" EXTI block provided in F2/F4/L1 + * devices. (differences only in the source selection) */ #include <libopencm3/stm32/exti.h> -#include <libopencm3/stm32/f2/syscfg.h> +#include <libopencm3/stm32/syscfg.h> +#if defined(STM32F2) #include <libopencm3/stm32/f2/gpio.h> +#elif defined(STM32F4) +#include <libopencm3/stm32/f4/gpio.h> +#elif defined(STM32L1) +#include <libopencm3/stm32/l1/gpio.h> +#else +#error "invalid/unknown stm32 family for this code" +#endif void exti_set_trigger(u32 extis, exti_trigger_type trig) { @@ -121,12 +133,24 @@ void exti_select_source(u32 exti, u32 gpioport) case GPIOE: bits = 0xb; break; +#if defined(STM32L1) +#else case GPIOF: bits = 0xa; break; case GPIOG: bits = 0x9; break; +#endif + case GPIOH: + bits = 0x8; + break; +#if defined(STM32L1) +#else + case GPIOI: + bits = 0x7; + break; +#endif } /* Ensure that only valid EXTI lines are used. */ diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index a2f7bf28..ed8ae29b 100644 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -28,10 +28,11 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ -ffunction-sections -fdata-sections -MD -DSTM32F1 # ARFLAGS = rcsv ARFLAGS = rcs -OBJS = vector.o rcc.o gpio.o usart.o adc.o spi.o flash.o nvic.o \ - rtc.o i2c.o dma.o systick.o exti.o scb.o ethernet.o \ +OBJS = rcc.o gpio.o usart.o adc.o spi.o flash.o \ + rtc.o i2c.o dma.o exti.o ethernet.o \ usb_f103.o usb.o usb_control.o usb_standard.o can.o \ - timer.o usb_f107.o desig.o crc.o assert.o dac.o iwdg.o pwr.o + timer.o usb_f107.o desig.o crc.o dac.o iwdg.o pwr.o \ + usb_fx07_common.o VPATH += ../../usb:../:../../cm3 diff --git a/lib/stm32/f1/dma.c b/lib/stm32/f1/dma.c index 2bc89265..3dbb14f5 100644 --- a/lib/stm32/f1/dma.c +++ b/lib/stm32/f1/dma.c @@ -10,12 +10,18 @@ @date 18 August 2012 -This library supports the DMA -Control System in the STM32F1xx series of ARM Cortex Microcontrollers -by ST Microelectronics. It can provide for two DMA controllers, -one with 7 channels and one with 5. Channels are hardware dedicated -and each is shared with a number of different sources (only one can be -used at a time, under the responsibility of the programmer). +This library supports the DMA Control System in the STM32 series of ARM Cortex +Microcontrollers by ST Microelectronics. + +Up to two DMA controllers are supported. 12 DMA channels are allocated 7 to +the first DMA controller and 5 to the second. Each channel is connected to +between 3 and 6 hardware peripheral DMA signals in a logical OR arrangement. + +DMA transfers can be configured to occur between peripheral and memory in +any combination including memory to memory. Circular mode transfers are +also supported in transfers involving a peripheral. An arbiter is provided +to resolve priority DMA requests. Transfers can be made with 8, 16 or 32 bit +words. LGPL License Terms @ref lgpl_license */ @@ -68,6 +74,42 @@ void dma_channel_reset(u32 dma, u8 channel) } /*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Clear Interrupt Flag + +The interrupt flag for the channel is cleared. More than one interrupt for the +same channel may be cleared by using the logical OR of the interrupt flags. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: @ref dma_st_number +@param[in] interrupts unsigned int32. Logical OR of interrupt numbers: @ref dma_if_offset +*/ + +void dma_clear_interrupt_flags(u32 dma, u8 channel, u32 interrupts) +{ +/* Get offset to interrupt flag location in channel field */ + u32 flags = (interrupts << DMA_FLAG_OFFSET(channel)); + DMA_IFCR(dma) = flags; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Read Interrupt Flag + +The interrupt flag for the channel is returned. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: @ref dma_st_number +@param[in] interrupt unsigned int32. Interrupt number: @ref dma_st_number +@returns bool interrupt flag is set. +*/ + +bool dma_get_interrupt_flag(u32 dma, u8 channel, u32 interrupt) +{ +/* get offset to interrupt flag location in channel field. */ + u32 flag = (interrupt << DMA_FLAG_OFFSET(channel)); + return ((DMA_ISR(dma) & flag) > 0); +} + +/*-----------------------------------------------------------------------------*/ /** @brief DMA Channel Enable Memory to Memory Transfers Memory to memory transfers do not require a trigger to activate each transfer. @@ -160,12 +202,40 @@ void dma_enable_memory_increment_mode(u32 dma, u8 channel) @param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 */ +void dma_disable_memory_increment_mode(u32 dma, u8 channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_MINC; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Peripheral Increment after Transfer + +Following each transfer the current peripheral address is incremented by +1, 2 or 4 depending on the data size set in @ref dma_set_peripheral_size. The +value held by the base peripheral address register is unchanged. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_peripheral_increment_mode(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_PINC; } /*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Peripheral Increment after Transfer + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + +void dma_disable_peripheral_increment_mode(u32 dma, u8 channel) +{ + DMA_CCR(dma, channel) &= ~DMA_CCR_PINC; +} + +/*-----------------------------------------------------------------------------*/ /** @brief DMA Channel Enable Memory Circular Mode After the number of bytes/words to be transferred has been completed, the diff --git a/lib/stm32/f1/vector.c b/lib/stm32/f1/vector.c deleted file mode 100644 index d660774b..00000000 --- a/lib/stm32/f1/vector.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#define WEAK __attribute__ ((weak)) - -/* Symbols exported by the linker script(s): */ -extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; - -void main(void); -void reset_handler(void); -void blocking_handler(void); -void null_handler(void); - -void WEAK nmi_handler(void); -void WEAK hard_fault_handler(void); -void WEAK mem_manage_handler(void); -void WEAK bus_fault_handler(void); -void WEAK usage_fault_handler(void); -void WEAK sv_call_handler(void); -void WEAK debug_monitor_handler(void); -void WEAK pend_sv_handler(void); -void WEAK sys_tick_handler(void); -void WEAK wwdg_isr(void); -void WEAK pvd_isr(void); -void WEAK tamper_isr(void); -void WEAK rtc_isr(void); -void WEAK flash_isr(void); -void WEAK rcc_isr(void); -void WEAK exti0_isr(void); -void WEAK exti1_isr(void); -void WEAK exti2_isr(void); -void WEAK exti3_isr(void); -void WEAK exti4_isr(void); -void WEAK dma1_channel1_isr(void); -void WEAK dma1_channel2_isr(void); -void WEAK dma1_channel3_isr(void); -void WEAK dma1_channel4_isr(void); -void WEAK dma1_channel5_isr(void); -void WEAK dma1_channel6_isr(void); -void WEAK dma1_channel7_isr(void); -void WEAK adc1_2_isr(void); -void WEAK usb_hp_can_tx_isr(void); -void WEAK usb_lp_can_rx0_isr(void); -void WEAK can_rx1_isr(void); -void WEAK can_sce_isr(void); -void WEAK exti9_5_isr(void); -void WEAK tim1_brk_isr(void); -void WEAK tim1_up_isr(void); -void WEAK tim1_trg_com_isr(void); -void WEAK tim1_cc_isr(void); -void WEAK tim2_isr(void); -void WEAK tim3_isr(void); -void WEAK tim4_isr(void); -void WEAK i2c1_ev_isr(void); -void WEAK i2c1_er_isr(void); -void WEAK i2c2_ev_isr(void); -void WEAK i2c2_er_isr(void); -void WEAK spi1_isr(void); -void WEAK spi2_isr(void); -void WEAK usart1_isr(void); -void WEAK usart2_isr(void); -void WEAK usart3_isr(void); -void WEAK exti15_10_isr(void); -void WEAK rtc_alarm_isr(void); -void WEAK usb_wakeup_isr(void); -void WEAK tim8_brk_isr(void); -void WEAK tim8_up_isr(void); -void WEAK tim8_trg_com_isr(void); -void WEAK tim8_cc_isr(void); -void WEAK adc3_isr(void); -void WEAK fsmc_isr(void); -void WEAK sdio_isr(void); -void WEAK tim5_isr(void); -void WEAK spi3_isr(void); -void WEAK uart4_isr(void); -void WEAK uart5_isr(void); -void WEAK tim6_isr(void); -void WEAK tim7_isr(void); -void WEAK dma2_channel1_isr(void); -void WEAK dma2_channel2_isr(void); -void WEAK dma2_channel3_isr(void); -void WEAK dma2_channel4_5_isr(void); -void WEAK dma2_channel5_isr(void); -void WEAK eth_isr(void); -void WEAK eth_wkup_isr(void); -void WEAK can2_tx_isr(void); -void WEAK can2_rx0_isr(void); -void WEAK can2_rx1_isr(void); -void WEAK can2_sce_isr(void); -void WEAK otg_fs_isr(void); - - -__attribute__ ((section(".vectors"))) -void (*const vector_table[]) (void) = { - (void*)&_stack, /* Addr: 0x0000_0000 */ - reset_handler, /* Addr: 0x0000_0004 */ - nmi_handler, /* Addr: 0x0000_0008 */ - hard_fault_handler, /* Addr: 0x0000_000C */ - mem_manage_handler, /* Addr: 0x0000_0010 */ - bus_fault_handler, /* Addr: 0x0000_0014 */ - usage_fault_handler, /* Addr: 0x0000_0018 */ - 0, 0, 0, 0, /* Reserved Addr: 0x0000_001C - 0x0000_002B */ - sv_call_handler, /* Addr: 0x0000_002C */ - debug_monitor_handler, /* Addr: 0x0000_0030*/ - 0, /* Reserved Addr: 0x0000_00034 */ - pend_sv_handler, /* Addr: 0x0000_0038 */ - sys_tick_handler, /* Addr: 0x0000_003C */ - wwdg_isr, /* Addr: 0x0000_0040 */ - pvd_isr, /* Addr: 0x0000_0044 */ - tamper_isr, /* Addr: 0x0000_0048 */ - rtc_isr, /* Addr: 0x0000_004C */ - flash_isr, /* Addr: 0x0000_0050 */ - rcc_isr, /* Addr: 0x0000_0054 */ - exti0_isr, /* Addr: 0x0000_0058 */ - exti1_isr, /* Addr: 0x0000_005C */ - exti2_isr, /* Addr: 0x0000_0060 */ - exti3_isr, /* Addr: 0x0000_0064 */ - exti4_isr, /* Addr: 0x0000_0068 */ - dma1_channel1_isr, /* Addr: 0x0000_006C */ - dma1_channel2_isr, /* Addr: 0x0000_0070 */ - dma1_channel3_isr, /* Addr: 0x0000_0074 */ - dma1_channel4_isr, /* Addr: 0x0000_0078 */ - dma1_channel5_isr, /* Addr: 0x0000_007C */ - dma1_channel6_isr, /* Addr: 0x0000_0080 */ - dma1_channel7_isr, /* Addr: 0x0000_0084 */ - adc1_2_isr, /* Addr: 0x0000_0088 */ - usb_hp_can_tx_isr, /* Addr: 0x0000_008C */ - usb_lp_can_rx0_isr, /* Addr: 0x0000_0090 */ - can_rx1_isr, /* Addr: 0x0000_0094 */ - can_sce_isr, /* Addr: 0x0000_0098 */ - exti9_5_isr, /* Addr: 0x0000_009C */ - tim1_brk_isr, /* Addr: 0x0000_00A0 */ - tim1_up_isr, /* Addr: 0x0000_00A4 */ - tim1_trg_com_isr, /* Addr: 0x0000_00A8 */ - tim1_cc_isr, /* Addr: 0x0000_00AC */ - tim2_isr, /* Addr: 0x0000_00B0 */ - tim3_isr, /* Addr: 0x0000_00B4 */ - tim4_isr, /* Addr: 0x0000_00B8 */ - i2c1_ev_isr, /* Addr: 0x0000_00BC */ - i2c1_er_isr, /* Addr: 0x0000_00C0 */ - i2c2_ev_isr, /* Addr: 0x0000_00C4 */ - i2c2_er_isr, /* Addr: 0x0000_00C8 */ - spi1_isr, /* Addr: 0x0000_00CC */ - spi2_isr, /* Addr: 0x0000_00D0 */ - usart1_isr, /* Addr: 0x0000_00D4 */ - usart2_isr, /* Addr: 0x0000_00D8 */ - usart3_isr, /* Addr: 0x0000_00DC */ - exti15_10_isr, /* Addr: 0x0000_00E0 */ - rtc_alarm_isr, /* Addr: 0x0000_00E4 */ - usb_wakeup_isr, /* Addr: 0x0000_00E8 */ - tim8_brk_isr, /* Addr: 0x0000_00EC */ - tim8_up_isr, /* Addr: 0x0000_00F0 */ - tim8_trg_com_isr, /* Addr: 0x0000_00F4 */ - tim8_cc_isr, /* Addr: 0x0000_00F8 */ - adc3_isr, /* Addr: 0x0000_00FC */ - fsmc_isr, /* Addr: 0x0000_0100 */ - sdio_isr, /* Addr: 0x0000_0104 */ - tim5_isr, /* Addr: 0x0000_0108 */ - spi3_isr, /* Addr: 0x0000_010C */ - uart4_isr, /* Addr: 0x0000_0110 */ - uart5_isr, /* Addr: 0x0000_0114 */ - tim6_isr, /* Addr: 0x0000_0118 */ - tim7_isr, /* Addr: 0x0000_011C */ - dma2_channel1_isr, /* Addr: 0x0000_0120 */ - dma2_channel2_isr, /* Addr: 0x0000_0124 */ - dma2_channel3_isr, /* Addr: 0x0000_0128 */ - dma2_channel4_5_isr, /* Addr: 0x0000_012C */ - dma2_channel5_isr, /* Addr: 0x0000_0130 */ - eth_isr, /* Addr: 0x0000_0134 */ - eth_wkup_isr, /* Addr: 0x0000_0138 */ - can2_tx_isr, /* Addr: 0x0000_013C */ - can2_rx0_isr, /* Addr: 0x0000_0140 */ - can2_rx1_isr, /* Addr: 0x0000_0144 */ - can2_sce_isr, /* Addr: 0x0000_0148 */ - otg_fs_isr, /* Addr: 0x0000_014C */ -}; - -#include <stdint.h> -void reset_handler(void) -{ - volatile unsigned *src, *dest; - uint32_t reset_str = *((uint32_t *)0x2000FFF0); - - if (reset_str == 0xDEADBEEF) { - *((uint32_t *)0x2000FFF0) = 0x00; - asm("ldr r0, =0x1fffb000"); - asm("ldr sp, [r0, #0]"); - asm("ldr r0, [r0, #4]"); - asm("bx r0"); - } - __asm__("MSR msp, %0" : : "r"(&_stack)); - - for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) - *dest = *src; - - while (dest < &_ebss) - *dest++ = 0; - - /* Call the application's entry point. */ - main(); -} - -void blocking_handler(void) -{ - while (1) ; -} - -void null_handler(void) -{ - /* Do nothing. */ -} - -#pragma weak nmi_handler = null_handler -#pragma weak hard_fault_handler = blocking_handler -#pragma weak mem_manage_handler = blocking_handler -#pragma weak bus_fault_handler = blocking_handler -#pragma weak usage_fault_handler = blocking_handler -#pragma weak sv_call_handler = null_handler -#pragma weak debug_monitor_handler = null_handler -#pragma weak pend_sv_handler = null_handler -#pragma weak sys_tick_handler = null_handler -#pragma weak wwdg_isr = null_handler -#pragma weak pvd_isr = null_handler -#pragma weak tamper_isr = null_handler -#pragma weak rtc_isr = null_handler -#pragma weak flash_isr = null_handler -#pragma weak rcc_isr = null_handler -#pragma weak exti0_isr = null_handler -#pragma weak exti1_isr = null_handler -#pragma weak exti2_isr = null_handler -#pragma weak exti3_isr = null_handler -#pragma weak exti4_isr = null_handler -#pragma weak dma1_channel1_isr = null_handler -#pragma weak dma1_channel2_isr = null_handler -#pragma weak dma1_channel3_isr = null_handler -#pragma weak dma1_channel4_isr = null_handler -#pragma weak dma1_channel5_isr = null_handler -#pragma weak dma1_channel6_isr = null_handler -#pragma weak dma1_channel7_isr = null_handler -#pragma weak adc1_2_isr = null_handler -#pragma weak usb_hp_can_tx_isr = null_handler -#pragma weak usb_lp_can_rx0_isr = null_handler -#pragma weak can_rx1_isr = null_handler -#pragma weak can_sce_isr = null_handler -#pragma weak exti9_5_isr = null_handler -#pragma weak tim1_brk_isr = null_handler -#pragma weak tim1_up_isr = null_handler -#pragma weak tim1_trg_com_isr = null_handler -#pragma weak tim1_cc_isr = null_handler -#pragma weak tim2_isr = null_handler -#pragma weak tim3_isr = null_handler -#pragma weak tim4_isr = null_handler -#pragma weak i2c1_ev_isr = null_handler -#pragma weak i2c1_er_isr = null_handler -#pragma weak i2c2_ev_isr = null_handler -#pragma weak i2c2_er_isr = null_handler -#pragma weak spi1_isr = null_handler -#pragma weak spi2_isr = null_handler -#pragma weak usart1_isr = null_handler -#pragma weak usart2_isr = null_handler -#pragma weak usart3_isr = null_handler -#pragma weak exti15_10_isr = null_handler -#pragma weak rtc_alarm_isr = null_handler -#pragma weak usb_wakeup_isr = null_handler -#pragma weak tim8_brk_isr = null_handler -#pragma weak tim8_up_isr = null_handler -#pragma weak tim8_trg_com_isr = null_handler -#pragma weak tim8_cc_isr = null_handler -#pragma weak adc3_isr = null_handler -#pragma weak fsmc_isr = null_handler -#pragma weak sdio_isr = null_handler -#pragma weak tim5_isr = null_handler -#pragma weak spi3_isr = null_handler -#pragma weak uart4_isr = null_handler -#pragma weak uart5_isr = null_handler -#pragma weak tim6_isr = null_handler -#pragma weak tim7_isr = null_handler -#pragma weak dma2_channel1_isr = null_handler -#pragma weak dma2_channel2_isr = null_handler -#pragma weak dma2_channel3_isr = null_handler -#pragma weak dma2_channel4_5_isr = null_handler -#pragma weak dma2_channel5_isr -#pragma weak eth_isr = null_handler -#pragma weak eth_wkup_isr = null_handler -#pragma weak can2_tx_isr = null_handler -#pragma weak can2_rx0_isr = null_handler -#pragma weak can2_rx1_isr = null_handler -#pragma weak can2_sce_isr = null_handler -#pragma weak otg_fs_isr = null_handler diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile index c127d61f..b64a0338 100644 --- a/lib/stm32/f2/Makefile +++ b/lib/stm32/f2/Makefile @@ -28,8 +28,8 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ -ffunction-sections -fdata-sections -MD -DSTM32F2 # ARFLAGS = rcsv ARFLAGS = rcs -OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \ - i2c.o systick.o exti.o scb.o timer.o assert.o +OBJS = rcc.o gpio2.o usart.o spi.o flash.o \ + i2c.o exti2.o timer.o VPATH += ../../usb:../:../../cm3 diff --git a/lib/stm32/f2/timer.c b/lib/stm32/f2/timer.c deleted file mode 100644 index 659f8a99..00000000 --- a/lib/stm32/f2/timer.c +++ /dev/null @@ -1,928 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org> - * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Basic TIMER handling API. - * - * Examples: - * timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT_MUL_2, - * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP); - */ - -#include <libopencm3/stm32/f2/timer.h> -#include <libopencm3/stm32/f2/rcc.h> - -void timer_reset(u32 timer_peripheral) -{ - switch (timer_peripheral) { - case TIM1: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST); - break; - case TIM2: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST); - break; - case TIM3: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST); - break; - case TIM4: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST); - break; - case TIM5: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST); - break; - case TIM6: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST); - break; - case TIM7: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST); - break; - case TIM8: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST); - break; -/* These timers are not supported in libopencm3 yet */ -/* - case TIM9: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST); - break; - case TIM10: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST); - break; - case TIM11: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST); - break; - case TIM12: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST); - break; - case TIM13: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST); - break; - case TIM14: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST); - break; -*/ - } -} - -void timer_enable_irq(u32 timer_peripheral, u32 irq) -{ - TIM_DIER(timer_peripheral) |= irq; -} - -void timer_disable_irq(u32 timer_peripheral, u32 irq) -{ - TIM_DIER(timer_peripheral) &= ~irq; -} - -bool timer_get_flag(u32 timer_peripheral, u32 flag) -{ - if (((TIM_SR(timer_peripheral) & flag) != 0) && - ((TIM_DIER(timer_peripheral) & flag) != 0)) { - return true; - } - - return false; -} - -void timer_clear_flag(u32 timer_peripheral, u32 flag) -{ - TIM_SR(timer_peripheral) &= ~flag; -} - -void timer_set_mode(u32 timer_peripheral, u32 clock_div, - u32 alignment, u32 direction) -{ - u32 cr1; - - cr1 = TIM_CR1(timer_peripheral); - - cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | TIM_CR1_CMS_MASK | TIM_CR1_DIR_DOWN); - - cr1 |= clock_div | alignment | direction; - - TIM_CR1(timer_peripheral) = cr1; -} - -void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) -{ - clock_div &= TIM_CR1_CKD_CK_INT_MASK; - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK; - TIM_CR1(timer_peripheral) |= clock_div; -} - -void timer_enable_preload(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE; -} - -void timer_disable_preload(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE; -} - -void timer_set_alignment(u32 timer_peripheral, u32 alignment) -{ - alignment &= TIM_CR1_CMS_MASK; - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK; - TIM_CR1(timer_peripheral) |= alignment; -} - -void timer_direction_up(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN; -} - -void timer_direction_down(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN; -} - -void timer_one_shot_mode(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_OPM; -} - -void timer_continuous_mode(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM; -} - -void timer_update_on_any(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS; -} - -void timer_update_on_overflow(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_URS; -} - -void timer_enable_update_event(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS; -} - -void timer_disable_update_event(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS; -} - -void timer_enable_counter(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_CEN; -} - -void timer_disable_counter(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN; -} - -void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs) -{ - TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; -} - -void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs) -{ - TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); -} - -void timer_set_ti1_ch123_xor(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S; -} - -void timer_set_ti1_ch1(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S; -} - -void timer_set_master_mode(u32 timer_peripheral, u32 mode) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK; - TIM_CR2(timer_peripheral) |= mode; -} - -void timer_set_dma_on_compare_event(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS; -} - -void timer_set_dma_on_update_event(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS; -} - -void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; -} - -void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; -} - -void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; -} - -void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; -} - -void timer_set_prescaler(u32 timer_peripheral, u32 value) -{ - TIM_PSC(timer_peripheral) = value; -} - -void timer_set_repetition_counter(u32 timer_peripheral, u32 value) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_RCR(timer_peripheral) = value; -} - -void timer_set_period(u32 timer_peripheral, u32 period) -{ - TIM_ARR(timer_peripheral) = period; -} - -void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, - enum tim_oc_mode oc_mode) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT; - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR1(timer_peripheral) |= - TIM_CCMR1_OC1M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM2; - break; - } - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT; - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR1(timer_peripheral) |= - TIM_CCMR1_OC2M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM2; - break; - } - break; - case TIM_OC3: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC3S_OUT; - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC3M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR2(timer_peripheral) |= - TIM_CCMR2_OC3M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM2; - break; - } - break; - case TIM_OC4: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC4S_OUT; - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC4M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR2(timer_peripheral) |= - TIM_CCMR2_OC4M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM2; - break; - } - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - /* Acting for TIM1 and TIM8 only. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1; - break; - case TIM_OC1N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N; - break; - case TIM_OC2: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2; - break; - case TIM_OC2N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N; - break; - case TIM_OC3: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3; - break; - case TIM_OC3N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N; - break; - case TIM_OC4: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4; - break; - } -} - -void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - /* Acting for TIM1 and TIM8 only. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1; - break; - case TIM_OC1N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N; - break; - case TIM_OC2: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2; - break; - case TIM_OC2N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N; - break; - case TIM_OC3: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3; - break; - case TIM_OC3N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N; - break; - case TIM_OC4: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4; - break; - } -} - -void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCR1(timer_peripheral) = value; - break; - case TIM_OC2: - TIM_CCR2(timer_peripheral) = value; - break; - case TIM_OC3: - TIM_CCR3(timer_peripheral) = value; - break; - case TIM_OC4: - TIM_CCR4(timer_peripheral) = value; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_enable_break_main_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE; -} - -void timer_disable_break_main_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE; -} - -void timer_enable_break_automatic_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE; -} - -void timer_disable_break_automatic_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE; -} - -void timer_set_break_polarity_high(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP; -} - -void timer_set_break_polarity_low(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP; -} - -void timer_enable_break(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE; -} - -void timer_disable_break(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE; -} - -void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR; -} - -void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR; -} - -void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI; -} - -void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI; -} - -void timer_set_break_lock(u32 timer_peripheral, u32 lock) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= lock; -} - -void timer_set_deadtime(u32 timer_peripheral, u32 deadtime) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= deadtime; -} - -void timer_generate_event(u32 timer_peripheral, u32 event) -{ - TIM_EGR(timer_peripheral) |= event; -} - -u32 timer_get_counter(u32 timer_peripheral) -{ - return TIM_CNT(timer_peripheral); -} - -void timer_set_option(u32 timer_peripheral, u32 option) -{ - if (timer_peripheral == TIM2) { - TIM_OR(timer_peripheral) &= ~TIM2_OR_ITR1_RMP_MASK; - TIM_OR(timer_peripheral) |= option; - } else if (timer_peripheral == TIM5) { - TIM_OR(timer_peripheral) &= ~TIM5_OR_TI4_RMP_MASK; - TIM_OR(timer_peripheral) |= option; - } -} diff --git a/lib/stm32/f2/vector.c b/lib/stm32/f2/vector.c deleted file mode 100644 index 3429bfb0..00000000 --- a/lib/stm32/f2/vector.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> - * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#define WEAK __attribute__ ((weak)) - -/* Symbols exported by the linker script(s): */ -extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; - -void main(void); -void reset_handler(void); -void blocking_handler(void); -void null_handler(void); - -void WEAK reset_handler(void); -void WEAK nmi_handler(void); -void WEAK hard_fault_handler(void); -void WEAK mem_manage_handler(void); -void WEAK bus_fault_handler(void); -void WEAK usage_fault_handler(void); -void WEAK sv_call_handler(void); -void WEAK debug_monitor_handler(void); -void WEAK pend_sv_handler(void); -void WEAK sys_tick_handler(void); -void WEAK wwdg_isr(void); -void WEAK pvd_isr(void); -void WEAK tamp_stamp_isr(void); -void WEAK rtc_wkup_isr(void); -void WEAK flash_isr(void); -void WEAK rcc_isr(void); -void WEAK exti0_isr(void); -void WEAK exti1_isr(void); -void WEAK exti2_isr(void); -void WEAK exti3_isr(void); -void WEAK exti4_isr(void); -void WEAK dma1_stream0_isr(void); -void WEAK dma1_stream1_isr(void); -void WEAK dma1_stream2_isr(void); -void WEAK dma1_stream3_isr(void); -void WEAK dma1_stream4_isr(void); -void WEAK dma1_stream5_isr(void); -void WEAK dma1_stream6_isr(void); -void WEAK adc_isr(void); -void WEAK can1_tx_isr(void); -void WEAK can1_rx0_isr(void); -void WEAK can1_rx1_isr(void); -void WEAK can1_sce_isr(void); -void WEAK exti9_5_isr(void); -void WEAK tim1_brk_tim9_isr(void); -void WEAK tim1_up_tim10_isr(void); -void WEAK tim1_trg_com_tim11_isr(void); -void WEAK tim1_cc_isr(void); -void WEAK tim2_isr(void); -void WEAK tim3_isr(void); -void WEAK tim4_isr(void); -void WEAK i2c1_ev_isr(void); -void WEAK i2c1_er_isr(void); -void WEAK i2c2_ev_isr(void); -void WEAK i2c2_er_isr(void); -void WEAK spi1_isr(void); -void WEAK spi2_isr(void); -void WEAK usart1_isr(void); -void WEAK usart2_isr(void); -void WEAK usart3_isr(void); -void WEAK exti15_10_isr(void); -void WEAK rtc_alarm_isr(void); -void WEAK usb_fs_wkup_isr(void); -void WEAK tim8_brk_tim12_isr(void); -void WEAK tim8_up_tim13_isr(void); -void WEAK tim8_trg_com_tim14_isr(void); -void WEAK tim8_cc_isr(void); -void WEAK dma1_stream7_isr(void); -void WEAK fsmc_isr(void); -void WEAK sdio_isr(void); -void WEAK tim5_isr(void); -void WEAK spi3_isr(void); -void WEAK uart4_isr(void); -void WEAK uart5_isr(void); -void WEAK tim6_dac_isr(void); -void WEAK tim7_isr(void); -void WEAK dma2_stream0_isr(void); -void WEAK dma2_stream1_isr(void); -void WEAK dma2_stream2_isr(void); -void WEAK dma2_stream3_isr(void); -void WEAK dma2_stream4_isr(void); -void WEAK eth_isr(void); -void WEAK eth_wkup_isr(void); -void WEAK can2_tx_isr(void); -void WEAK can2_rx0_isr(void); -void WEAK can2_rx1_isr(void); -void WEAK can2_sce_isr(void); -void WEAK otg_fs_isr(void); -void WEAK dma2_stream5_isr(void); -void WEAK dma2_stream6_isr(void); -void WEAK dma2_stream7_isr(void); -void WEAK usart6_isr(void); -void WEAK i2c3_ev_isr(void); -void WEAK i2c3_er_isr(void); -void WEAK otg_hs_ep1_out_isr(void); -void WEAK otg_hs_ep1_in_isr(void); -void WEAK otg_hs_wkup_isr(void); -void WEAK otg_hs_isr(void); -void WEAK dcmi_isr(void); -void WEAK cryp_isr(void); -void WEAK hash_rng_isr(void); - -__attribute__ ((section(".vectors"))) -void (*const vector_table[]) (void) = { - (void *)&_stack, - reset_handler, - nmi_handler, - hard_fault_handler, - mem_manage_handler, - bus_fault_handler, - usage_fault_handler, - 0, 0, 0, 0, /* Reserved */ - sv_call_handler, - debug_monitor_handler, - 0, /* Reserved */ - pend_sv_handler, - sys_tick_handler, - wwdg_isr, - pvd_isr, - tamp_stamp_isr, - rtc_wkup_isr, - flash_isr, - rcc_isr, - exti0_isr, - exti1_isr, - exti2_isr, - exti3_isr, - exti4_isr, - dma1_stream0_isr, - dma1_stream1_isr, - dma1_stream2_isr, - dma1_stream3_isr, - dma1_stream4_isr, - dma1_stream5_isr, - dma1_stream6_isr, - adc_isr, - can1_tx_isr, - can1_rx0_isr, - can1_rx1_isr, - can1_sce_isr, - exti9_5_isr, - tim1_brk_tim9_isr, - tim1_up_tim10_isr, - tim1_trg_com_tim11_isr, - tim1_cc_isr, - tim2_isr, - tim3_isr, - tim4_isr, - i2c1_ev_isr, - i2c1_er_isr, - i2c2_ev_isr, - i2c2_er_isr, - spi1_isr, - spi2_isr, - usart1_isr, - usart2_isr, - usart3_isr, - exti15_10_isr, - rtc_alarm_isr, - usb_fs_wkup_isr, - tim8_brk_tim12_isr, - tim8_up_tim13_isr, - tim8_trg_com_tim14_isr, - tim8_cc_isr, - dma1_stream7_isr, - fsmc_isr, - sdio_isr, - tim5_isr, - spi3_isr, - uart4_isr, - uart5_isr, - tim6_dac_isr, - tim7_isr, - dma2_stream0_isr, - dma2_stream1_isr, - dma2_stream2_isr, - dma2_stream3_isr, - dma2_stream4_isr, - eth_isr, - eth_wkup_isr, - can2_tx_isr, - can2_rx0_isr, - can2_rx1_isr, - can2_sce_isr, - otg_fs_isr, - dma2_stream5_isr, - dma2_stream6_isr, - dma2_stream7_isr, - usart6_isr, - i2c3_ev_isr, - i2c3_er_isr, - otg_hs_ep1_out_isr, - otg_hs_ep1_in_isr, - otg_hs_wkup_isr, - otg_hs_isr, - dcmi_isr, - cryp_isr, - hash_rng_isr, -}; - -void reset_handler(void) -{ - volatile unsigned *src, *dest; - - __asm__("MSR msp, %0" : : "r"(&_stack)); - - for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) - *dest = *src; - - while (dest < &_ebss) - *dest++ = 0; - - /* Call the application's entry point. */ - main(); -} - -void blocking_handler(void) -{ - while (1) ; -} - -void null_handler(void) -{ - /* Do nothing. */ -} - -#pragma weak nmi_handler = null_handler -#pragma weak hard_fault_handler = blocking_handler -#pragma weak mem_manage_handler = blocking_handler -#pragma weak bus_fault_handler = blocking_handler -#pragma weak usage_fault_handler = blocking_handler -#pragma weak sv_call_handler = null_handler -#pragma weak debug_monitor_handler = null_handler -#pragma weak pend_sv_handler = null_handler -#pragma weak sys_tick_handler = null_handler -#pragma weak wwdg_isr = null_handler -#pragma weak pvd_isr = null_handler -#pragma weak tamp_stamp_isr = null_handler -#pragma weak rtc_wkup_isr = null_handler -#pragma weak flash_isr = null_handler -#pragma weak rcc_isr = null_handler -#pragma weak exti0_isr = null_handler -#pragma weak exti1_isr = null_handler -#pragma weak exti2_isr = null_handler -#pragma weak exti3_isr = null_handler -#pragma weak exti4_isr = null_handler -#pragma weak dma1_stream0_isr = null_handler -#pragma weak dma1_stream1_isr = null_handler -#pragma weak dma1_stream2_isr = null_handler -#pragma weak dma1_stream3_isr = null_handler -#pragma weak dma1_stream4_isr = null_handler -#pragma weak dma1_stream5_isr = null_handler -#pragma weak dma1_stream6_isr = null_handler -#pragma weak adc_isr = null_handler -#pragma weak can1_tx_isr = null_handler -#pragma weak can1_rx0_isr = null_handler -#pragma weak can1_rx1_isr = null_handler -#pragma weak can1_sce_isr = null_handler -#pragma weak exti9_5_isr = null_handler -#pragma weak tim1_brk_tim9_isr = null_handler -#pragma weak tim1_up_tim10_isr = null_handler -#pragma weak tim1_trg_com_tim11_isr = null_handler -#pragma weak tim1_cc_isr = null_handler -#pragma weak tim2_isr = null_handler -#pragma weak tim3_isr = null_handler -#pragma weak tim4_isr = null_handler -#pragma weak i2c1_ev_isr = null_handler -#pragma weak i2c1_er_isr = null_handler -#pragma weak i2c2_ev_isr = null_handler -#pragma weak i2c2_er_isr = null_handler -#pragma weak spi1_isr = null_handler -#pragma weak spi2_isr = null_handler -#pragma weak usart1_isr = null_handler -#pragma weak usart2_isr = null_handler -#pragma weak usart3_isr = null_handler -#pragma weak exti15_10_isr = null_handler -#pragma weak rtc_alarm_isr = null_handler -#pragma weak usb_fs_wkup_isr = null_handler -#pragma weak tim8_brk_tim12_isr = null_handler -#pragma weak tim8_up_tim13_isr = null_handler -#pragma weak tim8_trg_com_tim14_isr = null_handler -#pragma weak tim8_cc_isr = null_handler -#pragma weak dma1_stream7_isr = null_handler -#pragma weak fsmc_isr = null_handler -#pragma weak sdio_isr = null_handler -#pragma weak tim5_isr = null_handler -#pragma weak spi3_isr = null_handler -#pragma weak uart4_isr = null_handler -#pragma weak uart5_isr = null_handler -#pragma weak tim6_dac_isr = null_handler -#pragma weak tim7_isr = null_handler -#pragma weak dma2_stream0_isr = null_handler -#pragma weak dma2_stream1_isr = null_handler -#pragma weak dma2_stream2_isr = null_handler -#pragma weak dma2_stream3_isr = null_handler -#pragma weak dma2_stream4_isr = null_handler -#pragma weak eth_isr = null_handler -#pragma weak eth_wkup_isr = null_handler -#pragma weak can2_tx_isr = null_handler -#pragma weak can2_rx0_isr = null_handler -#pragma weak can2_rx1_isr = null_handler -#pragma weak can2_sce_isr = null_handler -#pragma weak otg_fs_isr = null_handler -#pragma weak dma2_stream5_isr = null_handler -#pragma weak dma2_stream6_isr = null_handler -#pragma weak dma2_stream7_isr = null_handler -#pragma weak usart6_isr = null_handler -#pragma weak i2c3_ev_isr = null_handler -#pragma weak i2c3_er_isr = null_handler -#pragma weak otg_hs_ep1_out_isr = null_handler -#pragma weak otg_hs_ep1_in_isr = null_handler -#pragma weak otg_hs_wkup_isr = null_handler -#pragma weak otg_hs_isr = null_handler -#pragma weak dcmi_isr = null_handler -#pragma weak cryp_isr = null_handler -#pragma weak hash_rng_isr = null_handler diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index fd0b2793..09fe5732 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -29,10 +29,10 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ -ffunction-sections -fdata-sections -MD -DSTM32F4 # ARFLAGS = rcsv ARFLAGS = rcs -OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \ - i2c.o systick.o exti.o scb.o pwr.o timer.o \ - usb.o usb_standard.o usb_control.o usb_f107.o \ - assert.o +OBJS = rcc.o gpio2.o usart.o spi.o flash.o \ + i2c.o exti2.o pwr.o timer.o \ + usb.o usb_standard.o usb_control.o usb_fx07_common.o usb_f107.o \ + usb_f207.o adc.o dma.o VPATH += ../../usb:../:../../cm3 diff --git a/lib/stm32/f4/adc.c b/lib/stm32/f4/adc.c new file mode 100644 index 00000000..7475fac8 --- /dev/null +++ b/lib/stm32/f4/adc.c @@ -0,0 +1,1027 @@ +/** @defgroup STM32F4xx_adc_file ADC + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx Analog to Digital Converters</b> + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net> + +@date 30 August 2012 + +This library supports the A/D Converter Control System in the STM32 series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Devices can have up to three A/D converters each with their own set of registers. +However all the A/D converters share a common clock which is prescaled from the APB2 +clock by default by a minimum factor of 2 to a maximum of 8. The ADC resolution +can be set to 12, 10, 8 or 6 bits. + +Each A/D converter has up to 19 channels: +@li On ADC1 the analog channels 16 is internally connected to the temperature +sensor, channel 17 to V<sub>REFINT</sub>, and channel 18 to V<sub>BATT</sub>. +@li On ADC2 and ADC3 the analog channels 16 - 18 are not used. + +The conversions can occur as a one-off conversion whereby the process stops once +conversion is complete. The conversions can also be continuous wherein a new +conversion starts immediately the previous conversion has ended. + +Conversion can occur as a single channel conversion or a scan of a group of +channels in either continuous or one-off mode. If more than one channel is converted +in a scan group, DMA must be used to transfer the data as there is only one +result register available. An interrupt can be set to occur at the end of +conversion, which occurs after all channels have been scanned. + +A discontinuous mode allows a subgroup of group of a channels to be converted in +bursts of a given length. + +Injected conversions allow a second group of channels to be converted separately +from the regular group. An interrupt can be set to occur at the end of +conversion, which occurs after all channels have been scanned. + +@section adc_f4_api_ex Basic ADC Handling API. + +Example 1: Simple single channel conversion polled. Enable the peripheral clock +and ADC, reset ADC and set the prescaler divider. Set multiple mode to independent. + +@code +gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1); +rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); +adc_set_clk_prescale(RCC_CFGR_ADCPRE_BY2); +adc_disable_scan_mode(ADC1); +adc_set_single_conversion_mode(ADC1); +adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); +u8 channels[] = ADC_CHANNEL0; +adc_set_regular_sequence(ADC1, 1, channels); +adc_set_multi_mode(ADC_CCR_MULTI_INDEPENDENT); +adc_power_on(ADC1); +adc_start_conversion_regular(ADC1); +while (! adc_eoc(ADC1)); +reg16 = adc_read_regular(ADC1); +@endcode + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies <ksarkies@internode.on.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/f4/adc.h> + +/**@{*/ + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Off + +Turn off the ADC to reduce power consumption to a few microamps. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_off(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_ADON; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Regular Conversions + +The analog watchdog allows the monitoring of an analog signal between two threshold +levels. The thresholds must be preset. Comparison is done before data alignment +takes place, so the thresholds are left-aligned. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_analog_watchdog_regular(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_AWDEN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog for Regular Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_analog_watchdog_regular(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_AWDEN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Injected Conversions + +The analog watchdog allows the monitoring of an analog signal between two threshold +levels. The thresholds must be preset. Comparison is done before data alignment +takes place, so the thresholds are left-aligned. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_analog_watchdog_injected(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_JAWDEN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog for Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_analog_watchdog_injected(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JAWDEN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Regular Conversions + +In this mode the ADC converts, on each trigger, a subgroup of up to 8 of the +defined regular channel group. The subgroup is defined by the number of +consecutive channels to be converted. After a subgroup has been converted +the next trigger will start conversion of the immediately following subgroup +of the same length or until the whole group has all been converted. When the +the whole group has been converted, the next trigger will restart conversion +of the subgroup at the beginning of the whole group. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] length Unsigned int8. Number of channels in the group @ref adc_cr1_discnum +*/ + +void adc_enable_discontinuous_mode_regular(u32 adc, u8 length) +{ + if ( (length-1) > 7 ) return; + ADC_CR1(adc) |= ADC_CR1_DISCEN; + ADC_CR2(adc) |= ((length-1) << ADC_CR1_DISCNUM_SHIFT); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Regular Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_discontinuous_mode_regular(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_DISCEN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Injected Conversions + +In this mode the ADC converts sequentially one channel of the defined group of +injected channels, cycling back to the first channel in the group once the +entire group has been converted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_discontinuous_mode_injected(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_JDISCEN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_discontinuous_mode_injected(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JDISCEN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Automatic Injected Conversions + +The ADC converts a defined injected group of channels immediately after the +regular channels have been converted. The external trigger on the injected +channels is disabled as required. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_automatic_injected_group_conversion(u32 adc) +{ + adc_disable_external_trigger_injected(adc); + ADC_CR1(adc) |= ADC_CR1_JAUTO; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Automatic Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_automatic_injected_group_conversion(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JAUTO; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for All Regular and/or Injected Channels + +The analog watchdog allows the monitoring of an analog signal between two threshold +levels. The thresholds must be preset. Comparison is done before data alignment +takes place, so the thresholds are left-aligned. + +@note The analog watchdog must be enabled for either or both of the regular or +injected channels. If neither are enabled, the analog watchdog feature will be +disabled. +@ref adc_enable_analog_watchdog_injected, @ref adc_enable_analog_watchdog_regular. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_analog_watchdog_on_all_channels(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_AWDSGL; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for a Selected Channel + +The analog watchdog allows the monitoring of an analog signal between two threshold +levels. The thresholds must be preset. Comparison is done before data alignment +takes place, so the thresholds are left-aligned. + +@note The analog watchdog must be enabled for either or both of the regular or +injected channels. If neither are enabled, the analog watchdog feature will be +disabled. If both are enabled, the same channel number is monitored. +@ref adc_enable_analog_watchdog_injected, @ref adc_enable_analog_watchdog_regular. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] channel Unsigned int8. ADC channel number @ref adc_watchdog_channel +*/ + +void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel) +{ + u32 reg32; + + reg32 = (ADC_CR1(adc) & ~ADC_CR1_AWDCH_MASK); /* Clear bits [4:0]. */ + if (channel < 18) + reg32 |= channel; + ADC_CR1(adc) = reg32; + ADC_CR1(adc) |= ADC_CR1_AWDSGL; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Scan Mode + +In this mode a conversion consists of a scan of the predefined set of channels, +regular and injected, each channel conversion immediately following the +previous one. It can use single, continuous or discontinuous mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_scan_mode(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_SCAN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Scan Mode + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_scan_mode(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_SCAN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Injected End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_eoc_interrupt_injected(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_JEOCIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Injected End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_eoc_interrupt_injected(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JEOCIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_awd_interrupt(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_AWDIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_awd_interrupt(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_AWDIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Regular End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_eoc_interrupt(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_EOCIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Regular End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_eoc_interrupt(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_EOCIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Regular Channels + +This starts conversion on a set of defined regular channels. It is cleared by +hardware once conversion starts. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_start_conversion_regular(u32 adc) +{ + /* Start conversion on regular channels. */ + ADC_CR2(adc) |= ADC_CR2_SWSTART; + + /* Wait until the ADC starts the conversion. */ + while (ADC_CR2(adc) & ADC_CR2_SWSTART); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Injected Channels + +This starts conversion on a set of defined injected channels. It is cleared by +hardware once conversion starts. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_start_conversion_injected(u32 adc) +{ + /* Start conversion on injected channels. */ + ADC_CR2(adc) |= ADC_CR2_JSWSTART; + + /* Wait until the ADC starts the conversion. */ + while (ADC_CR2(adc) & ADC_CR2_JSWSTART); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Data as Left Aligned + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_left_aligned(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_ALIGN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Data as Right Aligned + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_right_aligned(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_ALIGN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable DMA Transfers + +Only available for ADC1 through DMA1 channel1, and ADC3 through DMA2 channel5. +ADC2 will use DMA if it is set as slave in dual mode with ADC1 in DMA transfer +mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_dma(u32 adc) +{ + if ((adc == ADC1) | (adc == ADC3)) + ADC_CR2(adc) |= ADC_CR2_DMA; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable DMA Transfers + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_dma(u32 adc) +{ + if ((adc == ADC1) | (adc == ADC3)) + ADC_CR2(adc) &= ~ADC_CR2_DMA; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Continuous Conversion Mode + +In this mode the ADC starts a new conversion of a single channel or a channel +group immediately following completion of the previous channel group conversion. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_continuous_conversion_mode(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_CONT; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Single Conversion Mode + +In this mode the ADC performs a conversion of one channel or a channel group +and stops. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_single_conversion_mode(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_CONT; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for a Single Channel + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] channel Unsigned int8. ADC Channel integer 0..18 or from @ref adc_channel +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg +*/ + +void adc_set_sample_time(u32 adc, u8 channel, u8 time) +{ + u32 reg32; + + if (channel < 10) { + reg32 = ADC_SMPR2(adc); + reg32 &= ~(0x7 << (channel * 3)); + reg32 |= (time << (channel * 3)); + ADC_SMPR2(adc) = reg32; + } else { + reg32 = ADC_SMPR1(adc); + reg32 &= ~(0x7 << ((channel - 10) * 3)); + reg32 |= (time << ((channel - 10) * 3)); + ADC_SMPR1(adc) = reg32; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for All Channels + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5, same for +all channels. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg +*/ + +void adc_set_sample_time_on_all_channels(u32 adc, u8 time) +{ + u8 i; + u32 reg32 = 0; + + for (i = 0; i <= 9; i++) + reg32 |= (time << (i * 3)); + ADC_SMPR2(adc) = reg32; + + for (i = 10; i <= 17; i++) + reg32 |= (time << ((i - 10) * 3)); + ADC_SMPR1(adc) = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Upper Threshold + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] threshold Unsigned int8. Upper threshold value +*/ + +void adc_set_watchdog_high_threshold(u32 adc, u16 threshold) +{ + u32 reg32 = 0; + + reg32 = (u32)threshold; + reg32 &= ~0xfffff000; /* Clear all bits above 11. */ + ADC_HTR(adc) = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Lower Threshold + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] threshold Unsigned int8. Lower threshold value +*/ + +void adc_set_watchdog_low_threshold(u32 adc, u16 threshold) +{ + u32 reg32 = 0; + + reg32 = (u32)threshold; + reg32 &= ~0xfffff000; /* Clear all bits above 11. */ + ADC_LTR(adc) = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set a Regular Channel Conversion Sequence + +Define a sequence of channels to be converted as a regular group with a length +from 1 to 16 channels. If this is called during conversion, the current conversion +is reset and conversion begins again with the newly defined group. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] length Unsigned int8. Number of channels in the group. +@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..18. +*/ + +void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]) +{ + u32 reg32_1 = 0, reg32_2 = 0, reg32_3 = 0; + u8 i = 0; + + /* Maximum sequence length is 16 channels. */ + if (length > 16) + return; + + for (i = 1; i <= length; i++) { + if (i <= 6) + reg32_3 |= (channel[i - 1] << ((i - 1) * 5)); + if ((i > 6) & (i <= 12)) + reg32_2 |= (channel[i - 1] << ((i - 6 - 1) * 5)); + if ((i > 12) & (i <= 16)) + reg32_1 |= (channel[i - 1] << ((i - 12 - 1) * 5)); + } + reg32_1 |= ((length -1) << ADC_SQR1_L_LSB); + + ADC_SQR1(adc) = reg32_1; + ADC_SQR2(adc) = reg32_2; + ADC_SQR3(adc) = reg32_3; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set an Injected Channel Conversion Sequence + +Defines a sequence of channels to be converted as an injected group with a length +from 1 to 4 channels. If this is called during conversion, the current conversion +is reset and conversion begins again with the newly defined group. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] length Unsigned int8. Number of channels in the group. +@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..18 +*/ + +void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]) +{ + u32 reg32 = 0; + u8 i = 0; + + /* Maximum sequence length is 4 channels. */ + if ((length-1) > 3) + return; + + for (i = 1; i <= length; i++) + reg32 |= (channel[4 - i] << ((4 - i) * 5)); + + reg32 |= ((length - 1) << ADC_JSQR_JL_LSB); + + ADC_JSQR(adc) = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Conversion Flag + +This flag is set after all channels of a regular or injected group have been +converted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. End of conversion flag. +*/ + +bool adc_eoc(u32 adc) +{ + return ((ADC_SR(adc) & ADC_SR_EOC) != 0); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Conversion Flag for Injected Conversion + +This flag is set after all channels of an injected group have been converted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. End of conversion flag. +*/ + +bool adc_eoc_injected(u32 adc) +{ + return ((ADC_SR(adc) & ADC_SR_JEOC) != 0); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read from the Regular Conversion Result Register + +The result read back is 12 bits, right or left aligned within the first 16 bits. +For ADC1 only, the higher 16 bits will hold the result from ADC2 if +an appropriate dual mode has been set @see adc_set_dual_mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +u32 adc_read_regular(u32 adc) +{ + return ADC_DR(adc); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read from an Injected Conversion Result Register + +The result read back from the selected injected result register (one of four) is +12 bits, right or left aligned within the first 16 bits. The result can have a +negative value if the injected channel offset has been set @see adc_set_injected_offset. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] reg Unsigned int8. Register number (1 ... 4). +@returns Unsigned int32 conversion result. +*/ + +u32 adc_read_injected(u32 adc, u8 reg) +{ + switch (reg) { + case 1: + return ADC_JDR1(adc); + case 2: + return ADC_JDR2(adc); + case 3: + return ADC_JDR3(adc); + case 4: + return ADC_JDR4(adc); + } + return 0; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Injected Channel Data Offset + +This value is subtracted from the injected channel results after conversion +is complete, and can result in negative results. A separate value can be specified +for each injected data register. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] reg Unsigned int8. Register number (1 ... 4). +@param[in] offset Unsigned int32. +*/ + +void adc_set_injected_offset(u32 adc, u8 reg, u32 offset) +{ + switch (reg) { + case 1: + ADC_JOFR1(adc) = offset; + break; + case 2: + ADC_JOFR2(adc) = offset; + break; + case 3: + ADC_JOFR3(adc) = offset; + break; + case 4: + ADC_JOFR4(adc) = offset; + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Power On + +If the ADC is in power-down mode then it is powered up. The application needs +to wait a time of about 3 microseconds for stabilization before using the ADC. +If the ADC is already on this function call will have no effect. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_power_on(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_ADON; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Prescale + +The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. + +@param[in] prescale Unsigned int32. Prescale value for ADC Clock @ref adc_ccr_adcpre +*/ + +void adc_set_clk_prescale(u32 prescale) +{ + u32 reg32 = ((ADC_CCR & ~ADC_CCR_ADCPRE_MASK) | prescale); + ADC_CCR = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Dual/Triple Mode + +The multiple mode uses ADC1 as master, ADC2 and optionally ADC3 in a slave +arrangement. This setting is applied to ADC1 only. + +The various modes possible are described in the reference manual. + +@param[in] mode Unsigned int32. Multiple mode selection from @ref adc_multi_mode +*/ + +void adc_set_multi_mode(u32 mode) +{ + ADC_CCR |= mode; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + +This enables an external trigger for set of defined regular channels, and sets the +polarity of the trigger event: rising or falling edge or both. Note that if the +trigger polarity is zero, triggering is disabled. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int32. Trigger identifier @ref adc_trigger_regular +@param[in] polarity Unsigned int32. Trigger polarity @ref adc_trigger_polarity_regular +*/ + +void adc_enable_external_trigger_regular(u32 adc, u32 trigger, u32 polarity) +{ + u32 reg32 = ADC_CR2(adc); + + reg32 &= ~(ADC_CR2_EXTSEL_MASK | ADC_CR2_EXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CR2(adc) = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_external_trigger_regular(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EXTEN_MASK; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + +This enables an external trigger for set of defined injected channels, and sets the +polarity of the trigger event: rising or falling edge or both. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_injected +@param[in] polarity Unsigned int32. Trigger polarity @ref adc_trigger_polarity_injected +*/ + +void adc_enable_external_trigger_injected(u32 adc, u32 trigger, u32 polarity) +{ + u32 reg32 = ADC_CR2(adc); + + reg32 &= ~(ADC_CR2_JEXTSEL_MASK | ADC_CR2_JEXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CR2(adc) = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Injected Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_external_trigger_injected(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_JEXTEN_MASK; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Resolution + +ADC Resolution can be reduced from 12 bits to 10, 8 or 6 bits for a corresponding +reduction in conversion time (resolution + 3 ADC clock cycles). + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] resolution Unsigned int8. Resolution value @ref adc_cr1_res +*/ + +void adc_set_resolution(u32 adc, u16 resolution) +{ + u32 reg32 = ADC_CR1(adc); + + reg32 &= ~ADC_CR1_RES_MASK; + reg32 |= resolution; + ADC_CR1(adc) = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable the Overrun Interrupt + +The overrun interrupt is generated when data is not read from a result register +before the next conversion is written. If DMA is enabled, all transfers are +terminated and any conversion sequence is aborted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_overrun_interrupt(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_OVRIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable the Overrun Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_overrun_interrupt(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_OVRIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read the Overrun Flag + +The overrun flag is set when data is not read from a result register before the next +conversion is written. If DMA is enabled, all transfers are terminated and any +conversion sequence is aborted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +bool adc_get_overrun_flag(u32 adc) +{ + return (ADC_SR(adc) & ADC_SR_OVR); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Clear Overrun Flags + +The overrun flag is cleared. Note that if an overrun occurs, DMA is terminated. +The flag must be cleared and the DMA stream and ADC reinitialised to resume +conversions (see the reference manual). + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +void adc_clear_overrun_flag(u32 adc) +{ +/* need to write zero to clear this */ + ADC_SR(adc) &= ~ADC_SR_OVR; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable an EOC for Each Conversion + +The EOC is set after each conversion in a sequence rather than at the end of the +sequence. Overrun detection is enabled only if DMA is enabled. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_eoc_after_each(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_EOCS; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable the EOC for Each Conversion + +The EOC is set at the end of each sequence rather than after each conversion in the +sequence. Overrun detection is enabled always. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_eoc_after_group(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EOCS; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set DMA to Continue + +This must be set to allow DMA to continue to operate after the last conversion in +the DMA sequence. This allows DMA to be used in continuous circular mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_dma_continue(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_DDS; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set DMA to Terminate + +This must be set to allow DMA to terminate after the last conversion in the DMA +sequence. This can avoid overrun errors. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_dma_terminate(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_DDS; +} +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read the Analog Watchdog Flag + +This flag is set when the converted voltage crosses the high or low thresholds. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. AWD flag. +*/ + +bool adc_awd(u32 adc) +{ + return (ADC_SR(adc) & ADC_SR_AWD); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable The Temperature Sensor + +This enables both the sensor and the reference voltage measurements on channels +16 and 17. These are only available on ADC1 channel 16 and 17 respectively. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_temperature_sensor() +{ + ADC_CCR |= ADC_CCR_TSVREFE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable The Temperature Sensor + +Disabling this will reduce power consumption from the sensor and the reference +voltage measurements. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_temperature_sensor() +{ + ADC_CCR &= ~ADC_CCR_TSVREFE; +} + +/*-----------------------------------------------------------------------------*/ + +/**@}*/ + diff --git a/lib/stm32/f4/dma.c b/lib/stm32/f4/dma.c new file mode 100644 index 00000000..7c80dcf6 --- /dev/null +++ b/lib/stm32/f4/dma.c @@ -0,0 +1,772 @@ +/** @defgroup STM32F4xx-dma-file DMA + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx DMA Controller</b> + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net> + +@date 18 October 2012 + +This library supports the DMA Control System in the STM32F2 and STM32F4 +series of ARM Cortex Microcontrollers by ST Microelectronics. + +Up to two DMA controllers are supported each with 8 streams, and each stream +having up to 8 channels hardware dedicated to various peripheral DMA signals. + +DMA transfers can be configured to occur between peripheral and memory in +either direction, and memory to memory. Peripheral to peripheral transfer +is not supported. Circular mode transfers are also supported in transfers +involving a peripheral. An arbiter is provided to resolve priority DMA +requests. Transfers can be made with 8, 16 or 32 bit words. + +Each stream has access to a 4 word deep FIFO and can use double buffering +by means of two memory pointers. When using the FIFO it is possible to +configure transfers to occur in indivisible bursts. + +It is also possible to select a peripheral to control the flow of data rather +than the DMA controller. This limits the functionality but is udeful when the +number of transfers is unknown. + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies <ksarkies@internode.on.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/**@{*/ + +#include <libopencm3/stm32/f4/dma.h> + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Reset + +The specified stream is disabled and configuration registers are cleared. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_stream_reset(u32 dma, u8 stream) +{ +/* Disable stream (must be done before register is otherwise changed). */ + DMA_SCR(dma, stream) &= ~DMA_SCR_EN; +/* Reset all config bits. */ + DMA_SCR(dma, stream) = 0; +/* Reset data transfer number. */ + DMA_SNDTR(dma, stream) = 0; +/* Reset peripheral and memory addresses. */ + DMA_SPAR(dma, stream) = 0; + DMA_SM0AR(dma, stream) = 0; + DMA_SM1AR(dma, stream) = 0; +/* This is the default setting */ + DMA_SFCR(dma, stream) = 0x21; +/* Reset all stream interrupt flags using the interrupt flag clear register. */ + u32 mask = DMA_ISR_MASK(stream); + if (stream < 4) + { + DMA_LIFCR(dma) |= mask; + } + else + { + DMA_HIFCR(dma) |= mask; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Clear Interrupt Flag + +The interrupt flag for the stream is cleared. More than one interrupt for the +same stream may be cleared by using the logical OR of the interrupt flags. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] interrupts unsigned int32. Logical OR of interrupt numbers: @ref dma_if_offset +*/ + +void dma_clear_interrupt_flags(u32 dma, u8 stream, u32 interrupts) +{ +/* Get offset to interrupt flag location in stream field */ + u32 flags = (interrupts << DMA_ISR_OFFSET(stream)); +/* First four streams are in low register. Flag clear must be set then reset. */ + if (stream < 4) + { + DMA_LIFCR(dma) = flags; + } + else + { + DMA_HIFCR(dma) = flags; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Read Interrupt Flag + +The interrupt flag for the stream is returned. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] interrupt unsigned int32. Interrupt number: @ref dma_if_offset +@returns bool interrupt flag is set. +*/ + +bool dma_get_interrupt_flag(u32 dma, u8 stream, u32 interrupt) +{ +/* get offset to interrupt flag location in stream field. +Assumes stream and interrupt parameters are integers */ + u32 flag = (interrupt << DMA_ISR_OFFSET(stream)); +/* First four streams are in low register */ + if (stream < 4) return ((DMA_LISR(dma) & flag) > 0); + else return ((DMA_HISR(dma) & flag) > 0); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Transfer Direction + +Set peripheral to memory, memory to peripheral or memory to memory. If memory +to memory mode is selected, circular mode and double buffer modes are disabled. +Ensure that these modes are not enabled at a later time. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] direction unsigned int32. Data transfer direction @ref dma_st_dir +*/ + +void dma_set_transfer_mode(u32 dma, u8 stream, u32 direction) +{ + u32 reg32 = (DMA_SCR(dma, stream) & ~DMA_SCR_DIR_MASK); +/* Disable circular and double buffer modes if memory to memory transfers +are in effect (Direct Mode is automatically disabled by hardware) */ + if (direction == DMA_SCR_DIR_MEM2MEM) + { + reg32 &= ~(DMA_SCR_CIRC | DMA_SCR_DBM); + } + DMA_SCR(dma, stream) = (reg32 | direction); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Priority + +Stream Priority has four levels: low to very high. This has precedence over the +hardware priority. In the event of equal software priority the lower numbered +stream has priority. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] prio unsigned int32. Priority level @ref dma_st_pri. +*/ + +void dma_set_priority(u32 dma, u8 stream, u32 prio) +{ + DMA_SCR(dma, stream) &= ~(DMA_SCR_PL_MASK); + DMA_SCR(dma, stream) |= prio; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Memory Word Width + +Set the memory word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for +alignment information if the source and destination widths do not match. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] mem_size unsigned int32. Memory word width @ref dma_st_memwidth. +*/ + +void dma_set_memory_size(u32 dma, u8 stream, u32 mem_size) +{ + + DMA_SCR(dma, stream) &= ~(DMA_SCR_MSIZE_MASK); + DMA_SCR(dma, stream) |= mem_size; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Peripheral Word Width + +Set the peripheral word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for +alignment information if the source and destination widths do not match, or +if the peripheral does not support byte or half-word writes. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] peripheral_size unsigned int32. Peripheral word width @ref dma_st_perwidth. +*/ + +void dma_set_peripheral_size(u32 dma, u8 stream, u32 peripheral_size) +{ + DMA_SCR(dma, stream) &= ~(DMA_SCR_PSIZE_MASK); + DMA_SCR(dma, stream) |= peripheral_size; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Memory Increment after Transfer + +Following each transfer the current memory address is incremented by +1, 2 or 4 depending on the data size set in @ref dma_set_memory_size. The +value held by the base memory address register is unchanged. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_memory_increment_mode(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) |= DMA_SCR_MINC; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Memory Increment after Transfer + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_memory_increment_mode(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SCR_MINC; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Variable Sized Peripheral Increment after Transfer + +Following each transfer the current peripheral address is incremented by +1, 2 or 4 depending on the data size set in @ref dma_set_peripheral_size. The +value held by the base peripheral address register is unchanged. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_peripheral_increment_mode(u32 dma, u8 stream) +{ + u32 reg32 = (DMA_SCR(dma, stream) | DMA_SCR_PINC); + DMA_SCR(dma, stream) = (reg32 & ~DMA_SCR_PINCOS); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Peripheral Increment after Transfer + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_peripheral_increment_mode(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SCR_PINC; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Fixed Sized Peripheral Increment after Transfer + +Following each transfer the current peripheral address is incremented by +4 regardless of the data size. The value held by the base peripheral address +register is unchanged. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_fixed_peripheral_increment_mode(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) |= (DMA_SCR_PINC | DMA_SCR_PINCOS); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Memory Circular Mode + +After the number of bytes/words to be transferred has been completed, the +original transfer block size, memory and peripheral base addresses are +reloaded and the process repeats. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@note This cannot be used with memory to memory mode. It is disabled +automatically if the peripheral is selected as the flow controller. +It is enabled automatically if double buffered mode is selected. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_circular_mode(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) |= DMA_SCR_CIRC; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Channel Select + +Associate an input channel to the stream. Not every channel is allocated to a +hardware DMA request signal. The allocations for each stream are given in the +STM32F4 Reference Manual. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] channel unsigned int8. Channel selection @ref dma_ch_sel +*/ + +void dma_channel_select(u32 dma, u8 stream, u32 channel) +{ + DMA_SCR(dma, stream) |= channel; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Memory Burst Configuration + +Set the memory burst type to none, 4 8 or 16 word length. This is forced to none +if direct mode is used. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] burst unsigned int8. Memory Burst selection @ref dma_mburst +*/ + +void dma_set_memory_burst(u32 dma, u8 stream, u32 burst) +{ + u32 reg32 = (DMA_SCR(dma, stream) & ~DMA_SCR_MBURST_MASK); + DMA_SCR(dma, stream) = (reg32 | burst); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Peripheral Burst Configuration + +Set the memory burst type to none, 4 8 or 16 word length. This is forced to none +if direct mode is used. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] burst unsigned int8. Peripheral Burst selection @ref dma_pburst +*/ + +void dma_set_peripheral_burst(u32 dma, u8 stream, u32 burst) +{ + u32 reg32 = (DMA_SCR(dma, stream) & ~DMA_SCR_PBURST_MASK); + DMA_SCR(dma, stream) = (reg32 | burst); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Initial Target Memory + +In double buffered mode, set the target memory (M0 or M1) to be used for the first +transfer. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] memory unsigned int8. Initial memory pointer to use: 0 or 1 +*/ + +void dma_set_initial_target(u32 dma, u8 stream, u8 memory) +{ + u32 reg32 = (DMA_SCR(dma, stream) & ~DMA_SCR_CT); + if (memory == 1) reg32 |= DMA_SCR_CT; + DMA_SCR(dma, stream) = reg32; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Read Current Memory Target + +In double buffer mode, return the current memory target (M0 or M1). It is possible +to update the memory pointer in the register that is <b> not </b> currently in +use. An attempt to change the register currently in use will cause the stream +to be disabled and the transfer error flag to be set. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@returns unsigned int8. Memory buffer in use: 0 or 1 +*/ + +u8 dma_get_target(u32 dma, u8 stream) +{ + if (DMA_SCR(dma, stream) & DMA_SCR_CT) return 1; + return 0; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Double Buffer Mode + +Double buffer mode is used for memory to/from peripheral transfers only, and in +circular mode which is automatically enabled. Two memory buffers must be +established with pointers stored in the memory pointer registers. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@note This cannot be used with memory to memory mode. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_double_buffer_mode(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) |= DMA_SCR_DBM; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set Peripheral Flow Control + +Set the peripheral to control DMA flow. Useful when the number of transfers is +unknown. This is forced off when memory to memory mode is selected. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_set_peripheral_flow_control(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) |= DMA_SCR_PFCTRL; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set DMA Flow Control + +Set the DMA controller to control DMA flow. This is the default. + +Ensure that the stream is disabled otherwise the setting will not be changed. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_set_dma_flow_control(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SCR_PFCTRL; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Interrupt on Transfer Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_transfer_error_interrupt(u32 dma, u8 stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_ISR_TEIF); + DMA_SCR(dma, stream) |= DMA_SCR_TEIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Interrupt on Transfer Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_transfer_error_interrupt(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SCR_TEIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Interrupt on Transfer Half Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_half_transfer_interrupt(u32 dma, u8 stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_ISR_HTIF); + DMA_SCR(dma, stream) |= DMA_SCR_HTIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Interrupt on Transfer Half Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_half_transfer_interrupt(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SCR_HTIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Interrupt on Transfer Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_transfer_complete_interrupt(u32 dma, u8 stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_ISR_TCIF); + DMA_SCR(dma, stream) |= DMA_SCR_TCIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Interrupt on Transfer Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_transfer_complete_interrupt(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SCR_TCIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable Interrupt on Direct Mode Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_direct_mode_error_interrupt(u32 dma, u8 stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_ISR_DMEIF); + DMA_SCR(dma, stream) |= DMA_SCR_DMEIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable Interrupt on Direct Mode Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_direct_mode_error_interrupt(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SCR_DMEIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Enable Interrupt on FIFO Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_fifo_error_interrupt(u32 dma, u8 stream) +{ + dma_clear_interrupt_flags(dma, stream, DMA_ISR_FEIF); + DMA_SFCR(dma, stream) |= DMA_FCR_FEIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Disable Interrupt on FIFO Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_fifo_error_interrupt(u32 dma, u8 stream) +{ + DMA_SFCR(dma, stream) &= ~DMA_FCR_FEIE; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Get FIFO Status + +Status of FIFO (empty. full or partial filled states) is returned. This has no +meaning if direct mode is enabled (as the FIFO is not used). + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@returns u32 FIFO Status @ref dma_fifo_status +*/ + +u32 dma_fifo_status(u32 dma, u8 stream) +{ + return (DMA_SFCR(dma, stream) & DMA_FCR_FS_MASK); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Enable Direct Mode + +Direct mode is the default. Data is transferred as soon as a DMA request is +received. The FIFO is not used. This must not be set when memory to memory +mode is selected. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_direct_mode(u32 dma, u8 stream) +{ + DMA_SFCR(dma, stream) &= ~DMA_FCR_DMDIS; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Enable FIFO Mode + +Data is transferred via a FIFO. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_fifo_mode(u32 dma, u8 stream) +{ + DMA_SFCR(dma, stream) |= DMA_FCR_DMDIS; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Set FIFO Threshold + +This is the filled level at which data is transferred out of the FIFO to the +destination. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] threshold unsigned int8. Threshold setting @ref dma_fifo_thresh +*/ + +void dma_set_fifo_threshold(u32 dma, u8 stream, u32 threshold) +{ + u32 reg32 = (DMA_SFCR(dma, stream) & ~DMA_FCR_FTH_MASK); + DMA_SFCR(dma, stream) = (reg32 | threshold); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Enable + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_enable_stream(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) |= DMA_SCR_EN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Disable + +@note The DMA stream registers retain their values when the stream is disabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +*/ + +void dma_disable_stream(u32 dma, u8 stream) +{ + DMA_SCR(dma, stream) &= ~DMA_SCR_EN; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set the Peripheral Address + +Set the address of the peripheral register to or from which data is to be transferred. +Refer to the documentation for the specific peripheral. + +@note The DMA stream must be disabled before setting this address. This function +has no effect if the stream is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] address unsigned int32. Peripheral Address. +*/ + +void dma_set_peripheral_address(u32 dma, u8 stream, u32 address) +{ + if (!(DMA_SCR(dma, stream) & DMA_SCR_EN)) + DMA_SPAR(dma, stream) = (u32) address; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set the Base Memory Address 0 + +Set the address pointer to the memory location for DMA transfers. The DMA stream +must normally be disabled before setting this address, however it is possible +to change this in double buffer mode when the current target is memory area 1 +(see @ref dma_get_target). + +This is the default base memory address used in direct mode. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] address unsigned int32. Memory Initial Address. +*/ + +void dma_set_memory_address(u32 dma, u8 stream, u32 address) +{ + u32 reg32 = DMA_SCR(dma, stream); + if ( !(reg32 & DMA_SCR_EN) || ((reg32 & DMA_SCR_CT) && (reg32 & DMA_SCR_DBM)) ) + DMA_SM0AR(dma, stream) = (u32) address; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set the Base Memory Address 1 + +Set the address pointer to the memory location for DMA transfers. The DMA stream +must normally be disabled before setting this address, however it is possible +to change this in double buffer mode when the current target is memory area 0 +(see @ref dma_get_target). + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] address unsigned int32. Memory Initial Address. +*/ + +void dma_set_memory_address_1(u32 dma, u8 stream, u32 address) +{ + u32 reg32 = DMA_SCR(dma, stream); + if ( !(reg32 & DMA_SCR_EN) || (!(reg32 & DMA_SCR_CT) && (reg32 & DMA_SCR_DBM)) ) + DMA_SM1AR(dma, stream) = (u32) address; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Stream Set the Transfer Block Size + +@note The DMA stream must be disabled before setting this count value. The count +is not changed if the stream is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] stream unsigned int8. Stream number: @ref dma_st_number +@param[in] number unsigned int16. Number of data words to transfer (65535 maximum). +*/ + +void dma_set_number_of_data(u32 dma, u8 stream, u16 number) +{ + DMA_SNDTR(dma, stream) = number; +} +/**@}*/ + diff --git a/lib/stm32/f4/exti.c b/lib/stm32/f4/exti.c deleted file mode 100644 index 155c21f2..00000000 --- a/lib/stm32/f4/exti.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <libopencm3/stm32/exti.h> -#include <libopencm3/stm32/f4/syscfg.h> -#include <libopencm3/stm32/f4/gpio.h> - -void exti_set_trigger(u32 extis, exti_trigger_type trig) -{ - switch (trig) { - case EXTI_TRIGGER_RISING: - EXTI_RTSR |= extis; - EXTI_FTSR &= ~extis; - break; - case EXTI_TRIGGER_FALLING: - EXTI_RTSR &= ~extis; - EXTI_FTSR |= extis; - break; - case EXTI_TRIGGER_BOTH: - EXTI_RTSR |= extis; - EXTI_FTSR |= extis; - break; - } -} - -void exti_enable_request(u32 extis) -{ - /* Enable interrupts. */ - EXTI_IMR |= extis; - - /* Enable events. */ - EXTI_EMR |= extis; -} - -void exti_disable_request(u32 extis) -{ - /* Disable interrupts. */ - EXTI_IMR &= ~extis; - - /* Disable events. */ - EXTI_EMR &= ~extis; -} - -/* - * Reset the interrupt request by writing a 1 to the corresponding - * pending bit register. - */ -void exti_reset_request(u32 extis) -{ - EXTI_PR = extis; -} - -/* - * Remap an external interrupt line to the corresponding pin on the - * specified GPIO port. - * - * TODO: This could be rewritten in fewer lines of code. - */ -void exti_select_source(u32 exti, u32 gpioport) -{ - u8 shift, bits; - - shift = bits = 0; - - switch (exti) { - case EXTI0: - case EXTI4: - case EXTI8: - case EXTI12: - shift = 0; - break; - case EXTI1: - case EXTI5: - case EXTI9: - case EXTI13: - shift = 4; - break; - case EXTI2: - case EXTI6: - case EXTI10: - case EXTI14: - shift = 8; - break; - case EXTI3: - case EXTI7: - case EXTI11: - case EXTI15: - shift = 12; - break; - } - - switch (gpioport) { - case GPIOA: - bits = 0xf; - break; - case GPIOB: - bits = 0xe; - break; - case GPIOC: - bits = 0xd; - break; - case GPIOD: - bits = 0xc; - break; - case GPIOE: - bits = 0xb; - break; - case GPIOF: - bits = 0xa; - break; - case GPIOG: - bits = 0x9; - break; - } - - /* Ensure that only valid EXTI lines are used. */ - if (exti < EXTI4) { - SYSCFG_EXTICR1 &= ~(0x000F << shift); - SYSCFG_EXTICR1 |= (~bits << shift); - } else if (exti < EXTI8) { - SYSCFG_EXTICR2 &= ~(0x000F << shift); - SYSCFG_EXTICR2 |= (~bits << shift); - } else if (exti < EXTI12) { - SYSCFG_EXTICR3 &= ~(0x000F << shift); - SYSCFG_EXTICR3 |= (~bits << shift); - } else if (exti < EXTI16) { - SYSCFG_EXTICR4 &= ~(0x000F << shift); - SYSCFG_EXTICR4 |= (~bits << shift); - } -} diff --git a/lib/stm32/f4/gpio.c b/lib/stm32/f4/gpio.c deleted file mode 100644 index 1d7739dd..00000000 --- a/lib/stm32/f4/gpio.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <libopencm3/stm32/f4/gpio.h> - -void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios) -{ - u16 i; - u32 moder, pupd; - - /* - * We want to set the config only for the pins mentioned in gpios, - * but keeping the others, so read out the actual config first. - */ - moder = GPIO_MODER(gpioport); - pupd = GPIO_PUPDR(gpioport); - - for (i = 0; i < 16; i++) { - if (!((1 << i) & gpios)) - continue; - - moder &= ~GPIO_MODE_MASK(i); - moder |= GPIO_MODE(i, mode); - pupd &= ~GPIO_PUPD_MASK(i); - pupd |= GPIO_PUPD(i, pull_up_down); - } - - /* Set mode and pull up/down control registers. */ - GPIO_MODER(gpioport) = moder; - GPIO_PUPDR(gpioport) = pupd; -} - -void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios) -{ - u16 i; - u32 ospeedr; - - if (otype == 0x1) - GPIO_OTYPER(gpioport) |= gpios; - else - GPIO_OTYPER(gpioport) &= ~gpios; - - ospeedr = GPIO_OSPEEDR(gpioport); - - for (i = 0; i < 16; i++) { - if (!((1 << i) & gpios)) - continue; - ospeedr &= ~GPIO_OSPEED_MASK(i); - ospeedr |= GPIO_OSPEED(i, speed); - } - - GPIO_OSPEEDR(gpioport) = ospeedr; -} - -void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios) -{ - u16 i; - u32 afrl, afrh; - - afrl = GPIO_AFRL(gpioport); - afrh = GPIO_AFRH(gpioport); - - for (i = 0; i < 8; i++) { - if (!((1 << i) & gpios)) - continue; - afrl &= ~GPIO_AFR_MASK(i); - afrl |= GPIO_AFR(i, alt_func_num); - } - - for (i = 8; i < 16; i++) { - if (!((1 << i) & gpios)) - continue; - afrl &= ~GPIO_AFR_MASK(i - 8); - afrh |= GPIO_AFR(i - 8, alt_func_num); - } - - GPIO_AFRL(gpioport) = afrl; - GPIO_AFRH(gpioport) = afrh; -} - -void gpio_set(u32 gpioport, u16 gpios) -{ - GPIO_BSRR(gpioport) = gpios; -} - -void gpio_clear(u32 gpioport, u16 gpios) -{ - GPIO_BSRR(gpioport) = gpios << 16; -} - -u16 gpio_get(u32 gpioport, u16 gpios) -{ - return gpio_port_read(gpioport) & gpios; -} - -void gpio_toggle(u32 gpioport, u16 gpios) -{ - GPIO_ODR(gpioport) ^= gpios; -} - -u16 gpio_port_read(u32 gpioport) -{ - return (u16)GPIO_IDR(gpioport); -} - -void gpio_port_write(u32 gpioport, u16 data) -{ - GPIO_ODR(gpioport) = data; -} - -void gpio_port_config_lock(u32 gpioport, u16 gpios) -{ - u32 reg32; - - /* Special "Lock Key Writing Sequence", see datasheet. */ - GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ - GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */ - GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ - reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */ - reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */ - - /* Tell the compiler the variable is actually used. It will get optimized out anyways. */ - reg32 = reg32; - - /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */ -} diff --git a/lib/stm32/f4/timer.c b/lib/stm32/f4/timer.c deleted file mode 100644 index 6d5ab9df..00000000 --- a/lib/stm32/f4/timer.c +++ /dev/null @@ -1,928 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org> - * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Basic TIMER handling API. - * - * Examples: - * timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT_MUL_2, - * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP); - */ - -#include <libopencm3/stm32/f4/timer.h> -#include <libopencm3/stm32/f4/rcc.h> - -void timer_reset(u32 timer_peripheral) -{ - switch (timer_peripheral) { - case TIM1: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST); - break; - case TIM2: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST); - break; - case TIM3: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST); - break; - case TIM4: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST); - break; - case TIM5: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST); - break; - case TIM6: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST); - break; - case TIM7: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST); - break; - case TIM8: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST); - break; -/* These timers are not supported in libopencm3 yet */ -/* - case TIM9: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST); - break; - case TIM10: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST); - break; - case TIM11: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST); - break; - case TIM12: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST); - break; - case TIM13: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST); - break; - case TIM14: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST); - break; -*/ - } -} - -void timer_enable_irq(u32 timer_peripheral, u32 irq) -{ - TIM_DIER(timer_peripheral) |= irq; -} - -void timer_disable_irq(u32 timer_peripheral, u32 irq) -{ - TIM_DIER(timer_peripheral) &= ~irq; -} - -bool timer_get_flag(u32 timer_peripheral, u32 flag) -{ - if (((TIM_SR(timer_peripheral) & flag) != 0) && - ((TIM_DIER(timer_peripheral) & flag) != 0)) { - return true; - } - - return false; -} - -void timer_clear_flag(u32 timer_peripheral, u32 flag) -{ - TIM_SR(timer_peripheral) &= ~flag; -} - -void timer_set_mode(u32 timer_peripheral, u32 clock_div, - u32 alignment, u32 direction) -{ - u32 cr1; - - cr1 = TIM_CR1(timer_peripheral); - - cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | TIM_CR1_CMS_MASK | TIM_CR1_DIR_DOWN); - - cr1 |= clock_div | alignment | direction; - - TIM_CR1(timer_peripheral) = cr1; -} - -void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) -{ - clock_div &= TIM_CR1_CKD_CK_INT_MASK; - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK; - TIM_CR1(timer_peripheral) |= clock_div; -} - -void timer_enable_preload(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE; -} - -void timer_disable_preload(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE; -} - -void timer_set_alignment(u32 timer_peripheral, u32 alignment) -{ - alignment &= TIM_CR1_CMS_MASK; - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK; - TIM_CR1(timer_peripheral) |= alignment; -} - -void timer_direction_up(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN; -} - -void timer_direction_down(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN; -} - -void timer_one_shot_mode(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_OPM; -} - -void timer_continuous_mode(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM; -} - -void timer_update_on_any(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS; -} - -void timer_update_on_overflow(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_URS; -} - -void timer_enable_update_event(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS; -} - -void timer_disable_update_event(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS; -} - -void timer_enable_counter(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_CEN; -} - -void timer_disable_counter(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN; -} - -void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs) -{ - TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; -} - -void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs) -{ - TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); -} - -void timer_set_ti1_ch123_xor(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S; -} - -void timer_set_ti1_ch1(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S; -} - -void timer_set_master_mode(u32 timer_peripheral, u32 mode) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK; - TIM_CR2(timer_peripheral) |= mode; -} - -void timer_set_dma_on_compare_event(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS; -} - -void timer_set_dma_on_update_event(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS; -} - -void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; -} - -void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; -} - -void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; -} - -void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; -} - -void timer_set_prescaler(u32 timer_peripheral, u32 value) -{ - TIM_PSC(timer_peripheral) = value; -} - -void timer_set_repetition_counter(u32 timer_peripheral, u32 value) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_RCR(timer_peripheral) = value; -} - -void timer_set_period(u32 timer_peripheral, u32 period) -{ - TIM_ARR(timer_peripheral) = period; -} - -void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, - enum tim_oc_mode oc_mode) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT; - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR1(timer_peripheral) |= - TIM_CCMR1_OC1M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM2; - break; - } - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT; - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR1(timer_peripheral) |= - TIM_CCMR1_OC2M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM2; - break; - } - break; - case TIM_OC3: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC3S_OUT; - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC3M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR2(timer_peripheral) |= - TIM_CCMR2_OC3M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM2; - break; - } - break; - case TIM_OC4: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC4S_OUT; - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC4M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR2(timer_peripheral) |= - TIM_CCMR2_OC4M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM2; - break; - } - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - /* Acting for TIM1 and TIM8 only. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1; - break; - case TIM_OC1N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N; - break; - case TIM_OC2: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2; - break; - case TIM_OC2N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N; - break; - case TIM_OC3: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3; - break; - case TIM_OC3N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N; - break; - case TIM_OC4: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4; - break; - } -} - -void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - /* Acting for TIM1 and TIM8 only. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1; - break; - case TIM_OC1N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N; - break; - case TIM_OC2: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2; - break; - case TIM_OC2N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N; - break; - case TIM_OC3: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3; - break; - case TIM_OC3N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N; - break; - case TIM_OC4: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4; - break; - } -} - -void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCR1(timer_peripheral) = value; - break; - case TIM_OC2: - TIM_CCR2(timer_peripheral) = value; - break; - case TIM_OC3: - TIM_CCR3(timer_peripheral) = value; - break; - case TIM_OC4: - TIM_CCR4(timer_peripheral) = value; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_enable_break_main_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE; -} - -void timer_disable_break_main_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE; -} - -void timer_enable_break_automatic_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE; -} - -void timer_disable_break_automatic_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE; -} - -void timer_set_break_polarity_high(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP; -} - -void timer_set_break_polarity_low(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP; -} - -void timer_enable_break(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE; -} - -void timer_disable_break(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE; -} - -void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR; -} - -void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR; -} - -void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI; -} - -void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI; -} - -void timer_set_break_lock(u32 timer_peripheral, u32 lock) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= lock; -} - -void timer_set_deadtime(u32 timer_peripheral, u32 deadtime) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= deadtime; -} - -void timer_generate_event(u32 timer_peripheral, u32 event) -{ - TIM_EGR(timer_peripheral) |= event; -} - -u32 timer_get_counter(u32 timer_peripheral) -{ - return TIM_CNT(timer_peripheral); -} - -void timer_set_option(u32 timer_peripheral, u32 option) -{ - if (timer_peripheral == TIM2) { - TIM_OR(timer_peripheral) &= ~TIM2_OR_ITR1_RMP_MASK; - TIM_OR(timer_peripheral) |= option; - } else if (timer_peripheral == TIM5) { - TIM_OR(timer_peripheral) &= ~TIM5_OR_TI4_RMP_MASK; - TIM_OR(timer_peripheral) |= option; - } -} diff --git a/lib/stm32/f4/vector.c b/lib/stm32/f4/vector.c deleted file mode 100644 index 01b5e646..00000000 --- a/lib/stm32/f4/vector.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> - * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com> - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <libopencm3/stm32/f4/scb.h> - -#define WEAK __attribute__ ((weak)) - -/* Symbols exported by the linker script(s): */ -extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack; - -void main(void); -void reset_handler(void); -void blocking_handler(void); -void null_handler(void); - -void WEAK reset_handler(void); -void WEAK nmi_handler(void); -void WEAK hard_fault_handler(void); -void WEAK mem_manage_handler(void); -void WEAK bus_fault_handler(void); -void WEAK usage_fault_handler(void); -void WEAK sv_call_handler(void); -void WEAK debug_monitor_handler(void); -void WEAK pend_sv_handler(void); -void WEAK sys_tick_handler(void); -void WEAK wwdg_isr(void); -void WEAK pvd_isr(void); -void WEAK tamp_stamp_isr(void); -void WEAK rtc_wkup_isr(void); -void WEAK flash_isr(void); -void WEAK rcc_isr(void); -void WEAK exti0_isr(void); -void WEAK exti1_isr(void); -void WEAK exti2_isr(void); -void WEAK exti3_isr(void); -void WEAK exti4_isr(void); -void WEAK dma1_stream0_isr(void); -void WEAK dma1_stream1_isr(void); -void WEAK dma1_stream2_isr(void); -void WEAK dma1_stream3_isr(void); -void WEAK dma1_stream4_isr(void); -void WEAK dma1_stream5_isr(void); -void WEAK dma1_stream6_isr(void); -void WEAK adc_isr(void); -void WEAK can1_tx_isr(void); -void WEAK can1_rx0_isr(void); -void WEAK can1_rx1_isr(void); -void WEAK can1_sce_isr(void); -void WEAK exti9_5_isr(void); -void WEAK tim1_brk_tim9_isr(void); -void WEAK tim1_up_tim10_isr(void); -void WEAK tim1_trg_com_tim11_isr(void); -void WEAK tim1_cc_isr(void); -void WEAK tim2_isr(void); -void WEAK tim3_isr(void); -void WEAK tim4_isr(void); -void WEAK i2c1_ev_isr(void); -void WEAK i2c1_er_isr(void); -void WEAK i2c2_ev_isr(void); -void WEAK i2c2_er_isr(void); -void WEAK spi1_isr(void); -void WEAK spi2_isr(void); -void WEAK usart1_isr(void); -void WEAK usart2_isr(void); -void WEAK usart3_isr(void); -void WEAK exti15_10_isr(void); -void WEAK rtc_alarm_isr(void); -void WEAK usb_fs_wkup_isr(void); -void WEAK tim8_brk_tim12_isr(void); -void WEAK tim8_up_tim13_isr(void); -void WEAK tim8_trg_com_tim14_isr(void); -void WEAK tim8_cc_isr(void); -void WEAK dma1_stream7_isr(void); -void WEAK fsmc_isr(void); -void WEAK sdio_isr(void); -void WEAK tim5_isr(void); -void WEAK spi3_isr(void); -void WEAK uart4_isr(void); -void WEAK uart5_isr(void); -void WEAK tim6_dac_isr(void); -void WEAK tim7_isr(void); -void WEAK dma2_stream0_isr(void); -void WEAK dma2_stream1_isr(void); -void WEAK dma2_stream2_isr(void); -void WEAK dma2_stream3_isr(void); -void WEAK dma2_stream4_isr(void); -void WEAK eth_isr(void); -void WEAK eth_wkup_isr(void); -void WEAK can2_tx_isr(void); -void WEAK can2_rx0_isr(void); -void WEAK can2_rx1_isr(void); -void WEAK can2_sce_isr(void); -void WEAK otg_fs_isr(void); -void WEAK dma2_stream5_isr(void); -void WEAK dma2_stream6_isr(void); -void WEAK dma2_stream7_isr(void); -void WEAK usart6_isr(void); -void WEAK i2c3_ev_isr(void); -void WEAK i2c3_er_isr(void); -void WEAK otg_hs_ep1_out_isr(void); -void WEAK otg_hs_ep1_in_isr(void); -void WEAK otg_hs_wkup_isr(void); -void WEAK otg_hs_isr(void); -void WEAK dcmi_isr(void); -void WEAK cryp_isr(void); -void WEAK hash_rng_isr(void); - -__attribute__ ((section(".vectors"))) -void (*const vector_table[]) (void) = { - (void *)&_stack, - reset_handler, - nmi_handler, - hard_fault_handler, - mem_manage_handler, - bus_fault_handler, - usage_fault_handler, - 0, 0, 0, 0, /* Reserved */ - sv_call_handler, - debug_monitor_handler, - 0, /* Reserved */ - pend_sv_handler, - sys_tick_handler, - wwdg_isr, - pvd_isr, - tamp_stamp_isr, - rtc_wkup_isr, - flash_isr, - rcc_isr, - exti0_isr, - exti1_isr, - exti2_isr, - exti3_isr, - exti4_isr, - dma1_stream0_isr, - dma1_stream1_isr, - dma1_stream2_isr, - dma1_stream3_isr, - dma1_stream4_isr, - dma1_stream5_isr, - dma1_stream6_isr, - adc_isr, - can1_tx_isr, - can1_rx0_isr, - can1_rx1_isr, - can1_sce_isr, - exti9_5_isr, - tim1_brk_tim9_isr, - tim1_up_tim10_isr, - tim1_trg_com_tim11_isr, - tim1_cc_isr, - tim2_isr, - tim3_isr, - tim4_isr, - i2c1_ev_isr, - i2c1_er_isr, - i2c2_ev_isr, - i2c2_er_isr, - spi1_isr, - spi2_isr, - usart1_isr, - usart2_isr, - usart3_isr, - exti15_10_isr, - rtc_alarm_isr, - usb_fs_wkup_isr, - tim8_brk_tim12_isr, - tim8_up_tim13_isr, - tim8_trg_com_tim14_isr, - tim8_cc_isr, - dma1_stream7_isr, - fsmc_isr, - sdio_isr, - tim5_isr, - spi3_isr, - uart4_isr, - uart5_isr, - tim6_dac_isr, - tim7_isr, - dma2_stream0_isr, - dma2_stream1_isr, - dma2_stream2_isr, - dma2_stream3_isr, - dma2_stream4_isr, - eth_isr, - eth_wkup_isr, - can2_tx_isr, - can2_rx0_isr, - can2_rx1_isr, - can2_sce_isr, - otg_fs_isr, - dma2_stream5_isr, - dma2_stream6_isr, - dma2_stream7_isr, - usart6_isr, - i2c3_ev_isr, - i2c3_er_isr, - otg_hs_ep1_out_isr, - otg_hs_ep1_in_isr, - otg_hs_wkup_isr, - otg_hs_isr, - dcmi_isr, - cryp_isr, - hash_rng_isr, -}; - -void reset_handler(void) -{ - volatile unsigned *src, *dest; - - __asm__("MSR msp, %0" : : "r"(&_stack)); - - /* Enable access to Floating-Point coprocessor. */ - SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); - - for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++) - *dest = *src; - - while (dest < &_ebss) - *dest++ = 0; - - /* Call the application's entry point. */ - main(); -} - -void blocking_handler(void) -{ - while (1) ; -} - -void null_handler(void) -{ - /* Do nothing. */ -} - -#pragma weak nmi_handler = null_handler -#pragma weak hard_fault_handler = blocking_handler -#pragma weak mem_manage_handler = blocking_handler -#pragma weak bus_fault_handler = blocking_handler -#pragma weak usage_fault_handler = blocking_handler -#pragma weak sv_call_handler = null_handler -#pragma weak debug_monitor_handler = null_handler -#pragma weak pend_sv_handler = null_handler -#pragma weak sys_tick_handler = null_handler -#pragma weak wwdg_isr = null_handler -#pragma weak pvd_isr = null_handler -#pragma weak tamp_stamp_isr = null_handler -#pragma weak rtc_wkup_isr = null_handler -#pragma weak flash_isr = null_handler -#pragma weak rcc_isr = null_handler -#pragma weak exti0_isr = null_handler -#pragma weak exti1_isr = null_handler -#pragma weak exti2_isr = null_handler -#pragma weak exti3_isr = null_handler -#pragma weak exti4_isr = null_handler -#pragma weak dma1_stream0_isr = null_handler -#pragma weak dma1_stream1_isr = null_handler -#pragma weak dma1_stream2_isr = null_handler -#pragma weak dma1_stream3_isr = null_handler -#pragma weak dma1_stream4_isr = null_handler -#pragma weak dma1_stream5_isr = null_handler -#pragma weak dma1_stream6_isr = null_handler -#pragma weak adc_isr = null_handler -#pragma weak can1_tx_isr = null_handler -#pragma weak can1_rx0_isr = null_handler -#pragma weak can1_rx1_isr = null_handler -#pragma weak can1_sce_isr = null_handler -#pragma weak exti9_5_isr = null_handler -#pragma weak tim1_brk_tim9_isr = null_handler -#pragma weak tim1_up_tim10_isr = null_handler -#pragma weak tim1_trg_com_tim11_isr = null_handler -#pragma weak tim1_cc_isr = null_handler -#pragma weak tim2_isr = null_handler -#pragma weak tim3_isr = null_handler -#pragma weak tim4_isr = null_handler -#pragma weak i2c1_ev_isr = null_handler -#pragma weak i2c1_er_isr = null_handler -#pragma weak i2c2_ev_isr = null_handler -#pragma weak i2c2_er_isr = null_handler -#pragma weak spi1_isr = null_handler -#pragma weak spi2_isr = null_handler -#pragma weak usart1_isr = null_handler -#pragma weak usart2_isr = null_handler -#pragma weak usart3_isr = null_handler -#pragma weak exti15_10_isr = null_handler -#pragma weak rtc_alarm_isr = null_handler -#pragma weak usb_fs_wkup_isr = null_handler -#pragma weak tim8_brk_tim12_isr = null_handler -#pragma weak tim8_up_tim13_isr = null_handler -#pragma weak tim8_trg_com_tim14_isr = null_handler -#pragma weak tim8_cc_isr = null_handler -#pragma weak dma1_stream7_isr = null_handler -#pragma weak fsmc_isr = null_handler -#pragma weak sdio_isr = null_handler -#pragma weak tim5_isr = null_handler -#pragma weak spi3_isr = null_handler -#pragma weak uart4_isr = null_handler -#pragma weak uart5_isr = null_handler -#pragma weak tim6_dac_isr = null_handler -#pragma weak tim7_isr = null_handler -#pragma weak dma2_stream0_isr = null_handler -#pragma weak dma2_stream1_isr = null_handler -#pragma weak dma2_stream2_isr = null_handler -#pragma weak dma2_stream3_isr = null_handler -#pragma weak dma2_stream4_isr = null_handler -#pragma weak eth_isr = null_handler -#pragma weak eth_wkup_isr = null_handler -#pragma weak can2_tx_isr = null_handler -#pragma weak can2_rx0_isr = null_handler -#pragma weak can2_rx1_isr = null_handler -#pragma weak can2_sce_isr = null_handler -#pragma weak otg_fs_isr = null_handler -#pragma weak dma2_stream5_isr = null_handler -#pragma weak dma2_stream6_isr = null_handler -#pragma weak dma2_stream7_isr = null_handler -#pragma weak usart6_isr = null_handler -#pragma weak i2c3_ev_isr = null_handler -#pragma weak i2c3_er_isr = null_handler -#pragma weak otg_hs_ep1_out_isr = null_handler -#pragma weak otg_hs_ep1_in_isr = null_handler -#pragma weak otg_hs_wkup_isr = null_handler -#pragma weak otg_hs_isr = null_handler -#pragma weak dcmi_isr = null_handler -#pragma weak cryp_isr = null_handler -#pragma weak hash_rng_isr = null_handler diff --git a/lib/stm32/f4/vector_chipset.c b/lib/stm32/f4/vector_chipset.c new file mode 100644 index 00000000..145be057 --- /dev/null +++ b/lib/stm32/f4/vector_chipset.c @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> + * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/cm3/scb.h> + +static void pre_main(void) +{ + /* Enable access to Floating-Point coprocessor. */ + SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); +} diff --git a/lib/stm32/f2/gpio.c b/lib/stm32/gpio2.c index 984cddb1..c185e986 100644 --- a/lib/stm32/f2/gpio.c +++ b/lib/stm32/gpio2.c @@ -17,7 +17,15 @@ * along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#if defined(STM32F2) #include <libopencm3/stm32/f2/gpio.h> +#elif defined(STM32F4) +#include <libopencm3/stm32/f4/gpio.h> +#elif defined(STM32L1) +#include <libopencm3/stm32/l1/gpio.h> +#else +#error "invalid/unknown stm32 family for this code" +#endif void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios) { @@ -86,7 +94,7 @@ void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios) for (i = 8; i < 16; i++) { if (!((1 << i) & gpios)) continue; - afrl &= ~GPIO_AFR_MASK(i - 8); + afrh &= ~GPIO_AFR_MASK(i - 8); afrh |= GPIO_AFR(i - 8, alt_func_num); } diff --git a/lib/stm32/i2c.c b/lib/stm32/i2c.c index e6869f6e..a67beced 100644 --- a/lib/stm32/i2c.c +++ b/lib/stm32/i2c.c @@ -313,26 +313,57 @@ void i2c_disable_interrupt(u32 i2c, u32 interrupt) I2C_CR2(i2c) &= ~interrupt; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C Enable ACK + +Enables acking of own 7/10 bit address +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ void i2c_enable_ack(u32 i2c) { I2C_CR1(i2c) |= I2C_CR1_ACK; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C Disable ACK + +Disables acking of own 7/10 bit address +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ void i2c_disable_ack(u32 i2c) { I2C_CR1(i2c) &= ~I2C_CR1_ACK; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C NACK Next Byte + +Causes the I2C controller to NACK the reception of the next byte +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ void i2c_nack_next(u32 i2c) { I2C_CR1(i2c) |= I2C_CR1_POS; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C NACK Next Byte + +Causes the I2C controller to NACK the reception of the current byte + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ void i2c_nack_current(u32 i2c) { I2C_CR1(i2c) &= ~I2C_CR1_POS; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C Set clock duty cycle + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +@param[in] dutycycle Unsigned int32. I2C duty cycle @ref i2c_duty_cycle. +*/ void i2c_set_dutycycle(u32 i2c, u32 dutycycle) { if (dutycycle == I2C_CCR_DUTY_DIV2) @@ -341,21 +372,41 @@ void i2c_set_dutycycle(u32 i2c, u32 dutycycle) I2C_CCR(i2c) |= I2C_CCR_DUTY; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C Enable DMA + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ void i2c_enable_dma(u32 i2c) { I2C_CR2(i2c) |= I2C_CR2_DMAEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C Disable DMA + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ void i2c_disable_dma(u32 i2c) { I2C_CR2(i2c) &= ~I2C_CR2_DMAEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C Set DMA last transfer + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ void i2c_set_dma_last_transfer(u32 i2c) { I2C_CR2(i2c) |= I2C_CR2_LAST; } +/*-----------------------------------------------------------------------------*/ +/** @brief I2C Clear DMA last transfer + +@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. +*/ void i2c_clear_dma_last_transfer(u32 i2c) { I2C_CR2(i2c) &= ~I2C_CR2_LAST; diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile new file mode 100644 index 00000000..9e07b2df --- /dev/null +++ b/lib/stm32/l1/Makefile @@ -0,0 +1,36 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +LIBNAME = libopencm3_stm32l1 + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32L1 +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = rcc.o gpio2.o desig.o crc.o usart.o exti2.o + +VPATH += ../../usb:../:../../cm3 + +include ../../Makefile.include + diff --git a/lib/stm32/l1/libopencm3_stm32l1.ld b/lib/stm32/l1/libopencm3_stm32l1.ld new file mode 100644 index 00000000..9d165f68 --- /dev/null +++ b/lib/stm32/l1/libopencm3_stm32l1.ld @@ -0,0 +1,83 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c new file mode 100644 index 00000000..a0236224 --- /dev/null +++ b/lib/stm32/l1/rcc.c @@ -0,0 +1,357 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde <memeruiz at gmail dot com> + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + * Based on the F4 code... + */ + +#include <libopencm3/stm32/l1/rcc.h> + +/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset. */ +u32 rcc_ppre1_frequency = 2097000; +u32 rcc_ppre2_frequency = 2097000; + +void rcc_osc_ready_int_clear(osc_t osc) +{ + switch (osc) { + case PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + case MSI: + RCC_CIR |= RCC_CIR_MSIRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(osc_t osc) +{ + switch (osc) { + case PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + case MSI: + RCC_CIR |= RCC_CIR_MSIRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(osc_t osc) +{ + switch (osc) { + case PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYIE; + break; + case HSE: + RCC_CIR &= ~RCC_CIR_HSERDYIE; + break; + case HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYIE; + break; + case LSE: + RCC_CIR &= ~RCC_CIR_LSERDYIE; + break; + case LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYIE; + break; + case MSI: + RCC_CIR &= ~RCC_CIR_MSIRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(osc_t osc) +{ + switch (osc) { + case PLL: + return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + break; + case HSE: + return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + break; + case HSI: + return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + break; + case LSE: + return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + break; + case LSI: + return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + break; + case MSI: + return ((RCC_CIR & RCC_CIR_MSIRDYF) != 0); + break; + } + + /* Shouldn't be reached. */ + return -1; +} + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +void rcc_wait_for_osc_ready(osc_t osc) +{ + switch (osc) { + case PLL: + while ((RCC_CR & RCC_CR_PLLRDY) == 0); + break; + case HSE: + while ((RCC_CR & RCC_CR_HSERDY) == 0); + break; + case HSI: + while ((RCC_CR & RCC_CR_HSIRDY) == 0); + break; + case MSI: + while ((RCC_CR & RCC_CR_MSIRDY) == 0); + break; + case LSE: + while ((RCC_CSR & RCC_CSR_LSERDY) == 0); + break; + case LSI: + while ((RCC_CSR & RCC_CSR_LSIRDY) == 0); + break; + } +} + +void rcc_wait_for_sysclk_status(osc_t osc) +{ + switch (osc) { + case PLL: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_PLLCLK); + break; + case HSE: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_HSECLK); + break; + case HSI: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_HSICLK); + break; + case MSI: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_MSICLK); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(osc_t osc) +{ + switch (osc) { + case PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case MSI: + RCC_CR |= RCC_CR_MSION; + break; + case HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case HSI: + RCC_CR |= RCC_CR_HSION; + break; + case LSE: + RCC_CSR |= RCC_CSR_LSEON; + break; + case LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(osc_t osc) +{ + switch (osc) { + case PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case MSI: + RCC_CR &= ~RCC_CR_MSION; + break; + case HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case LSE: + RCC_CSR &= ~RCC_CSR_LSEON; + break; + case LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +void rcc_osc_bypass_enable(osc_t osc) +{ + switch (osc) { + case HSE: + RCC_CR |= RCC_CR_HSEBYP; + break; + case LSE: + RCC_CSR |= RCC_CSR_LSEBYP; + break; + case PLL: + case HSI: + case LSI: + case MSI: + /* Do nothing, only HSE/LSE allowed here. */ + break; + } +} + +void rcc_osc_bypass_disable(osc_t osc) +{ + switch (osc) { + case HSE: + RCC_CR &= ~RCC_CR_HSEBYP; + break; + case LSE: + RCC_CSR &= ~RCC_CSR_LSEBYP; + break; + case PLL: + case HSI: + case LSI: + case MSI: + /* Do nothing, only HSE/LSE allowed here. */ + break; + } +} + +void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en) +{ + *reg |= en; +} + +void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en) +{ + *reg &= ~en; +} + +void rcc_peripheral_reset(volatile u32 *reg, u32 reset) +{ + *reg |= reset; +} + +void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset) +{ + *reg &= ~clear_reset; +} + +void rcc_set_sysclk_source(u32 clk) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | clk); +} + +void rcc_set_pll_source(u32 pllsrc) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(1 << 16); + RCC_CFGR = (reg32 | (pllsrc << 16)); +} + +void rcc_set_ppre2(u32 ppre2) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 13) | (1 << 12) | (1 << 11)); + RCC_CFGR = (reg32 | (ppre2 << 11)); +} + +void rcc_set_ppre1(u32 ppre1) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 10) | (1 << 9) | (1 << 8)); + RCC_CFGR = (reg32 | (ppre1 << 8)); +} + +void rcc_set_hpre(u32 hpre) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); + RCC_CFGR = (reg32 | (hpre << 4)); +} + +void rcc_set_rtcpre(u32 rtcpre) +{ + u32 reg32; + + reg32 = RCC_CR; + reg32 &= ~((1 << 30) | (1 << 29)); + RCC_CR = (reg32 | (rtcpre << 29)); +} + +u32 rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return ((RCC_CFGR & 0x000c) >> 2); +} + diff --git a/lib/stm32/f4/scb.c b/lib/stm32/l1/stm32l15xx8.ld index cbf4d539..1f20f571 100644 --- a/lib/stm32/f4/scb.c +++ b/lib/stm32/l1/stm32l15xx8.ld @@ -1,7 +1,7 @@ /* * This file is part of the libopencm3 project. * - * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz> + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -17,19 +17,15 @@ * along with this library. If not, see <http://www.gnu.org/licenses/>. */ -#include <libopencm3/stm32/f4/scb.h> +/* Linker script for STM32L15xx8, 64K flash, 10K RAM. */ -void scb_reset_core(void) +/* Define memory regions. */ +MEMORY { - SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_VECTRESET; + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K } -void scb_reset_system(void) -{ - SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ; -} +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l1.ld -void scb_set_priority_grouping(u32 prigroup) -{ - SCB_AIRCR = SCB_AIRCR_VECTKEY | prigroup; -} diff --git a/lib/stm32/l1/stm32l15xxb.ld b/lib/stm32/l1/stm32l15xxb.ld new file mode 100644 index 00000000..4c14b713 --- /dev/null +++ b/lib/stm32/l1/stm32l15xxb.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Linker script for STM32L15xxB, 128K flash, 16K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32l1.ld + diff --git a/lib/stm32/f1/timer.c b/lib/stm32/timer.c index 384eaaf0..a5cf99dd 100644 --- a/lib/stm32/f1/timer.c +++ b/lib/stm32/timer.c @@ -2,7 +2,7 @@ @ingroup STM32F1xx -@brief <b>libopencm3 STM32F1xx Timers</b> +@brief <b>libopencm3 STM32 Timers</b> @version 1.0.0 @@ -11,9 +11,9 @@ @date 18 August 2012 This library supports the General Purpose and Advanced Control Timers for -the STM32F1xx series of ARM Cortex Microcontrollers by ST Microelectronics. +the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics. -The STM32F1xx series have four general purpose timers (2-5), while some have +The STM32 series have four general purpose timers (2-5), while some have an additional two advanced timers (1,8), and some have two basic timers (6,7). Some of the larger devices have additional general purpose timers (9-14). @@ -70,6 +70,7 @@ push-pull outputs where the PWM output will appear. * This file is part of the libopencm3 project. * * Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org> + * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -96,7 +97,18 @@ push-pull outputs where the PWM output will appear. /**@{*/ #include <libopencm3/stm32/timer.h> -#include <libopencm3/stm32/f1/rcc.h> + +#if defined(STM32F1) +# include <libopencm3/stm32/f1/rcc.h> +#elif defined(STM32F2) +# include <libopencm3/stm32/f2/timer.h> +# include <libopencm3/stm32/f2/rcc.h> +#elif defined(STM32F4) +# include <libopencm3/stm32/f4/timer.h> +# include <libopencm3/stm32/f4/rcc.h> +#else +# error "stm32 family not defined." +#endif /*---------------------------------------------------------------------------*/ /** @brief Reset a Timer. @@ -1697,6 +1709,29 @@ u32 timer_get_counter(u32 timer_peripheral) } /*---------------------------------------------------------------------------*/ +/** @brief Set Timer Option + +Set timer options register on TIM2 or TIM5, used for oscillator calibration +on TIM5 and trigger remapping on TIM2. Only available on F4 and F2. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@returns Unsigned int32. Option flags. +*/ + +#if (defined(STM32F4) || defined(STM32F2)) +void timer_set_option(u32 timer_peripheral, u32 option) +{ + if (timer_peripheral == TIM2) { + TIM_OR(timer_peripheral) &= ~TIM2_OR_ITR1_RMP_MASK; + TIM_OR(timer_peripheral) |= option; + } else if (timer_peripheral == TIM5) { + TIM_OR(timer_peripheral) &= ~TIM5_OR_TI4_RMP_MASK; + TIM_OR(timer_peripheral) |= option; + } +} +#endif + +/*---------------------------------------------------------------------------*/ /** @brief Set Counter Set the value of a timer's counter register contents. diff --git a/lib/stm32/usart.c b/lib/stm32/usart.c index 5cf861b5..1faf4867 100644 --- a/lib/stm32/usart.c +++ b/lib/stm32/usart.c @@ -46,6 +46,8 @@ LGPL License Terms @ref lgpl_license # include <libopencm3/stm32/f2/rcc.h> #elif defined(STM32F4) # include <libopencm3/stm32/f4/rcc.h> +#elif defined(STM32L1) +# include <libopencm3/stm32/l1/rcc.h> #else # error "stm32 family not defined." #endif diff --git a/lib/usb/usb.c b/lib/usb/usb.c index 1ebb6ec5..0799202a 100644 --- a/lib/usb/usb.c +++ b/lib/usb/usb.c @@ -21,8 +21,6 @@ #include <libopencm3/usb/usbd.h> #include "usb_private.h" -struct _usbd_device _usbd_device; - u8 usbd_control_buffer[128] __attribute__((weak)); /** @@ -43,104 +41,112 @@ u8 usbd_control_buffer[128] __attribute__((weak)); * @param strings TODO * @return Zero on success (currently cannot fail). */ -int usbd_init(const usbd_driver *driver, - const struct usb_device_descriptor *dev, - const struct usb_config_descriptor *conf, const char **strings) +usbd_device *usbd_init(const usbd_driver *driver, + const struct usb_device_descriptor *dev, + const struct usb_config_descriptor *conf, + const char **strings, int num_strings) { - _usbd_device.driver = driver; - _usbd_device.desc = dev; - _usbd_device.config = conf; - _usbd_device.strings = strings; - _usbd_device.ctrl_buf = usbd_control_buffer; - _usbd_device.ctrl_buf_len = sizeof(usbd_control_buffer); + usbd_device *usbd_dev; + + usbd_dev = driver->init(); - _usbd_hw_init(); + usbd_dev->driver = driver; + usbd_dev->desc = dev; + usbd_dev->config = conf; + usbd_dev->strings = strings; + usbd_dev->num_strings = num_strings; + usbd_dev->ctrl_buf = usbd_control_buffer; + usbd_dev->ctrl_buf_len = sizeof(usbd_control_buffer); - _usbd_device.user_callback_ctr[0][USB_TRANSACTION_SETUP] = + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_SETUP] = _usbd_control_setup; - _usbd_device.user_callback_ctr[0][USB_TRANSACTION_OUT] = + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_OUT] = _usbd_control_out; - _usbd_device.user_callback_ctr[0][USB_TRANSACTION_IN] = + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_IN] = _usbd_control_in; - return 0; + return usbd_dev; } -void usbd_register_reset_callback(void (*callback)(void)) +void usbd_register_reset_callback(usbd_device *usbd_dev, void (*callback)(void)) { - _usbd_device.user_callback_reset = callback; + usbd_dev->user_callback_reset = callback; } -void usbd_register_suspend_callback(void (*callback)(void)) +void usbd_register_suspend_callback(usbd_device *usbd_dev, + void (*callback)(void)) { - _usbd_device.user_callback_suspend = callback; + usbd_dev->user_callback_suspend = callback; } -void usbd_register_resume_callback(void (*callback)(void)) +void usbd_register_resume_callback(usbd_device *usbd_dev, + void (*callback)(void)) { - _usbd_device.user_callback_resume = callback; + usbd_dev->user_callback_resume = callback; } -void usbd_register_sof_callback(void (*callback)(void)) +void usbd_register_sof_callback(usbd_device *usbd_dev, void (*callback)(void)) { - _usbd_device.user_callback_sof = callback; + usbd_dev->user_callback_sof = callback; } -void usbd_set_control_buffer_size(u16 size) +void usbd_set_control_buffer_size(usbd_device *usbd_dev, u16 size) { - _usbd_device.ctrl_buf_len = size; + usbd_dev->ctrl_buf_len = size; } -void _usbd_reset(void) +void _usbd_reset(usbd_device *usbd_dev) { - _usbd_device.current_address = 0; - _usbd_device.current_config = 0; - usbd_ep_setup(0, USB_ENDPOINT_ATTR_CONTROL, 64, NULL); - _usbd_hw_set_address(0); + usbd_dev->current_address = 0; + usbd_dev->current_config = 0; + usbd_ep_setup(usbd_dev, 0, USB_ENDPOINT_ATTR_CONTROL, 64, NULL); + usbd_dev->driver->set_address(usbd_dev, 0); - if (_usbd_device.user_callback_reset) - _usbd_device.user_callback_reset(); + if (usbd_dev->user_callback_reset) + usbd_dev->user_callback_reset(); } /* Functions to wrap the low-level driver */ -void usbd_poll(void) +void usbd_poll(usbd_device *usbd_dev) { - _usbd_device.driver->poll(); + usbd_dev->driver->poll(usbd_dev); } -void usbd_disconnect(bool disconnected) +void usbd_disconnect(usbd_device *usbd_dev, bool disconnected) { /* not all drivers support disconnection */ - if (_usbd_device.driver->disconnect) - _usbd_device.driver->disconnect(disconnected); + if (usbd_dev->driver->disconnect) + usbd_dev->driver->disconnect(usbd_dev, disconnected); } -void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback)(u8 ep)) +void usbd_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*callback)(usbd_device *usbd_dev, u8 ep)) { - _usbd_device.driver->ep_setup(addr, type, max_size, callback); + usbd_dev->driver->ep_setup(usbd_dev, addr, type, max_size, callback); } -u16 usbd_ep_write_packet(u8 addr, const void *buf, u16 len) +u16 usbd_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len) { - return _usbd_device.driver->ep_write_packet(addr, buf, len); + return usbd_dev->driver->ep_write_packet(usbd_dev, addr, buf, len); } -u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len) +u16 usbd_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, u16 len) { - return _usbd_device.driver->ep_read_packet(addr, buf, len); + return usbd_dev->driver->ep_read_packet(usbd_dev, addr, buf, len); } -void usbd_ep_stall_set(u8 addr, u8 stall) +void usbd_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall) { - _usbd_device.driver->ep_stall_set(addr, stall); + usbd_dev->driver->ep_stall_set(usbd_dev, addr, stall); } -u8 usbd_ep_stall_get(u8 addr) +u8 usbd_ep_stall_get(usbd_device *usbd_dev, u8 addr) { - return _usbd_device.driver->ep_stall_get(addr); + return usbd_dev->driver->ep_stall_get(usbd_dev, addr); } -void usbd_ep_nak_set(u8 addr, u8 nak) +void usbd_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak) { - _usbd_device.driver->ep_nak_set(addr, nak); + usbd_dev->driver->ep_nak_set(usbd_dev, addr, nak); } diff --git a/lib/usb/usb_control.c b/lib/usb/usb_control.c index 3dd08578..82843dfb 100644 --- a/lib/usb/usb_control.c +++ b/lib/usb/usb_control.c @@ -21,77 +21,73 @@ #include <libopencm3/usb/usbd.h> #include "usb_private.h" -static struct usb_control_state { - enum { - IDLE, STALLED, - DATA_IN, LAST_DATA_IN, STATUS_IN, - DATA_OUT, LAST_DATA_OUT, STATUS_OUT, - } state; - struct usb_setup_data req; - u8 *ctrl_buf; - u16 ctrl_len; - void (*complete)(struct usb_setup_data *req); -} control_state; - /* Register application callback function for handling USB control requests. */ -int usbd_register_control_callback(u8 type, u8 type_mask, +int usbd_register_control_callback(usbd_device *usbd_dev, u8 type, u8 type_mask, usbd_control_callback callback) { int i; for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) { - if (_usbd_device.user_control_callback[i].cb) + if (usbd_dev->user_control_callback[i].cb) continue; - _usbd_device.user_control_callback[i].type = type; - _usbd_device.user_control_callback[i].type_mask = type_mask; - _usbd_device.user_control_callback[i].cb = callback; + usbd_dev->user_control_callback[i].type = type; + usbd_dev->user_control_callback[i].type_mask = type_mask; + usbd_dev->user_control_callback[i].cb = callback; return 0; } return -1; } -static void usb_control_send_chunk(void) +static void usb_control_send_chunk(usbd_device *usbd_dev) { - if (_usbd_device.desc->bMaxPacketSize0 < control_state.ctrl_len) { + if (usbd_dev->desc->bMaxPacketSize0 < usbd_dev->control_state.ctrl_len) { /* Data stage, normal transmission */ - usbd_ep_write_packet(0, control_state.ctrl_buf, - _usbd_device.desc->bMaxPacketSize0); - control_state.state = DATA_IN; - control_state.ctrl_buf += _usbd_device.desc->bMaxPacketSize0; - control_state.ctrl_len -= _usbd_device.desc->bMaxPacketSize0; + usbd_ep_write_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf, + usbd_dev->desc->bMaxPacketSize0); + usbd_dev->control_state.state = DATA_IN; + usbd_dev->control_state.ctrl_buf += + usbd_dev->desc->bMaxPacketSize0; + usbd_dev->control_state.ctrl_len -= + usbd_dev->desc->bMaxPacketSize0; } else { /* Data stage, end of transmission */ - usbd_ep_write_packet(0, control_state.ctrl_buf, - control_state.ctrl_len); - control_state.state = LAST_DATA_IN; - control_state.ctrl_len = 0; - control_state.ctrl_buf = NULL; + usbd_ep_write_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf, + usbd_dev->control_state.ctrl_len); + usbd_dev->control_state.state = LAST_DATA_IN; + usbd_dev->control_state.ctrl_len = 0; + usbd_dev->control_state.ctrl_buf = NULL; } } -static int usb_control_recv_chunk(void) +static int usb_control_recv_chunk(usbd_device *usbd_dev) { - u16 packetsize = MIN(_usbd_device.desc->bMaxPacketSize0, - control_state.req.wLength - control_state.ctrl_len); - u16 size = usbd_ep_read_packet(0, control_state.ctrl_buf + - control_state.ctrl_len, packetsize); + u16 packetsize = MIN(usbd_dev->desc->bMaxPacketSize0, + usbd_dev->control_state.req.wLength - + usbd_dev->control_state.ctrl_len); + u16 size = usbd_ep_read_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf + + usbd_dev->control_state.ctrl_len, + packetsize); if (size != packetsize) { - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); return -1; } - control_state.ctrl_len += size; + usbd_dev->control_state.ctrl_len += size; return packetsize; } -static int usb_control_request_dispatch(struct usb_setup_data *req) +static int usb_control_request_dispatch(usbd_device *usbd_dev, + struct usb_setup_data *req) { int i, result = 0; - struct user_control_callback *cb = _usbd_device.user_control_callback; + struct user_control_callback *cb = usbd_dev->user_control_callback; /* Call user command hook function. */ for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) { @@ -99,140 +95,149 @@ static int usb_control_request_dispatch(struct usb_setup_data *req) break; if ((req->bmRequestType & cb[i].type_mask) == cb[i].type) { - result = cb[i].cb(req, &control_state.ctrl_buf, - &control_state.ctrl_len, - &control_state.complete); - if (result) + result = cb[i].cb(usbd_dev, req, + &(usbd_dev->control_state.ctrl_buf), + &(usbd_dev->control_state.ctrl_len), + &(usbd_dev->control_state.complete)); + if (result == USBD_REQ_HANDLED || + result == USBD_REQ_NOTSUPP) return result; } } - + /* Try standard request if not already handled. */ - return _usbd_standard_request(req, &control_state.ctrl_buf, - &control_state.ctrl_len); + return _usbd_standard_request(usbd_dev, req, + &(usbd_dev->control_state.ctrl_buf), + &(usbd_dev->control_state.ctrl_len)); } /* Handle commands and read requests. */ -static void usb_control_setup_read(struct usb_setup_data *req) +static void usb_control_setup_read(usbd_device *usbd_dev, + struct usb_setup_data *req) { - control_state.ctrl_buf = _usbd_device.ctrl_buf; - control_state.ctrl_len = req->wLength; + usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf; + usbd_dev->control_state.ctrl_len = req->wLength; - if (usb_control_request_dispatch(req)) { - if (control_state.ctrl_len) { + if (usb_control_request_dispatch(usbd_dev, req)) { + if (usbd_dev->control_state.ctrl_len) { /* Go to data out stage if handled. */ - usb_control_send_chunk(); + usb_control_send_chunk(usbd_dev); } else { /* Go to status stage if handled. */ - usbd_ep_write_packet(0, NULL, 0); - control_state.state = STATUS_IN; + usbd_ep_write_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = STATUS_IN; } } else { /* Stall endpoint on failure. */ - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); } } -static void usb_control_setup_write(struct usb_setup_data *req) +static void usb_control_setup_write(usbd_device *usbd_dev, + struct usb_setup_data *req) { - if (req->wLength > _usbd_device.ctrl_buf_len) { - usbd_ep_stall_set(0, 1); + if (req->wLength > usbd_dev->ctrl_buf_len) { + usbd_ep_stall_set(usbd_dev, 0, 1); return; } /* Buffer into which to write received data. */ - control_state.ctrl_buf = _usbd_device.ctrl_buf; - control_state.ctrl_len = 0; + usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf; + usbd_dev->control_state.ctrl_len = 0; /* Wait for DATA OUT stage. */ - if (req->wLength > _usbd_device.desc->bMaxPacketSize0) - control_state.state = DATA_OUT; + if (req->wLength > usbd_dev->desc->bMaxPacketSize0) + usbd_dev->control_state.state = DATA_OUT; else - control_state.state = LAST_DATA_OUT; + usbd_dev->control_state.state = LAST_DATA_OUT; } -void _usbd_control_setup(u8 ea) +void _usbd_control_setup(usbd_device *usbd_dev, u8 ea) { - struct usb_setup_data *req = &control_state.req; + struct usb_setup_data *req = &usbd_dev->control_state.req; (void)ea; - control_state.complete = NULL; + usbd_dev->control_state.complete = NULL; - if (usbd_ep_read_packet(0, req, 8) != 8) { - usbd_ep_stall_set(0, 1); + if (usbd_ep_read_packet(usbd_dev, 0, req, 8) != 8) { + usbd_ep_stall_set(usbd_dev, 0, 1); return; } if (req->wLength == 0) { - usb_control_setup_read(req); + usb_control_setup_read(usbd_dev, req); } else if (req->bmRequestType & 0x80) { - usb_control_setup_read(req); + usb_control_setup_read(usbd_dev, req); } else { - usb_control_setup_write(req); + usb_control_setup_write(usbd_dev, req); } } -void _usbd_control_out(u8 ea) +void _usbd_control_out(usbd_device *usbd_dev, u8 ea) { (void)ea; - switch (control_state.state) { + switch (usbd_dev->control_state.state) { case DATA_OUT: - if (usb_control_recv_chunk() < 0) + if (usb_control_recv_chunk(usbd_dev) < 0) break; - if ((control_state.req.wLength - control_state.ctrl_len) <= - _usbd_device.desc->bMaxPacketSize0) - control_state.state = LAST_DATA_OUT; + if ((usbd_dev->control_state.req.wLength - + usbd_dev->control_state.ctrl_len) <= + usbd_dev->desc->bMaxPacketSize0) + usbd_dev->control_state.state = LAST_DATA_OUT; break; case LAST_DATA_OUT: - if (usb_control_recv_chunk() < 0) + if (usb_control_recv_chunk(usbd_dev) < 0) break; /* * We have now received the full data payload. * Invoke callback to process. */ - if (usb_control_request_dispatch(&control_state.req)) { + if (usb_control_request_dispatch(usbd_dev, + &(usbd_dev->control_state.req))) { /* Got to status stage on success. */ - usbd_ep_write_packet(0, NULL, 0); - control_state.state = STATUS_IN; + usbd_ep_write_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = STATUS_IN; } else { - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); } break; case STATUS_OUT: - usbd_ep_read_packet(0, NULL, 0); - control_state.state = IDLE; - if (control_state.complete) - control_state.complete(&control_state.req); - control_state.complete = NULL; + usbd_ep_read_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = IDLE; + if (usbd_dev->control_state.complete) + usbd_dev->control_state.complete(usbd_dev, + &(usbd_dev->control_state.req)); + usbd_dev->control_state.complete = NULL; break; default: - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); } } -void _usbd_control_in(u8 ea) +void _usbd_control_in(usbd_device *usbd_dev, u8 ea) { (void)ea; - struct usb_setup_data *req = &control_state.req; + struct usb_setup_data *req = &(usbd_dev->control_state.req); - switch (control_state.state) { + switch (usbd_dev->control_state.state) { case DATA_IN: - usb_control_send_chunk(); + usb_control_send_chunk(usbd_dev); break; case LAST_DATA_IN: - control_state.state = STATUS_OUT; + usbd_dev->control_state.state = STATUS_OUT; break; case STATUS_IN: - if (control_state.complete) - control_state.complete(&control_state.req); + if (usbd_dev->control_state.complete) + usbd_dev->control_state.complete(usbd_dev, + &(usbd_dev->control_state.req)); /* Exception: Handle SET ADDRESS function here... */ if ((req->bmRequestType == 0) && (req->bRequest == USB_REQ_SET_ADDRESS)) - _usbd_hw_set_address(req->wValue); - control_state.state = IDLE; + usbd_dev->driver->set_address(usbd_dev, req->wValue); + usbd_dev->control_state.state = IDLE; break; default: - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); } } diff --git a/lib/usb/usb_f103.c b/lib/usb/usb_f103.c index 22db8ccf..aa323d97 100644 --- a/lib/usb/usb_f103.c +++ b/lib/usb/usb_f103.c @@ -24,19 +24,23 @@ #include <libopencm3/usb/usbd.h> #include "usb_private.h" -static void stm32f103_usbd_init(void); -static void stm32f103_set_address(u8 addr); -static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback) (u8 ep)); -static void stm32f103_endpoints_reset(void); -static void stm32f103_ep_stall_set(u8 addr, u8 stall); -static u8 stm32f103_ep_stall_get(u8 addr); -static void stm32f103_ep_nak_set(u8 addr, u8 nak); -static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len); -static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len); -static void stm32f103_poll(void); +static usbd_device *stm32f103_usbd_init(void); +static void stm32f103_set_address(usbd_device *usbd_dev, u8 addr); +static void stm32f103_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, + u16 max_size, + void (*callback) (usbd_device *usbd_dev, u8 ep)); +static void stm32f103_endpoints_reset(usbd_device *usbd_dev); +static void stm32f103_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall); +static u8 stm32f103_ep_stall_get(usbd_device *usbd_dev, u8 addr); +static void stm32f103_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak); +static u16 stm32f103_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len); +static u16 stm32f103_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, + u16 len); +static void stm32f103_poll(usbd_device *usbd_dev); static u8 force_nak[8]; +static struct _usbd_device usbd_dev; const struct _usbd_driver stm32f103_usb_driver = { .init = stm32f103_usbd_init, @@ -52,7 +56,7 @@ const struct _usbd_driver stm32f103_usb_driver = { }; /** Initialize the USB device controller hardware of the STM32. */ -static void stm32f103_usbd_init(void) +static usbd_device *stm32f103_usbd_init(void) { rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN); SET_REG(USB_CNTR_REG, 0); @@ -62,10 +66,12 @@ static void stm32f103_usbd_init(void) /* Enable RESET, SUSPEND, RESUME and CTR interrupts. */ SET_REG(USB_CNTR_REG, USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM); + return &usbd_dev; } -static void stm32f103_set_address(u8 addr) +static void stm32f103_set_address(usbd_device *usbd_dev, u8 addr) { + (void)usbd_dev; /* Set device address and enable. */ SET_REG(USB_DADDR_REG, (addr & USB_DADDR_ADDR) | USB_DADDR_ENABLE); } @@ -76,8 +82,9 @@ static void stm32f103_set_address(u8 addr) * @param ep Index of endpoint to configure. * @param size Size in bytes of the RX buffer. */ -static void usb_set_ep_rx_bufsize(u8 ep, u32 size) +static void usb_set_ep_rx_bufsize(usbd_device *usbd_dev, u8 ep, u32 size) { + (void)usbd_dev; if (size > 62) { if (size & 0x1f) size -= 32; @@ -89,8 +96,9 @@ static void usb_set_ep_rx_bufsize(u8 ep, u32 size) } } -static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback) (u8 ep)) +static void stm32f103_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, + u16 max_size, + void (*callback) (usbd_device *usbd_dev, u8 ep)) { /* Translate USB standard type codes to STM32. */ const u16 typelookup[] = { @@ -107,32 +115,30 @@ static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, USB_SET_EP_TYPE(addr, typelookup[type]); if (dir || (addr == 0)) { - USB_SET_EP_TX_ADDR(addr, _usbd_device.pm_top); + USB_SET_EP_TX_ADDR(addr, usbd_dev->pm_top); if (callback) { - _usbd_device. - user_callback_ctr[addr][USB_TRANSACTION_IN] = + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] = (void *)callback; } USB_CLR_EP_TX_DTOG(addr); USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_NAK); - _usbd_device.pm_top += max_size; + usbd_dev->pm_top += max_size; } if (!dir) { - USB_SET_EP_RX_ADDR(addr, _usbd_device.pm_top); - usb_set_ep_rx_bufsize(addr, max_size); + USB_SET_EP_RX_ADDR(addr, usbd_dev->pm_top); + usb_set_ep_rx_bufsize(usbd_dev, addr, max_size); if (callback) { - _usbd_device. - user_callback_ctr[addr][USB_TRANSACTION_OUT] = + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] = (void *)callback; } USB_CLR_EP_RX_DTOG(addr); USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID); - _usbd_device.pm_top += max_size; + usbd_dev->pm_top += max_size; } } -static void stm32f103_endpoints_reset(void) +static void stm32f103_endpoints_reset(usbd_device *usbd_dev) { int i; @@ -141,11 +147,12 @@ static void stm32f103_endpoints_reset(void) USB_SET_EP_TX_STAT(i, USB_EP_TX_STAT_DISABLED); USB_SET_EP_RX_STAT(i, USB_EP_RX_STAT_DISABLED); } - _usbd_device.pm_top = 0x40 + (2 * _usbd_device.desc->bMaxPacketSize0); + usbd_dev->pm_top = 0x40 + (2 * usbd_dev->desc->bMaxPacketSize0); } -static void stm32f103_ep_stall_set(u8 addr, u8 stall) +static void stm32f103_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall) { + (void)usbd_dev; if (addr == 0) USB_SET_EP_TX_STAT(addr, stall ? USB_EP_TX_STAT_STALL : USB_EP_TX_STAT_NAK); @@ -169,8 +176,9 @@ static void stm32f103_ep_stall_set(u8 addr, u8 stall) } } -static u8 stm32f103_ep_stall_get(u8 addr) +static u8 stm32f103_ep_stall_get(usbd_device *usbd_dev, u8 addr) { + (void)usbd_dev; if (addr & 0x80) { if ((*USB_EP_REG(addr & 0x7F) & USB_EP_TX_STAT) == USB_EP_TX_STAT_STALL) @@ -183,8 +191,9 @@ static u8 stm32f103_ep_stall_get(u8 addr) return 0; } -static void stm32f103_ep_nak_set(u8 addr, u8 nak) +static void stm32f103_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak) { + (void)usbd_dev; /* It does not make sence to force NAK on IN endpoints. */ if (addr & 0x80) return; @@ -213,8 +222,10 @@ static void usb_copy_to_pm(volatile void *vPM, const void *buf, u16 len) *PM = *lbuf; } -static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len) +static u16 stm32f103_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len) { + (void)usbd_dev; addr &= 0x7F; if ((*USB_EP_REG(addr) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) @@ -247,8 +258,10 @@ static void usb_copy_from_pm(void *buf, const volatile void *vPM, u16 len) *(u8 *) lbuf = *(u8 *) PM; } -static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len) +static u16 stm32f103_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, + u16 len) { + (void)usbd_dev; if ((*USB_EP_REG(addr) & USB_EP_RX_STAT) == USB_EP_RX_STAT_VALID) return 0; @@ -262,13 +275,13 @@ static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len) return len; } -static void stm32f103_poll(void) +static void stm32f103_poll(usbd_device *usbd_dev) { u16 istr = *USB_ISTR_REG; if (istr & USB_ISTR_RESET) { - _usbd_device.pm_top = 0x40; - _usbd_reset(); + usbd_dev->pm_top = 0x40; + _usbd_reset(usbd_dev); USB_CLR_ISTR_RESET(); return; } @@ -282,27 +295,27 @@ static void stm32f103_poll(void) else /* IN transaction */ USB_CLR_EP_TX_CTR(ep); - if (_usbd_device.user_callback_ctr[ep][type]) - _usbd_device.user_callback_ctr[ep][type] (ep); + if (usbd_dev->user_callback_ctr[ep][type]) + usbd_dev->user_callback_ctr[ep][type] (usbd_dev, ep); else USB_CLR_EP_RX_CTR(ep); } if (istr & USB_ISTR_SUSP) { USB_CLR_ISTR_SUSP(); - if (_usbd_device.user_callback_suspend) - _usbd_device.user_callback_suspend(); + if (usbd_dev->user_callback_suspend) + usbd_dev->user_callback_suspend(); } if (istr & USB_ISTR_WKUP) { USB_CLR_ISTR_WKUP(); - if (_usbd_device.user_callback_resume) - _usbd_device.user_callback_resume(); + if (usbd_dev->user_callback_resume) + usbd_dev->user_callback_resume(); } if (istr & USB_ISTR_SOF) { - if (_usbd_device.user_callback_sof) - _usbd_device.user_callback_sof(); + if (usbd_dev->user_callback_sof) + usbd_dev->user_callback_sof(); USB_CLR_ISTR_SOF(); } } diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c index a5a4a6c9..009979d6 100644 --- a/lib/usb/usb_f107.c +++ b/lib/usb/usb_f107.c @@ -23,49 +23,34 @@ #include <libopencm3/stm32/otg_fs.h> #include <libopencm3/usb/usbd.h> #include "usb_private.h" +#include "usb_fx07_common.h" /* Receive FIFO size in 32-bit words. */ #define RX_FIFO_SIZE 128 -static uint16_t fifo_mem_top; -static uint16_t fifo_mem_top_ep0; -static u8 force_nak[4]; +static usbd_device *stm32f107_usbd_init(void); -static void stm32f107_usbd_init(void); -static void stm32f107_set_address(u8 addr); -static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback)(u8 ep)); -static void stm32f107_endpoints_reset(void); -static void stm32f107_ep_stall_set(u8 addr, u8 stall); -static u8 stm32f107_ep_stall_get(u8 addr); -static void stm32f107_ep_nak_set(u8 addr, u8 nak); -static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len); -static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len); -static void stm32f107_poll(void); -static void stm32f107_disconnect(bool disconnected); - -/* - * We keep a backup copy of the out endpoint size registers to restore them - * after a transaction. - */ -static u32 doeptsiz[4]; +static struct _usbd_device usbd_dev; const struct _usbd_driver stm32f107_usb_driver = { .init = stm32f107_usbd_init, - .set_address = stm32f107_set_address, - .ep_setup = stm32f107_ep_setup, - .ep_reset = stm32f107_endpoints_reset, - .ep_stall_set = stm32f107_ep_stall_set, - .ep_stall_get = stm32f107_ep_stall_get, - .ep_nak_set = stm32f107_ep_nak_set, - .ep_write_packet = stm32f107_ep_write_packet, - .ep_read_packet = stm32f107_ep_read_packet, - .poll = stm32f107_poll, - .disconnect = stm32f107_disconnect, + .set_address = stm32fx07_set_address, + .ep_setup = stm32fx07_ep_setup, + .ep_reset = stm32fx07_endpoints_reset, + .ep_stall_set = stm32fx07_ep_stall_set, + .ep_stall_get = stm32fx07_ep_stall_get, + .ep_nak_set = stm32fx07_ep_nak_set, + .ep_write_packet = stm32fx07_ep_write_packet, + .ep_read_packet = stm32fx07_ep_read_packet, + .poll = stm32fx07_poll, + .disconnect = stm32fx07_disconnect, + .base_address = USB_OTG_FS_BASE, + .set_address_before_status = 1, + .rx_fifo_size = RX_FIFO_SIZE, }; /** Initialize the USB device controller hardware of the STM32. */ -static void stm32f107_usbd_init(void) +static usbd_device *stm32f107_usbd_init(void) { OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS; @@ -88,8 +73,8 @@ static void stm32f107_usbd_init(void) /* Restart the PHY clock. */ OTG_FS_PCGCCTL = 0; - OTG_FS_GRXFSIZ = RX_FIFO_SIZE; - fifo_mem_top = RX_FIFO_SIZE; + OTG_FS_GRXFSIZ = stm32f107_usb_driver.rx_fifo_size; + usbd_dev.fifo_mem_top = stm32f107_usb_driver.rx_fifo_size; /* Unmask interrupts for TX and RX. */ OTG_FS_GAHBCFG |= OTG_FS_GAHBCFG_GINT; @@ -101,289 +86,6 @@ static void stm32f107_usbd_init(void) OTG_FS_GINTMSK_SOFM; OTG_FS_DAINTMSK = 0xF; OTG_FS_DIEPMSK = OTG_FS_DIEPMSK_XFRCM; -} - -static void stm32f107_set_address(u8 addr) -{ - OTG_FS_DCFG = (OTG_FS_DCFG & ~OTG_FS_DCFG_DAD) | (addr << 4); -} - -static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback) (u8 ep)) -{ - /* - * Configure endpoint address and type. Allocate FIFO memory for - * endpoint. Install callback funciton. - */ - u8 dir = addr & 0x80; - addr &= 0x7f; - - if (addr == 0) { /* For the default control endpoint */ - /* Configure IN part. */ - if (max_size >= 64) { - OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_64; - } else if (max_size >= 32) { - OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_32; - } else if (max_size >= 16) { - OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_16; - } else { - OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_8; - } - OTG_FS_DIEPTSIZ0 = (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); - OTG_FS_DIEPCTL0 |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; - - /* Configure OUT part. */ - doeptsiz[0] = OTG_FS_DIEPSIZ0_STUPCNT_1 | (1 << 19) | - (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); - OTG_FS_DOEPTSIZ(0) = doeptsiz[0]; - OTG_FS_DOEPCTL(0) |= - OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; - - OTG_FS_GNPTXFSIZ = ((max_size / 4) << 16) | RX_FIFO_SIZE; - fifo_mem_top += max_size / 4; - fifo_mem_top_ep0 = fifo_mem_top; - - return; - } - - if (dir) { - OTG_FS_DIEPTXF(addr) = ((max_size / 4) << 16) | fifo_mem_top; - fifo_mem_top += max_size / 4; - - OTG_FS_DIEPTSIZ(addr) = - (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); - OTG_FS_DIEPCTL(addr) |= - OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK | (type << 18) - | OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID - | (addr << 22) | max_size; - - if (callback) { - _usbd_device. - user_callback_ctr[addr][USB_TRANSACTION_IN] = - (void *)callback; - } - } - - if (!dir) { - doeptsiz[addr] = (1 << 19) | - (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); - OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr]; - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | - OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK | - OTG_FS_DOEPCTLX_SD0PID | (type << 18) | max_size; - - if (callback) { - _usbd_device. - user_callback_ctr[addr][USB_TRANSACTION_OUT] = - (void *)callback; - } - } -} - -static void stm32f107_endpoints_reset(void) -{ - /* The core resets the endpoints automatically on reset. */ - fifo_mem_top = fifo_mem_top_ep0; -} - -static void stm32f107_ep_stall_set(u8 addr, u8 stall) -{ - if (addr == 0) { - if (stall) - OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL; - else - OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL; - } - - if (addr & 0x80) { - addr &= 0x7F; - - if (stall) { - OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL; - } else { - OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL; - OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTLX_SD0PID; - } - } else { - if (stall) { - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_STALL; - } else { - OTG_FS_DOEPCTL(addr) &= ~OTG_FS_DOEPCTL0_STALL; - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTLX_SD0PID; - } - } -} - -static u8 stm32f107_ep_stall_get(u8 addr) -{ - /* Return non-zero if STALL set. */ - if (addr & 0x80) - return - (OTG_FS_DIEPCTL(addr & 0x7f) & OTG_FS_DIEPCTL0_STALL) ? 1 : 0; - else - return (OTG_FS_DOEPCTL(addr) & OTG_FS_DOEPCTL0_STALL) ? 1 : 0; -} - -static void stm32f107_ep_nak_set(u8 addr, u8 nak) -{ - /* It does not make sence to force NAK on IN endpoints. */ - if (addr & 0x80) - return; - - force_nak[addr] = nak; - - if (nak) - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_SNAK; - else - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_CNAK; -} -static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len) -{ - const u32 *buf32 = buf; - int i; - - addr &= 0x7F; - - /* Return if endpoint is already enabled. */ - if (OTG_FS_DIEPTSIZ(addr) & OTG_FS_DIEPSIZ0_PKTCNT) - return 0; - - /* Enable endpoint for transmission. */ - OTG_FS_DIEPTSIZ(addr) = (1 << 19) | len; - OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_CNAK; - - /* Copy buffer to endpoint FIFO. */ - volatile u32 *fifo = OTG_FS_FIFO(addr); - for (i = len; i > 0; i -= 4) - *fifo++ = *buf32++; - - return len; -} - -/* - * Received packet size for each endpoint. This is assigned in - * stm32f107_poll() which reads the packet status push register GRXSTSP - * for use in stm32f107_ep_read_packet(). - */ -static uint16_t rxbcnt; - -static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len) -{ - int i; - u32 *buf32 = buf; - u32 extra; - - len = MIN(len, rxbcnt); - rxbcnt -= len; - - volatile u32 *fifo = OTG_FS_FIFO(addr); - for (i = len; i >= 4; i -= 4) - *buf32++ = *fifo++; - - if (i) { - extra = *fifo++; - memcpy(buf32, &extra, i); - } - - OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr]; - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | - (force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK); - - return len; -} - -static void stm32f107_poll(void) -{ - /* Read interrupt status register. */ - u32 intsts = OTG_FS_GINTSTS; - int i; - - if (intsts & OTG_FS_GINTSTS_ENUMDNE) { - /* Handle USB RESET condition. */ - OTG_FS_GINTSTS = OTG_FS_GINTSTS_ENUMDNE; - fifo_mem_top = RX_FIFO_SIZE; - _usbd_reset(); - return; - } - - /* Note: RX and TX handled differently in this device. */ - if (intsts & OTG_FS_GINTSTS_RXFLVL) { - /* Receive FIFO non-empty. */ - u32 rxstsp = OTG_FS_GRXSTSP; - u32 pktsts = rxstsp & OTG_FS_GRXSTSP_PKTSTS_MASK; - if ((pktsts != OTG_FS_GRXSTSP_PKTSTS_OUT) && - (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP)) - return; - - u8 ep = rxstsp & OTG_FS_GRXSTSP_EPNUM_MASK; - u8 type; - if (pktsts == OTG_FS_GRXSTSP_PKTSTS_SETUP) - type = USB_TRANSACTION_SETUP; - else - type = USB_TRANSACTION_OUT; - - /* Save packet size for stm32f107_ep_read_packet(). */ - rxbcnt = (rxstsp & OTG_FS_GRXSTSP_BCNT_MASK) >> 4; - - /* - * FIXME: Why is a delay needed here? - * This appears to fix a problem where the first 4 bytes - * of the DATA OUT stage of a control transaction are lost. - */ - for (i = 0; i < 1000; i++) - __asm__("nop"); - - if (_usbd_device.user_callback_ctr[ep][type]) - _usbd_device.user_callback_ctr[ep][type] (ep); - - /* Discard unread packet data. */ - for (i = 0; i < rxbcnt; i += 4) - (void)*OTG_FS_FIFO(ep); - - rxbcnt = 0; - } - - /* - * There is no global interrupt flag for transmit complete. - * The XFRC bit must be checked in each OTG_FS_DIEPINT(x). - */ - for (i = 0; i < 4; i++) { /* Iterate over endpoints. */ - if (OTG_FS_DIEPINT(i) & OTG_FS_DIEPINTX_XFRC) { - /* Transfer complete. */ - if (_usbd_device. - user_callback_ctr[i][USB_TRANSACTION_IN]) { - _usbd_device. - user_callback_ctr[i][USB_TRANSACTION_IN](i); - } - OTG_FS_DIEPINT(i) = OTG_FS_DIEPINTX_XFRC; - } - } - - if (intsts & OTG_FS_GINTSTS_USBSUSP) { - if (_usbd_device.user_callback_suspend) - _usbd_device.user_callback_suspend(); - OTG_FS_GINTSTS = OTG_FS_GINTSTS_USBSUSP; - } - - if (intsts & OTG_FS_GINTSTS_WKUPINT) { - if (_usbd_device.user_callback_resume) - _usbd_device.user_callback_resume(); - OTG_FS_GINTSTS = OTG_FS_GINTSTS_WKUPINT; - } - - if (intsts & OTG_FS_GINTSTS_SOF) { - if (_usbd_device.user_callback_sof) - _usbd_device.user_callback_sof(); - OTG_FS_GINTSTS = OTG_FS_GINTSTS_SOF; - } -} - -static void stm32f107_disconnect(bool disconnected) -{ - if (disconnected) { - OTG_FS_DCTL |= OTG_FS_DCTL_SDIS; - } else { - OTG_FS_DCTL &= ~OTG_FS_DCTL_SDIS; - } + return &usbd_dev; } diff --git a/lib/usb/usb_f207.c b/lib/usb/usb_f207.c new file mode 100644 index 00000000..b2509e5e --- /dev/null +++ b/lib/usb/usb_f207.c @@ -0,0 +1,91 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <libopencm3/cm3/common.h> +#include <libopencm3/stm32/tools.h> +#include <libopencm3/stm32/otg_hs.h> +#include <libopencm3/usb/usbd.h> +#include "usb_private.h" +#include "usb_fx07_common.h" + +/* Receive FIFO size in 32-bit words. */ +#define RX_FIFO_SIZE 512 + +static usbd_device *stm32f207_usbd_init(void); + +static struct _usbd_device usbd_dev; + +const struct _usbd_driver stm32f207_usb_driver = { + .init = stm32f207_usbd_init, + .set_address = stm32fx07_set_address, + .ep_setup = stm32fx07_ep_setup, + .ep_reset = stm32fx07_endpoints_reset, + .ep_stall_set = stm32fx07_ep_stall_set, + .ep_stall_get = stm32fx07_ep_stall_get, + .ep_nak_set = stm32fx07_ep_nak_set, + .ep_write_packet = stm32fx07_ep_write_packet, + .ep_read_packet = stm32fx07_ep_read_packet, + .poll = stm32fx07_poll, + .disconnect = stm32fx07_disconnect, + .base_address = USB_OTG_HS_BASE, + .set_address_before_status = 1, + .rx_fifo_size = RX_FIFO_SIZE, +}; + +/** Initialize the USB device controller hardware of the STM32. */ +static usbd_device *stm32f207_usbd_init(void) +{ + OTG_HS_GINTSTS = OTG_HS_GINTSTS_MMIS; + + OTG_HS_GUSBCFG |= OTG_HS_GUSBCFG_PHYSEL; + /* Enable VBUS sensing in device mode and power down the PHY. */ + OTG_HS_GCCFG |= OTG_HS_GCCFG_VBUSBSEN | OTG_HS_GCCFG_PWRDWN; + + /* Wait for AHB idle. */ + while (!(OTG_HS_GRSTCTL & OTG_HS_GRSTCTL_AHBIDL)) ; + /* Do core soft reset. */ + OTG_HS_GRSTCTL |= OTG_HS_GRSTCTL_CSRST; + while (OTG_HS_GRSTCTL & OTG_HS_GRSTCTL_CSRST) ; + + /* Force peripheral only mode. */ + OTG_HS_GUSBCFG |= OTG_HS_GUSBCFG_FDMOD | OTG_HS_GUSBCFG_TRDT_MASK; + + /* Full speed device. */ + OTG_HS_DCFG |= OTG_HS_DCFG_DSPD; + + /* Restart the PHY clock. */ + OTG_HS_PCGCCTL = 0; + + OTG_HS_GRXFSIZ = stm32f207_usb_driver.rx_fifo_size; + usbd_dev.fifo_mem_top = stm32f207_usb_driver.rx_fifo_size; + + /* Unmask interrupts for TX and RX. */ + OTG_HS_GAHBCFG |= OTG_HS_GAHBCFG_GINT; + OTG_HS_GINTMSK = OTG_HS_GINTMSK_ENUMDNEM | + OTG_HS_GINTMSK_RXFLVLM | + OTG_HS_GINTMSK_IEPINT | + OTG_HS_GINTMSK_USBSUSPM | + OTG_HS_GINTMSK_WUIM | + OTG_HS_GINTMSK_SOFM; + OTG_HS_DAINTMSK = 0xF; + OTG_HS_DIEPMSK = OTG_HS_DIEPMSK_XFRCM; + + return &usbd_dev; +} diff --git a/lib/usb/usb_fx07_common.c b/lib/usb/usb_fx07_common.c new file mode 100644 index 00000000..9178092c --- /dev/null +++ b/lib/usb/usb_fx07_common.c @@ -0,0 +1,318 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <libopencm3/cm3/common.h> +#include <libopencm3/stm32/tools.h> +#include <libopencm3/stm32/otg_fs.h> +#include <libopencm3/stm32/otg_hs.h> +#include <libopencm3/usb/usbd.h> +#include "usb_private.h" +#include "usb_fx07_common.h" + +/* The FS core and the HS core have the same register layout. + * As the code can be used on both cores, the registers offset is modified + * according to the selected cores base address. */ +#define dev_base_address (usbd_dev->driver->base_address) +#define REBASE(x) MMIO32((x)+(dev_base_address)) +#define REBASE_FIFO(x) ((volatile u32*)((dev_base_address) + (OTG_FIFO(x)))) + +void stm32fx07_set_address(usbd_device *usbd_dev, u8 addr) +{ + REBASE(OTG_DCFG) = (REBASE(OTG_DCFG) & ~OTG_FS_DCFG_DAD) | (addr << 4); +} + +void stm32fx07_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*callback) (usbd_device *usbd_dev, u8 ep)) +{ + /* + * Configure endpoint address and type. Allocate FIFO memory for + * endpoint. Install callback funciton. + */ + u8 dir = addr & 0x80; + addr &= 0x7f; + + if (addr == 0) { /* For the default control endpoint */ + /* Configure IN part. */ + if (max_size >= 64) { + REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_64; + } else if (max_size >= 32) { + REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_32; + } else if (max_size >= 16) { + REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_16; + } else { + REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_8; + } + REBASE(OTG_DIEPTSIZ0) = + (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DIEPCTL0) |= + OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; + + /* Configure OUT part. */ + usbd_dev->doeptsiz[0] = OTG_FS_DIEPSIZ0_STUPCNT_1 | + OTG_FS_DIEPSIZ0_PKTCNT | + (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DOEPTSIZ(0)) = usbd_dev->doeptsiz[0]; + REBASE(OTG_DOEPCTL(0)) |= + OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; + + REBASE(OTG_GNPTXFSIZ) = ((max_size / 4) << 16) | + usbd_dev->driver->rx_fifo_size; + usbd_dev->fifo_mem_top += max_size / 4; + usbd_dev->fifo_mem_top_ep0 = usbd_dev->fifo_mem_top; + + return; + } + + if (dir) { + REBASE(OTG_DIEPTXF(addr)) = ((max_size / 4) << 16) | + usbd_dev->fifo_mem_top; + usbd_dev->fifo_mem_top += max_size / 4; + + REBASE(OTG_DIEPTSIZ(addr)) = + (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DIEPCTL(addr)) |= + OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK | (type << 18) + | OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID + | (addr << 22) | max_size; + + if (callback) { + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] = + (void *)callback; + } + } + + if (!dir) { + usbd_dev->doeptsiz[addr] = OTG_FS_DIEPSIZ0_PKTCNT | + (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr]; + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_EPENA | + OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK | + OTG_FS_DOEPCTLX_SD0PID | (type << 18) | max_size; + + if (callback) { + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] = + (void *)callback; + } + } +} + +void stm32fx07_endpoints_reset(usbd_device *usbd_dev) +{ + /* The core resets the endpoints automatically on reset. */ + usbd_dev->fifo_mem_top = usbd_dev->fifo_mem_top_ep0; +} + +void stm32fx07_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall) +{ + if (addr == 0) { + if (stall) + REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_STALL; + else + REBASE(OTG_DIEPCTL(addr)) &= ~OTG_FS_DIEPCTL0_STALL; + } + + if (addr & 0x80) { + addr &= 0x7F; + + if (stall) { + REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_STALL; + } else { + REBASE(OTG_DIEPCTL(addr)) &= ~OTG_FS_DIEPCTL0_STALL; + REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTLX_SD0PID; + } + } else { + if (stall) { + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_STALL; + } else { + REBASE(OTG_DOEPCTL(addr)) &= ~OTG_FS_DOEPCTL0_STALL; + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTLX_SD0PID; + } + } +} + +u8 stm32fx07_ep_stall_get(usbd_device *usbd_dev, u8 addr) +{ + /* Return non-zero if STALL set. */ + if (addr & 0x80) + return (REBASE(OTG_DIEPCTL(addr & 0x7f)) & + OTG_FS_DIEPCTL0_STALL) ? 1 : 0; + else + return (REBASE(OTG_DOEPCTL(addr)) & + OTG_FS_DOEPCTL0_STALL) ? 1 : 0; +} + +void stm32fx07_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak) +{ + /* It does not make sence to force NAK on IN endpoints. */ + if (addr & 0x80) + return; + + usbd_dev->force_nak[addr] = nak; + + if (nak) + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_SNAK; + else + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_CNAK; +} + +u16 stm32fx07_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len) +{ + const u32 *buf32 = buf; + int i; + + addr &= 0x7F; + + /* Return if endpoint is already enabled. */ + if (REBASE(OTG_DIEPTSIZ(addr)) & OTG_FS_DIEPSIZ0_PKTCNT) + return 0; + + /* Enable endpoint for transmission. */ + REBASE(OTG_DIEPTSIZ(addr)) = OTG_FS_DIEPSIZ0_PKTCNT | len; + REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_EPENA | + OTG_FS_DIEPCTL0_CNAK; + volatile u32 *fifo = REBASE_FIFO(addr); + + /* Copy buffer to endpoint FIFO, note - memcpy does not work */ + for (i = len; i > 0; i -= 4) + *fifo++ = *buf32++; + + return len; +} + +u16 stm32fx07_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, u16 len) +{ + int i; + u32 *buf32 = buf; + u32 extra; + + len = MIN(len, usbd_dev->rxbcnt); + usbd_dev->rxbcnt -= len; + + volatile u32 *fifo = REBASE_FIFO(addr); + for (i = len; i >= 4; i -= 4) + *buf32++ = *fifo++; + + if (i) { + extra = *fifo++; + memcpy(buf32, &extra, i); + } + + REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr]; + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_EPENA | + (usbd_dev->force_nak[addr] ? + OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK); + + return len; +} + +void stm32fx07_poll(usbd_device *usbd_dev) +{ + /* Read interrupt status register. */ + u32 intsts = REBASE(OTG_GINTSTS); + int i; + + if (intsts & OTG_FS_GINTSTS_ENUMDNE) { + /* Handle USB RESET condition. */ + REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_ENUMDNE; + usbd_dev->fifo_mem_top = usbd_dev->driver->rx_fifo_size; + _usbd_reset(usbd_dev); + return; + } + + /* Note: RX and TX handled differently in this device. */ + if (intsts & OTG_FS_GINTSTS_RXFLVL) { + /* Receive FIFO non-empty. */ + u32 rxstsp = REBASE(OTG_GRXSTSP); + u32 pktsts = rxstsp & OTG_FS_GRXSTSP_PKTSTS_MASK; + if ((pktsts != OTG_FS_GRXSTSP_PKTSTS_OUT) && + (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP)) + return; + + u8 ep = rxstsp & OTG_FS_GRXSTSP_EPNUM_MASK; + u8 type; + if (pktsts == OTG_FS_GRXSTSP_PKTSTS_SETUP) + type = USB_TRANSACTION_SETUP; + else + type = USB_TRANSACTION_OUT; + + /* Save packet size for stm32f107_ep_read_packet(). */ + usbd_dev->rxbcnt = (rxstsp & OTG_FS_GRXSTSP_BCNT_MASK) >> 4; + + /* + * FIXME: Why is a delay needed here? + * This appears to fix a problem where the first 4 bytes + * of the DATA OUT stage of a control transaction are lost. + */ + for (i = 0; i < 1000; i++) + __asm__("nop"); + + if (usbd_dev->user_callback_ctr[ep][type]) + usbd_dev->user_callback_ctr[ep][type] (usbd_dev, ep); + + /* Discard unread packet data. */ + for (i = 0; i < usbd_dev->rxbcnt; i += 4) + (void)*REBASE_FIFO(ep); + + usbd_dev->rxbcnt = 0; + } + + /* + * There is no global interrupt flag for transmit complete. + * The XFRC bit must be checked in each OTG_FS_DIEPINT(x). + */ + for (i = 0; i < 4; i++) { /* Iterate over endpoints. */ + if (REBASE(OTG_DIEPINT(i)) & OTG_FS_DIEPINTX_XFRC) { + /* Transfer complete. */ + if (usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN]) + usbd_dev->user_callback_ctr[i] + [USB_TRANSACTION_IN](usbd_dev, i); + + REBASE(OTG_DIEPINT(i)) = OTG_FS_DIEPINTX_XFRC; + } + } + + if (intsts & OTG_FS_GINTSTS_USBSUSP) { + if (usbd_dev->user_callback_suspend) + usbd_dev->user_callback_suspend(); + REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_USBSUSP; + } + + if (intsts & OTG_FS_GINTSTS_WKUPINT) { + if (usbd_dev->user_callback_resume) + usbd_dev->user_callback_resume(); + REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_WKUPINT; + } + + if (intsts & OTG_FS_GINTSTS_SOF) { + if (usbd_dev->user_callback_sof) + usbd_dev->user_callback_sof(); + REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_SOF; + } +} + +void stm32fx07_disconnect(usbd_device *usbd_dev, bool disconnected) +{ + if (disconnected) { + REBASE(OTG_DCTL) |= OTG_FS_DCTL_SDIS; + } else { + REBASE(OTG_DCTL) &= ~OTG_FS_DCTL_SDIS; + } +} diff --git a/lib/usb/usb_fx07_common.h b/lib/usb/usb_fx07_common.h new file mode 100644 index 00000000..4d8d38e2 --- /dev/null +++ b/lib/usb/usb_fx07_common.h @@ -0,0 +1,38 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __USB_FX07_COMMON_H_ +#define __USB_FX07_COMMON_H_ + +void stm32fx07_set_address(usbd_device *usbd_dev, u8 addr); +void stm32fx07_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*callback)(usbd_device *usbd_dev, u8 ep)); +void stm32fx07_endpoints_reset(usbd_device *usbd_dev); +void stm32fx07_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall); +u8 stm32fx07_ep_stall_get(usbd_device *usbd_dev, u8 addr); +void stm32fx07_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak); +u16 stm32fx07_ep_write_packet(usbd_device *usbd_dev, u8 addr, const void *buf, + u16 len); +u16 stm32fx07_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, + u16 len); +void stm32fx07_poll(usbd_device *usbd_dev); +void stm32fx07_disconnect(usbd_device *usbd_dev, bool disconnected); + + +#endif /* __USB_FX07_COMMON_H_ */ diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h index a1e5e4c8..454e8c6b 100644 --- a/lib/usb/usb_private.h +++ b/lib/usb/usb_private.h @@ -25,10 +25,11 @@ #define MIN(a, b) ((a)<(b) ? (a) : (b)) /** Internal collection of device information. */ -extern struct _usbd_device { +struct _usbd_device { const struct usb_device_descriptor *desc; const struct usb_config_descriptor *config; const char **strings; + int num_strings; u8 *ctrl_buf; /**< Internal buffer used for control transfers */ u16 ctrl_buf_len; @@ -44,19 +45,49 @@ extern struct _usbd_device { void (*user_callback_resume)(void); void (*user_callback_sof)(void); + struct usb_control_state { + enum { + IDLE, STALLED, + DATA_IN, LAST_DATA_IN, STATUS_IN, + DATA_OUT, LAST_DATA_OUT, STATUS_OUT, + } state; + struct usb_setup_data req __attribute__((aligned(4))); + u8 *ctrl_buf; + u16 ctrl_len; + void (*complete)(usbd_device *usbd_dev, + struct usb_setup_data *req); + } control_state; + struct user_control_callback { usbd_control_callback cb; u8 type; u8 type_mask; } user_control_callback[MAX_USER_CONTROL_CALLBACK]; - void (*user_callback_ctr[8][3])(u8 ea); + void (*user_callback_ctr[8][3])(usbd_device *usbd_dev, u8 ea); /* User callback function for some standard USB function hooks */ - void (*user_callback_set_config)(u16 wValue); + void (*user_callback_set_config)(usbd_device *usbd_dev, u16 wValue); const struct _usbd_driver *driver; -} _usbd_device; + + /* private driver data */ + + uint16_t fifo_mem_top; + uint16_t fifo_mem_top_ep0; + u8 force_nak[4]; + /* + * We keep a backup copy of the out endpoint size registers to restore them + * after a transaction. + */ + u32 doeptsiz[4]; + /* + * Received packet size for each endpoint. This is assigned in + * stm32f107_poll() which reads the packet status push register GRXSTSP + * for use in stm32f107_ep_read_packet(). + */ + uint16_t rxbcnt; +}; enum _usbd_transaction { USB_TRANSACTION_IN, @@ -64,31 +95,34 @@ enum _usbd_transaction { USB_TRANSACTION_SETUP, }; -void _usbd_control_in(u8 ea); -void _usbd_control_out(u8 ea); -void _usbd_control_setup(u8 ea); +void _usbd_control_in(usbd_device *usbd_dev, u8 ea); +void _usbd_control_out(usbd_device *usbd_dev, u8 ea); +void _usbd_control_setup(usbd_device *usbd_dev, u8 ea); -int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len); +int _usbd_standard_request(usbd_device *usbd_dev, struct usb_setup_data *req, + u8 **buf, u16 *len); -void _usbd_reset(void); +void _usbd_reset(usbd_device *usbd_dev); /* Functions provided by the hardware abstraction. */ struct _usbd_driver { - void (*init)(void); - void (*set_address)(u8 addr); - void (*ep_setup)(u8 addr, u8 type, u16 max_size, void (*cb)(u8 ep)); - void (*ep_reset)(void); - void (*ep_stall_set)(u8 addr, u8 stall); - void (*ep_nak_set)(u8 addr, u8 nak); - u8 (*ep_stall_get)(u8 addr); - u16 (*ep_write_packet)(u8 addr, const void *buf, u16 len); - u16 (*ep_read_packet)(u8 addr, void *buf, u16 len); - void (*poll)(void); - void (*disconnect)(bool disconnected); + usbd_device *(*init)(void); + void (*set_address)(usbd_device *usbd_dev, u8 addr); + void (*ep_setup)(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*cb)(usbd_device *usbd_dev, u8 ep)); + void (*ep_reset)(usbd_device *usbd_dev); + void (*ep_stall_set)(usbd_device *usbd_dev, u8 addr, u8 stall); + void (*ep_nak_set)(usbd_device *usbd_dev, u8 addr, u8 nak); + u8 (*ep_stall_get)(usbd_device *usbd_dev, u8 addr); + u16 (*ep_write_packet)(usbd_device *usbd_dev, u8 addr, const void *buf, + u16 len); + u16 (*ep_read_packet)(usbd_device *usbd_dev, u8 addr, void *buf, + u16 len); + void (*poll)(usbd_device *usbd_dev); + void (*disconnect)(usbd_device *usbd_dev, bool disconnected); + u32 base_address; + bool set_address_before_status; + u16 rx_fifo_size; }; -#define _usbd_hw_init() _usbd_device.driver->init() -#define _usbd_hw_set_address(addr) _usbd_device.driver->set_address(addr) -#define _usbd_hw_endpoints_reset() _usbd_device.driver->ep_reset() - #endif diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c index 2d7c619e..e14fee35 100644 --- a/lib/usb/usb_standard.c +++ b/lib/usb/usb_standard.c @@ -21,15 +21,18 @@ #include <libopencm3/usb/usbd.h> #include "usb_private.h" -void usbd_register_set_config_callback(void (*callback)(u16 wValue)) +void usbd_register_set_config_callback(usbd_device *usbd_dev, + void (*callback)(usbd_device *usbd_dev, + u16 wValue)) { - _usbd_device.user_callback_set_config = callback; + usbd_dev->user_callback_set_config = callback; } -static u16 build_config_descriptor(u8 index, u8 *buf, u16 len) +static u16 build_config_descriptor(usbd_device *usbd_dev, + u8 index, u8 *buf, u16 len) { u8 *tmpbuf = buf; - const struct usb_config_descriptor *cfg = &_usbd_device.config[index]; + const struct usb_config_descriptor *cfg = &usbd_dev->config[index]; u16 count, total = 0, totallen = 0; u16 i, j, k; @@ -43,7 +46,7 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len) for (i = 0; i < cfg->bNumInterfaces; i++) { /* Interface Association Descriptor, if any */ if (cfg->interface[i].iface_assoc) { - const struct usb_iface_assoc_descriptor *assoc = + const struct usb_iface_assoc_descriptor *assoc = cfg->interface[i].iface_assoc; memcpy(buf, assoc, count = MIN(len, assoc->bLength)); buf += count; @@ -87,53 +90,79 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len) return total; } -static int usb_standard_get_descriptor(struct usb_setup_data *req, +static int usb_descriptor_type(u16 wValue) +{ + return wValue >> 8; +} + +static int usb_descriptor_index(u16 wValue) +{ + return wValue & 0xFF; +} + +static int usb_standard_get_descriptor(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { - int i; + int i, array_idx, descr_idx; struct usb_string_descriptor *sd; - switch (req->wValue >> 8) { + descr_idx = usb_descriptor_index(req->wValue); + + switch (usb_descriptor_type(req->wValue)) { case USB_DT_DEVICE: - *buf = (u8 *) _usbd_device.desc; - *len = MIN(*len, _usbd_device.desc->bLength); - return 1; + *buf = (u8 *) usbd_dev->desc; + *len = MIN(*len, usbd_dev->desc->bLength); + return USBD_REQ_HANDLED; case USB_DT_CONFIGURATION: - *buf = _usbd_device.ctrl_buf; - *len = build_config_descriptor(req->wValue & 0xff, *buf, *len); - return 1; + *buf = usbd_dev->ctrl_buf; + *len = build_config_descriptor(usbd_dev, descr_idx, *buf, *len); + return USBD_REQ_HANDLED; case USB_DT_STRING: - sd = (struct usb_string_descriptor *)_usbd_device.ctrl_buf; - - if (!_usbd_device.strings) - return 0; /* Device doesn't support strings. */ - - /* Check that string index is in range. */ - for (i = 0; i <= (req->wValue & 0xff); i++) - if (_usbd_device.strings[i] == NULL) - return 0; + sd = (struct usb_string_descriptor *)usbd_dev->ctrl_buf; + + if (descr_idx == 0) { + /* Send sane Language ID descriptor... */ + sd->wData[0] = USB_LANGID_ENGLISH_US; + sd->bLength = sizeof(sd->bLength) + sizeof(sd->bDescriptorType) + + sizeof(sd->wData[0]); + + *len = MIN(*len, sd->bLength); + } else { + array_idx = descr_idx - 1; + + if (!usbd_dev->strings) + return USBD_REQ_NOTSUPP; /* Device doesn't support strings. */ + /* Check that string index is in range. */ + if (array_idx >= usbd_dev->num_strings) + return USBD_REQ_NOTSUPP; + + /* Strings with Language ID differnet from + * USB_LANGID_ENGLISH_US are not supported */ + if (req->wIndex != USB_LANGID_ENGLISH_US) + return USBD_REQ_NOTSUPP; + + /* Ths string is returned as UTF16, hence the multiplication */ + sd->bLength = strlen(usbd_dev->strings[array_idx]) * 2 + + sizeof(sd->bLength) + sizeof(sd->bDescriptorType); + + *len = MIN(*len, sd->bLength); + + for (i = 0; i < (*len / 2) - 1; i++) + sd->wData[i] = + usbd_dev->strings[array_idx][i]; + } - sd->bLength = strlen(_usbd_device.strings[req->wValue & 0xff]) - * 2 + 2; sd->bDescriptorType = USB_DT_STRING; - *buf = (u8 *)sd; - *len = MIN(*len, sd->bLength); - - for (i = 0; i < (*len / 2) - 1; i++) - sd->wData[i] = - _usbd_device.strings[req->wValue & 0xff][i]; - /* Send sane Language ID descriptor... */ - if ((req->wValue & 0xff) == 0) - sd->wData[0] = 0x409; - - return 1; + return USBD_REQ_HANDLED; } - return 0; + return USBD_REQ_NOTSUPP; } -static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf, +static int usb_standard_set_address(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)req; @@ -144,19 +173,20 @@ static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf, if ((req->bmRequestType != 0) || (req->wValue >= 128)) return 0; - _usbd_device.current_address = req->wValue; + usbd_dev->current_address = req->wValue; /* * Special workaround for STM32F10[57] that require the address * to be set here. This is undocumented! */ - if (_usbd_device.driver == &stm32f107_usb_driver) - _usbd_device.driver->set_address(req->wValue); + if ( usbd_dev->driver->set_address_before_status) + usbd_dev->driver->set_address(usbd_dev, req->wValue); return 1; } -static int usb_standard_set_configuration(struct usb_setup_data *req, +static int usb_standard_set_configuration(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { int i; @@ -166,43 +196,46 @@ static int usb_standard_set_configuration(struct usb_setup_data *req, (void)len; /* Is this correct, or should we reset alternate settings. */ - if (req->wValue == _usbd_device.current_config) + if (req->wValue == usbd_dev->current_config) return 1; - _usbd_device.current_config = req->wValue; + usbd_dev->current_config = req->wValue; /* Reset all endpoints. */ - _usbd_hw_endpoints_reset(); + usbd_dev->driver->ep_reset(usbd_dev); - if (_usbd_device.user_callback_set_config) { + if (usbd_dev->user_callback_set_config) { /* * Flush control callbacks. These will be reregistered * by the user handler. */ for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) - _usbd_device.user_control_callback[i].cb = NULL; + usbd_dev->user_control_callback[i].cb = NULL; - _usbd_device.user_callback_set_config(req->wValue); + usbd_dev->user_callback_set_config(usbd_dev, req->wValue); } return 1; } -static int usb_standard_get_configuration(struct usb_setup_data *req, +static int usb_standard_get_configuration(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)req; if (*len > 1) *len = 1; - (*buf)[0] = _usbd_device.current_config; + (*buf)[0] = usbd_dev->current_config; return 1; } -static int usb_standard_set_interface(struct usb_setup_data *req, +static int usb_standard_set_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { + (void)usbd_dev; (void)req; (void)buf; @@ -214,9 +247,11 @@ static int usb_standard_set_interface(struct usb_setup_data *req, return 1; } -static int usb_standard_get_interface(struct usb_setup_data *req, +static int usb_standard_get_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { + (void)usbd_dev; (void)req; (void)buf; @@ -227,9 +262,11 @@ static int usb_standard_get_interface(struct usb_setup_data *req, return 1; } -static int usb_standard_device_get_status(struct usb_setup_data *req, +static int usb_standard_device_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { + (void)usbd_dev; (void)req; /* bit 0: self powered */ @@ -242,9 +279,11 @@ static int usb_standard_device_get_status(struct usb_setup_data *req, return 1; } -static int usb_standard_interface_get_status(struct usb_setup_data *req, +static int usb_standard_interface_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { + (void)usbd_dev; (void)req; /* not defined */ @@ -256,45 +295,50 @@ static int usb_standard_interface_get_status(struct usb_setup_data *req, return 1; } -static int usb_standard_endpoint_get_status(struct usb_setup_data *req, +static int usb_standard_endpoint_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)req; if (*len > 2) *len = 2; - (*buf)[0] = usbd_ep_stall_get(req->wIndex) ? 1 : 0; + (*buf)[0] = usbd_ep_stall_get(usbd_dev, req->wIndex) ? 1 : 0; (*buf)[1] = 0; return 1; } -static int usb_standard_endpoint_stall(struct usb_setup_data *req, +static int usb_standard_endpoint_stall(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)buf; (void)len; - usbd_ep_stall_set(req->wIndex, 1); + usbd_ep_stall_set(usbd_dev, req->wIndex, 1); return 1; } -static int usb_standard_endpoint_unstall(struct usb_setup_data *req, +static int usb_standard_endpoint_unstall(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)buf; (void)len; - usbd_ep_stall_set(req->wIndex, 0); + usbd_ep_stall_set(usbd_dev, req->wIndex, 0); return 1; } -int _usbd_standard_request_device(struct usb_setup_data *req, u8 **buf, +int _usbd_standard_request_device(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { - int (*command)(struct usb_setup_data *req, u8 **buf, u16 *len) = NULL; + int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req, u8 + **buf, u16 *len) = NULL; switch (req->bRequest) { case USB_REQ_CLEAR_FEATURE: @@ -337,13 +381,15 @@ int _usbd_standard_request_device(struct usb_setup_data *req, u8 **buf, if (!command) return 0; - return command(req, buf, len); + return command(usbd_dev, req, buf, len); } -int _usbd_standard_request_interface(struct usb_setup_data *req, u8 **buf, +int _usbd_standard_request_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { - int (*command)(struct usb_setup_data *req, u8 **buf, u16 *len) = NULL; + int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req, + u8 **buf, u16 *len) = NULL; switch (req->bRequest) { case USB_REQ_CLEAR_FEATURE: @@ -364,13 +410,15 @@ int _usbd_standard_request_interface(struct usb_setup_data *req, u8 **buf, if (!command) return 0; - return command(req, buf, len); + return command(usbd_dev, req, buf, len); } -int _usbd_standard_request_endpoint(struct usb_setup_data *req, u8 **buf, +int _usbd_standard_request_endpoint(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { - int (*command) (struct usb_setup_data *req, u8 **buf, u16 *len) = NULL; + int (*command) (usbd_device *usbd_dev, struct usb_setup_data *req, + u8 **buf, u16 *len) = NULL; switch (req->bRequest) { case USB_REQ_CLEAR_FEATURE: @@ -396,10 +444,11 @@ int _usbd_standard_request_endpoint(struct usb_setup_data *req, u8 **buf, if (!command) return 0; - return command(req, buf, len); + return command(usbd_dev, req, buf, len); } -int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len) +int _usbd_standard_request(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { /* FIXME: Have class/vendor requests as well. */ if ((req->bmRequestType & USB_REQ_TYPE_TYPE) != USB_REQ_TYPE_STANDARD) @@ -407,11 +456,12 @@ int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len) switch (req->bmRequestType & USB_REQ_TYPE_RECIPIENT) { case USB_REQ_TYPE_DEVICE: - return _usbd_standard_request_device(req, buf, len); + return _usbd_standard_request_device(usbd_dev, req, buf, len); case USB_REQ_TYPE_INTERFACE: - return _usbd_standard_request_interface(req, buf, len); + return _usbd_standard_request_interface(usbd_dev, req, + buf, len); case USB_REQ_TYPE_ENDPOINT: - return _usbd_standard_request_endpoint(req, buf, len); + return _usbd_standard_request_endpoint(usbd_dev, req, buf, len); default: return 0; } diff --git a/scripts/irq2nvic_h b/scripts/irq2nvic_h new file mode 100755 index 00000000..d1a8a40f --- /dev/null +++ b/scripts/irq2nvic_h @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +# This file is part of the libopencm3 project. +# +# Copyright (C) 2012 chrysn <chrysn@fsfe.org> +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see <http://www.gnu.org/licenses/>. + +"""Generate an nvic.h header from a small YAML file describing the interrupt +numbers. + +Code generation is chosen here because the resulting C code needs to be very +repetetive (definition of the IRQ numbers, function prototypes, weak fallback +definition and vector table definition), all being very repetitive. No portable +method to achive the same thing with C preprocessor is known to the author. +(Neither is any non-portable method, for that matter.)""" + +import sys +import os +import os.path +import yaml + +template_nvic_h = '''\ +/* This file is part of the libopencm3 project. + * + * It was generated by the irq2nvic_h script. + */ + +#ifndef {includeguard} +#define {includeguard} + +#include <libopencm3/cm3/nvic.h> + +/** @defgroup CM3_nvic_defines_{partname_doxygen} User interrupts for {partname_humanreadable} + @ingroup CM3_nvic_defines + + @{{*/ + +{irqdefinitions} + +#define NVIC_IRQ_COUNT {irqcount} + +/**@}}*/ + +#define WEAK __attribute__ ((weak)) + +/** @defgroup CM3_nvic_isrprototypes_{partname_doxygen} User interrupt service routines (ISR) prototypes for {partname_humanreadable} + @ingroup CM3_nvic_isrprototypes + + @{{*/ + +BEGIN_DECLS + +{isrprototypes} + +END_DECLS + +/**@}}*/ + +#endif /* {includeguard} */ +''' + +template_vector_nvic_c = '''\ +/* This file is part of the libopencm3 project. + * + * It was generated by the irq2nvic_h script. + * + * This part needs to get included in the compilation unit where + * blocking_handler gets defined due to the way #pragma works. + */ + + +/** @defgroup CM3_nvic_isrpragmas_{partname_doxygen} User interrupt service routines (ISR) defaults for {partname_humanreadable} + @ingroup CM3_nvic_isrpragmas + + @{{*/ + +{isrpragmas} + +/**@}}*/ + +/* Initialization template for the interrupt vector table. This definition is + * used by the startup code generator (vector.c) to set the initial values for + * the interrupt handling routines to the chip family specific _isr weak + * symbols. */ + +#define IRQ_HANDLERS \\ + {vectortableinitialization} +''' + +template_cmsis_h = '''\ +/* This file is part of the libopencm3 project. + * + * It was generated by the irq2nvic_h script. + * + * These definitions bend every interrupt handler that is defined CMSIS style + * to the weak symbol exported by libopenmc3. + */ + +{cmsisbends} +''' + +def convert(infile, outfile_nvic, outfile_vectornvic, outfile_cmsis): + data = yaml.load(infile) + + irq2name = list(enumerate(data['irqs']) if isinstance(data['irqs'], list) else data['irqs'].items()) + irqnames = [v for (k,v) in irq2name] + + if isinstance(data['irqs'], list): + data['irqcount'] = len(irq2name) + else: + data['irqcount'] = max(data['irqs'].keys()) + 1 + + data['irqdefinitions'] = "\n".join('#define NVIC_%s_IRQ %d'%(v.upper(),k) for (k,v) in irq2name) + data['isrprototypes'] = "\n".join('void WEAK %s_isr(void);'%name.lower() for name in irqnames) + data['isrpragmas'] = "\n".join('#pragma weak %s_isr = blocking_handler'%name.lower() for name in irqnames) + data['vectortableinitialization'] = ', \\\n '.join('[NVIC_%s_IRQ] = %s_isr'%(name.upper(), name.lower()) for name in irqnames) + data['cmsisbends'] = "\n".join("#define %s_IRQHandler %s_isr"%(name.upper(), name.lower()) for name in irqnames) + + outfile_nvic.write(template_nvic_h.format(**data)) + outfile_vectornvic.write(template_vector_nvic_c.format(**data)) + outfile_cmsis.write(template_cmsis_h.format(**data)) + +def makeparentdir(filename): + try: + os.makedirs(os.path.dirname(filename)) + except OSError: + # where is my 'mkdir -p'? + pass + +def needs_update(infiles, outfiles): + timestamp = lambda filename: os.stat(filename).st_mtime + return any(not os.path.exists(o) for o in outfiles) or max(map(timestamp, infiles)) > min(map(timestamp, outfiles)) + +def main(): + if sys.argv[1] == '--remove': + remove = True + del sys.argv[1] + else: + remove = False + infile = sys.argv[1] + if not infile.startswith('./include/libopencm3/') or not infile.endswith('/irq.yaml'): + raise ValueError("Arguent must match ./include/libopencm3/**/irq.yaml") + nvic_h = infile.replace('irq.yaml', 'nvic.h') + vector_nvic_c = infile.replace('./include/libopencm3/', './lib/').replace('irq.yaml', 'vector_nvic.c') + cmsis = infile.replace('irq.yaml', 'irqhandlers.h').replace('/libopencm3/', '/libopencmsis/') + + if remove: + if os.path.exists(nvic_h): + os.unlink(nvic_h) + if os.path.exists(vector_nvic_c): + os.unlink(vector_nvic_c) + sys.exit(0) + + if not needs_update([__file__, infile], [nvic_h, vector_nvic_c]): + sys.exit(0) + + makeparentdir(nvic_h) + makeparentdir(vector_nvic_c) + makeparentdir(cmsis) + + convert(open(infile), open(nvic_h, 'w'), open(vector_nvic_c, 'w'), open(cmsis, 'w')) + +if __name__ == "__main__": + main() |