From 946c1cbc48f58e56e5f1d3b65d91c7fd2b94140e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 11 Oct 2020 13:02:43 +0000 Subject: [PATCH 001/206] jenkins: try no parallelism clutching at straws to try and eliminate incomprehensible build failures :( --- tests/gadget-zero/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gadget-zero/Jenkinsfile b/tests/gadget-zero/Jenkinsfile index 6e6ff4d4..c7939ab8 100644 --- a/tests/gadget-zero/Jenkinsfile +++ b/tests/gadget-zero/Jenkinsfile @@ -34,7 +34,7 @@ pipeline { steps { sh ''' . .env3/bin/activate - make -j3 V=1 + make V=1 make -C tests/gadget-zero all V=s ''' } From 08c5f2a1fb16b279907eb622ac043046d7a1a35c Mon Sep 17 00:00:00 2001 From: Dima Barsky Date: Fri, 10 Jan 2020 20:45:21 +0000 Subject: [PATCH 002/206] stm32: i2c-v1: Fixed a typo in i2c_read7_v1 and i2c_write7_v1 Replaced & with && Wait for all three bits to be set - SB, MSL, and BUSY. Old code worked by chance, use booleans to correctly convey intent. Reviewed-by: Karl Palsson --- lib/stm32/common/i2c_common_v1.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/stm32/common/i2c_common_v1.c b/lib/stm32/common/i2c_common_v1.c index 85c2f893..c87ef96f 100644 --- a/lib/stm32/common/i2c_common_v1.c +++ b/lib/stm32/common/i2c_common_v1.c @@ -471,9 +471,10 @@ static void i2c_write7_v1(uint32_t i2c, int addr, uint8_t *data, size_t n) i2c_send_start(i2c); - /* Wait for master mode selected */ - while (!((I2C_SR1(i2c) & I2C_SR1_SB) - & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); + /* Wait for the end of the start condition, master mode selected, and BUSY bit set */ + while ( !( (I2C_SR1(i2c) & I2C_SR1_SB) + && (I2C_SR2(i2c) & I2C_SR2_MSL) + && (I2C_SR2(i2c) & I2C_SR2_BUSY) )); i2c_send_7bit_address(i2c, addr, I2C_WRITE); @@ -494,9 +495,10 @@ static void i2c_read7_v1(uint32_t i2c, int addr, uint8_t *res, size_t n) i2c_send_start(i2c); i2c_enable_ack(i2c); - /* Wait for master mode selected */ - while (!((I2C_SR1(i2c) & I2C_SR1_SB) - & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); + /* Wait for the end of the start condition, master mode selected, and BUSY bit set */ + while ( !( (I2C_SR1(i2c) & I2C_SR1_SB) + && (I2C_SR2(i2c) & I2C_SR2_MSL) + && (I2C_SR2(i2c) & I2C_SR2_BUSY) )); i2c_send_7bit_address(i2c, addr, I2C_READ); From 33c0a1d9140275ed38ed08cd713c42bbfa7ee425 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 26 Nov 2020 23:43:58 +0000 Subject: [PATCH 003/206] README: explain versioning goals --- README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b1024b74..d49fa0f3 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,19 @@ code to a microcontroller can be done using the OpenOCD ARM JTAG software. Status and API -------------- -The libopencm3 project is currently work in progress. Not all subsystems -of the microcontrollers are supported, yet. +The libopencm3 project is (and presumably, always will be) a work in progress. +Not all subsystems of all microcontrollers are supported, yet, though some parts +have more complete support than others. -**IMPORTANT**: The API of the library is _NOT_ yet considered stable! Please do - not rely on it, yet! Changes to function names, macro names, etc. - can happen at any time without prior notice! +Prior to version 0.8.0, the api was largely in flux. Attempts were made to provide +backwards compatibility, but this was not always considered critical. + +From 0.8.0 to 1.0, we'll atempt to follow semver, but **EXPECT CHANGES**, as we +attempt to clear up old APIs and remove deprecated functions. The 0.8.0 tag was +placed to provide the "old stable" point before all the new code started landing. + +From 1.0, expect to follow semver, with functions (and defines!) being deprecated for +a release before being removed. _TIP_: Include this repository as a Git submodule in your project to make sure your users get the right version of the library to compile your project. From 9ae81c798ac5cfb9ec4641f6b91b938f8ec88ef5 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 26 Nov 2020 23:45:33 +0000 Subject: [PATCH 004/206] README: description of website --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d49fa0f3..b0a42619 100644 --- a/README.md +++ b/README.md @@ -201,5 +201,5 @@ Mailing lists Website ------- - * http://libopencm3.org + * http://libopencm3.org - contains daily autogenerated API documentation From fd3c950b29c7073cdad86f762198aa5b1c12f5d3 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 11 Oct 2020 22:28:20 +0000 Subject: [PATCH 005/206] tests: gadget0: switch to Linker script generation We're about to drop the very limited set of fixed linker scripts we have, so convert all the in tree code to linker script generation --- tests/gadget-zero/Makefile.efm32hg309-generic | 12 ++++-------- tests/gadget-zero/Makefile.stm32f072disco | 12 ++++-------- tests/gadget-zero/Makefile.stm32f103-generic | 11 ++++------- tests/gadget-zero/Makefile.stm32f3-disco | 12 ++++-------- tests/gadget-zero/Makefile.stm32f429i-disco | 10 +++------- tests/gadget-zero/Makefile.stm32f4disco | 12 ++++-------- tests/gadget-zero/Makefile.stm32l053disco | 12 ++++-------- tests/gadget-zero/Makefile.stm32l1-generic | 11 ++++------- tests/gadget-zero/Makefile.tilm4f120xl | 2 -- 9 files changed, 31 insertions(+), 63 deletions(-) diff --git a/tests/gadget-zero/Makefile.efm32hg309-generic b/tests/gadget-zero/Makefile.efm32hg309-generic index 00eac7d7..27a47743 100644 --- a/tests/gadget-zero/Makefile.efm32hg309-generic +++ b/tests/gadget-zero/Makefile.efm32hg309-generic @@ -32,13 +32,9 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../.. ### This section can go to an arch shared rules eventually... -LDSCRIPT = ../../lib/efm32/hg/efm32hg309f64.ld -OPENCM3_LIB = opencm3_efm32hg -OPENCM3_DEFS = -DEFM32HG -FP_FLAGS ?= -mfloat-abi=soft -ARCH_FLAGS = -mthumb -mcpu=cortex-m0plus $(FP_FLAGS) -#OOCD_INTERFACE = stlink-v2-1 -#OOCD_TARGET = efm32 -OOCD_FILE = openocd.efm32hg309-generic.cfg +DEVICE=efm32hg309f64 +OOCD_FILE = openocd.$(BOARD).cfg +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk diff --git a/tests/gadget-zero/Makefile.stm32f072disco b/tests/gadget-zero/Makefile.stm32f072disco index e155a523..f567805f 100644 --- a/tests/gadget-zero/Makefile.stm32f072disco +++ b/tests/gadget-zero/Makefile.stm32f072disco @@ -32,13 +32,9 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../.. ### This section can go to an arch shared rules eventually... -LDSCRIPT = ../../lib/stm32/f0/stm32f07xzb.ld -OPENCM3_LIB = opencm3_stm32f0 -OPENCM3_DEFS = -DSTM32F0 -#FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ARCH_FLAGS = -mthumb -mcpu=cortex-m0 $(FP_FLAGS) -#OOCD_INTERFACE = stlink-v2 -#OOCD_TARGET = stm32f4x -OOCD_FILE = openocd.stm32f072disco.cfg +DEVICE=stm32f072rb +OOCD_FILE = openocd.$(BOARD).cfg +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk diff --git a/tests/gadget-zero/Makefile.stm32f103-generic b/tests/gadget-zero/Makefile.stm32f103-generic index a27dd607..a413aa9c 100644 --- a/tests/gadget-zero/Makefile.stm32f103-generic +++ b/tests/gadget-zero/Makefile.stm32f103-generic @@ -32,12 +32,9 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../../ ### This section can go to an arch shared rules eventually... -LDSCRIPT = ../../lib/stm32/f1/stm32f103x8.ld -OPENCM3_LIB = opencm3_stm32f1 -OPENCM3_DEFS = -DSTM32F1 -ARCH_FLAGS = -mthumb -mcpu=cortex-m3 -#OOCD_INTERFACE = jlink -#OOCD_TARGET = stm32f1x -OOCD_FILE = openocd.stm32f103-generic.cfg +DEVICE=stm32f103x8 +OOCD_FILE = openocd.$(BOARD).cfg +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk diff --git a/tests/gadget-zero/Makefile.stm32f3-disco b/tests/gadget-zero/Makefile.stm32f3-disco index 3a60392e..5e419832 100644 --- a/tests/gadget-zero/Makefile.stm32f3-disco +++ b/tests/gadget-zero/Makefile.stm32f3-disco @@ -32,13 +32,9 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../.. ### This section can go to an arch shared rules eventually... -LDSCRIPT = ../../lib/stm32/f3/stm32f303xc.ld -OPENCM3_LIB = opencm3_stm32f3 -OPENCM3_DEFS = -DSTM32F3 -FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) -#OOCD_INTERFACE = stlink-v2 -#OOCD_TARGET = stm32f3x -OOCD_FILE = openocd.stm32f3-disco.cfg +DEVICE=stm32f303xc +OOCD_FILE = openocd.$(BOARD).cfg +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk diff --git a/tests/gadget-zero/Makefile.stm32f429i-disco b/tests/gadget-zero/Makefile.stm32f429i-disco index d1c432fd..f13c4f66 100644 --- a/tests/gadget-zero/Makefile.stm32f429i-disco +++ b/tests/gadget-zero/Makefile.stm32f429i-disco @@ -32,13 +32,9 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../.. ### This section can go to an arch shared rules eventually... -LDSCRIPT = ../../lib/stm32/f4/stm32f405x6.ld -OPENCM3_LIB = opencm3_stm32f4 -OPENCM3_DEFS = -DSTM32F4 -FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) -#OOCD_INTERFACE = stlink-v2 -#OOCD_TARGET = stm32f4x +DEVICE=stm32f405re OOCD_FILE = openocd.$(BOARD).cfg +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk diff --git a/tests/gadget-zero/Makefile.stm32f4disco b/tests/gadget-zero/Makefile.stm32f4disco index ca737cb3..20cffcec 100644 --- a/tests/gadget-zero/Makefile.stm32f4disco +++ b/tests/gadget-zero/Makefile.stm32f4disco @@ -32,13 +32,9 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../.. ### This section can go to an arch shared rules eventually... -LDSCRIPT = ../../lib/stm32/f4/stm32f405x6.ld -OPENCM3_LIB = opencm3_stm32f4 -OPENCM3_DEFS = -DSTM32F4 -FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) -#OOCD_INTERFACE = stlink-v2 -#OOCD_TARGET = stm32f4x -OOCD_FILE = openocd.stm32f4disco.cfg +DEVICE=stm32f405re +OOCD_FILE = openocd.$(BOARD).cfg +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk diff --git a/tests/gadget-zero/Makefile.stm32l053disco b/tests/gadget-zero/Makefile.stm32l053disco index 9c79127d..6d7f028c 100644 --- a/tests/gadget-zero/Makefile.stm32l053disco +++ b/tests/gadget-zero/Makefile.stm32l053disco @@ -32,13 +32,9 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../.. ### This section can go to an arch shared rules eventually... -LDSCRIPT = ../../lib/stm32/l0/stm32l0xx8.ld -OPENCM3_LIB = opencm3_stm32l0 -OPENCM3_DEFS = -DSTM32L0 -#FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ARCH_FLAGS = -mthumb -mcpu=cortex-m0plus $(FP_FLAGS) -#OOCD_INTERFACE = stlink-v2-1 -#OOCD_TARGET = stm32l0 -OOCD_FILE = openocd.stm32l053disco.cfg +DEVICE=stm32l053x8 +OOCD_FILE = openocd.$(BOARD).cfg +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk diff --git a/tests/gadget-zero/Makefile.stm32l1-generic b/tests/gadget-zero/Makefile.stm32l1-generic index 9a410de4..6318896f 100644 --- a/tests/gadget-zero/Makefile.stm32l1-generic +++ b/tests/gadget-zero/Makefile.stm32l1-generic @@ -32,12 +32,9 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../.. ### This section can go to an arch shared rules eventually... -LDSCRIPT = ../../lib/stm32/l1/stm32l15xx8.ld -OPENCM3_LIB = opencm3_stm32l1 -OPENCM3_DEFS = -DSTM32L1 -ARCH_FLAGS = -mthumb -mcpu=cortex-m3 -#OOCD_INTERFACE = jlink -#OOCD_TARGET = stm32l1x -OOCD_FILE = openocd.stm32l1-generic.cfg +DEVICE=stm32l151c8 +OOCD_FILE = openocd.$(BOARD).cfg +include $(OPENCM3_DIR)/mk/genlink-config.mk +include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk diff --git a/tests/gadget-zero/Makefile.tilm4f120xl b/tests/gadget-zero/Makefile.tilm4f120xl index d458b338..c8a36ff9 100644 --- a/tests/gadget-zero/Makefile.tilm4f120xl +++ b/tests/gadget-zero/Makefile.tilm4f120xl @@ -36,7 +36,5 @@ DEVICE=lm4f120xl OOCD_FILE = openocd.$(BOARD).cfg include $(OPENCM3_DIR)/mk/genlink-config.mk -#include $(OPENCM3_DIR)/mk/gcc-config.mk include $(OPENCM3_DIR)/mk/genlink-rules.mk include ../rules.mk -#include $(OPENCM3_DIR)/mk/gcc-rules.mk From e15071dbf8ac4bf651602f19eb2916fe3c3fd48d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 7 Oct 2020 22:12:03 +0000 Subject: [PATCH 006/206] BREAKING: drop all part specific ld files We were never going to be capable of supporting every single part variant with their own files, so stop trying. We've been supporting the linker script generator for a long time now, so move on from these old static files. Breaking: if you were using one of these, and don't wish to use the linker script generator, you should simply declare a stub linker script, and include the generic section definitions file, and provide this in your own application. Old: LDSCRIPT = $(OPENCM3_DIR)/lib/stm32/l1/stm32l15xxb.ld New (linker script generator): DEVICE=stm32l151cb New (manual): * Add file mymemorymap.ld, with contents similar too: ``` MEMORY { rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K } /* Include the common ld script. */ INCLUDE cortex-m-generic.ld ``` LDSCRIPT=mymemorymap.ld See ld/README for more information on using the linker script generator --- lib/efm32/ezr32wg/libopencm3_ezr32wg.ld | 106 ------------- lib/efm32/g/libopencm3_efm32g880f128.ld | 15 -- lib/efm32/gg/libopencm3_efm32gg990f1024.ld | 15 -- lib/efm32/hg/efm32hg309f64.ld | 28 ---- lib/efm32/tg/libopencm3_efm32tg840f32.ld | 15 -- lib/efm32/wg/libopencm3_efm32wg.ld | 106 ------------- lib/lm3s/lm3s6965.ld | 31 ---- lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld | 0 .../m0/libopencm3_lpc43xx_ram_only_m0.ld | 96 ------------ lib/lpc43xx/m4/libopencm3_lpc43xx.ld | 127 ---------------- lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld | 139 ------------------ .../m4/libopencm3_lpc43xx_rom_to_ram.ld | 128 ---------------- lib/sam/4l/libopencm3_sam4l.ld | 105 ------------- lib/stm32/f0/stm32f03xz6.ld | 31 ---- lib/stm32/f0/stm32f04xz6.ld | 31 ---- lib/stm32/f0/stm32f05xz6.ld | 31 ---- lib/stm32/f0/stm32f05xz8.ld | 31 ---- lib/stm32/f0/stm32f07xz8.ld | 31 ---- lib/stm32/f0/stm32f07xzb.ld | 31 ---- lib/stm32/f1/stm32f100x4.ld | 31 ---- lib/stm32/f1/stm32f100x6.ld | 31 ---- lib/stm32/f1/stm32f100x8.ld | 31 ---- lib/stm32/f1/stm32f100xb.ld | 31 ---- lib/stm32/f1/stm32f100xc.ld | 31 ---- lib/stm32/f1/stm32f100xd.ld | 31 ---- lib/stm32/f1/stm32f100xe.ld | 31 ---- lib/stm32/f1/stm32f103x8.ld | 31 ---- lib/stm32/f1/stm32f103xb.ld | 31 ---- lib/stm32/f1/stm32f103xc.ld | 31 ---- lib/stm32/f1/stm32f103xd.ld | 31 ---- lib/stm32/f1/stm32f103xe.ld | 31 ---- lib/stm32/f3/stm32f303xc.ld | 31 ---- lib/stm32/f4/stm32f405x6.ld | 34 ----- lib/stm32/l0/stm32l0xx6.ld | 32 ---- lib/stm32/l0/stm32l0xx8.ld | 32 ---- lib/stm32/l1/stm32l100xc.ld | 33 ----- lib/stm32/l1/stm32l15xx6.ld | 32 ---- lib/stm32/l1/stm32l15xx8.ld | 32 ---- lib/stm32/l1/stm32l15xxb.ld | 32 ---- lib/stm32/l1/stm32l15xxc.ld | 32 ---- lib/stm32/l1/stm32l15xxd.ld | 32 ---- 41 files changed, 1791 deletions(-) delete mode 100644 lib/efm32/ezr32wg/libopencm3_ezr32wg.ld delete mode 100644 lib/efm32/g/libopencm3_efm32g880f128.ld delete mode 100644 lib/efm32/gg/libopencm3_efm32gg990f1024.ld delete mode 100644 lib/efm32/hg/efm32hg309f64.ld delete mode 100644 lib/efm32/tg/libopencm3_efm32tg840f32.ld delete mode 100644 lib/efm32/wg/libopencm3_efm32wg.ld delete mode 100644 lib/lm3s/lm3s6965.ld delete mode 100644 lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld delete mode 100644 lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld delete mode 100644 lib/lpc43xx/m4/libopencm3_lpc43xx.ld delete mode 100644 lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld delete mode 100644 lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld delete mode 100644 lib/sam/4l/libopencm3_sam4l.ld delete mode 100644 lib/stm32/f0/stm32f03xz6.ld delete mode 100644 lib/stm32/f0/stm32f04xz6.ld delete mode 100644 lib/stm32/f0/stm32f05xz6.ld delete mode 100644 lib/stm32/f0/stm32f05xz8.ld delete mode 100644 lib/stm32/f0/stm32f07xz8.ld delete mode 100644 lib/stm32/f0/stm32f07xzb.ld delete mode 100644 lib/stm32/f1/stm32f100x4.ld delete mode 100644 lib/stm32/f1/stm32f100x6.ld delete mode 100644 lib/stm32/f1/stm32f100x8.ld delete mode 100644 lib/stm32/f1/stm32f100xb.ld delete mode 100644 lib/stm32/f1/stm32f100xc.ld delete mode 100644 lib/stm32/f1/stm32f100xd.ld delete mode 100644 lib/stm32/f1/stm32f100xe.ld delete mode 100644 lib/stm32/f1/stm32f103x8.ld delete mode 100644 lib/stm32/f1/stm32f103xb.ld delete mode 100644 lib/stm32/f1/stm32f103xc.ld delete mode 100644 lib/stm32/f1/stm32f103xd.ld delete mode 100644 lib/stm32/f1/stm32f103xe.ld delete mode 100644 lib/stm32/f3/stm32f303xc.ld delete mode 100644 lib/stm32/f4/stm32f405x6.ld delete mode 100644 lib/stm32/l0/stm32l0xx6.ld delete mode 100644 lib/stm32/l0/stm32l0xx8.ld delete mode 100644 lib/stm32/l1/stm32l100xc.ld delete mode 100644 lib/stm32/l1/stm32l15xx6.ld delete mode 100644 lib/stm32/l1/stm32l15xx8.ld delete mode 100644 lib/stm32/l1/stm32l15xxb.ld delete mode 100644 lib/stm32/l1/stm32l15xxc.ld delete mode 100644 lib/stm32/l1/stm32l15xxd.ld diff --git a/lib/efm32/ezr32wg/libopencm3_ezr32wg.ld b/lib/efm32/ezr32wg/libopencm3_ezr32wg.ld deleted file mode 100644 index 87d6ee63..00000000 --- a/lib/efm32/ezr32wg/libopencm3_ezr32wg.ld +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* 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 -{ - .text : { - *(.vectors) /* Vector table */ - *(.text*) /* Program code */ - . = ALIGN(4); - *(.rodata*) /* Read-only data */ - . = ALIGN(4); - } >rom - - /* C++ Static constructors/destructors, also used for __attribute__ - * ((constructor)) and the likes */ - .preinit_array : { - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - } >rom - .init_array : { - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - } >rom - .fini_array : { - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - } >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/efm32/g/libopencm3_efm32g880f128.ld b/lib/efm32/g/libopencm3_efm32g880f128.ld deleted file mode 100644 index dac6aa38..00000000 --- a/lib/efm32/g/libopencm3_efm32g880f128.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* 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 cortex-m-generic.ld; diff --git a/lib/efm32/gg/libopencm3_efm32gg990f1024.ld b/lib/efm32/gg/libopencm3_efm32gg990f1024.ld deleted file mode 100644 index e1dcc103..00000000 --- a/lib/efm32/gg/libopencm3_efm32gg990f1024.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* lengths from d046_efm32gg990_datasheet.pdf table 1.1, offset from - * d0034_efm32tg_reference_manual.pdf figure 5.2. - * - * the origins and memory structure are constant over all giantgeckos, 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 = 1024k - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128k -} - -INCLUDE cortex-m-generic.ld; diff --git a/lib/efm32/hg/efm32hg309f64.ld b/lib/efm32/hg/efm32hg309f64.ld deleted file mode 100644 index e9bc1d6c..00000000 --- a/lib/efm32/hg/efm32hg309f64.ld +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for EFM32HG309F64, 64K flash, 8K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 64K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld diff --git a/lib/efm32/tg/libopencm3_efm32tg840f32.ld b/lib/efm32/tg/libopencm3_efm32tg840f32.ld deleted file mode 100644 index 2a133ddc..00000000 --- a/lib/efm32/tg/libopencm3_efm32tg840f32.ld +++ /dev/null @@ -1,15 +0,0 @@ -/* 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 cortex-m-generic.ld; diff --git a/lib/efm32/wg/libopencm3_efm32wg.ld b/lib/efm32/wg/libopencm3_efm32wg.ld deleted file mode 100644 index 87d6ee63..00000000 --- a/lib/efm32/wg/libopencm3_efm32wg.ld +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* 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 -{ - .text : { - *(.vectors) /* Vector table */ - *(.text*) /* Program code */ - . = ALIGN(4); - *(.rodata*) /* Read-only data */ - . = ALIGN(4); - } >rom - - /* C++ Static constructors/destructors, also used for __attribute__ - * ((constructor)) and the likes */ - .preinit_array : { - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - } >rom - .init_array : { - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - } >rom - .fini_array : { - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - } >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/lm3s/lm3s6965.ld b/lib/lm3s/lm3s6965.ld deleted file mode 100644 index c0fc3b2b..00000000 --- a/lib/lm3s/lm3s6965.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2016 Daniele Lacamera - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for the LM3S6965 chip (256K flash, 64K RAM). */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 256K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld b/lib/lpc43xx/m0/libopencm3_lpc43xx_m0.ld deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld b/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld deleted file mode 100644 index fedd3e1d..00000000 --- a/lib/lpc43xx/m0/libopencm3_lpc43xx_ram_only_m0.ld +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2012 Michael Ossmann - * Copyright (C) 2012 Benjamin Vernoux - * Copyright (C) 2012 Jared Boone - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Generic linker script for LPC43XX targets using libopencm3. */ - -/* Memory regions must be defined in the ld script which includes this one. */ - -/* Enforce emmition of the vector table. */ -EXTERN (vector_table) - -/* Define the entry point of the output file. */ -ENTRY(reset_handler) - -/* Define sections. */ -SECTIONS -{ - . = ORIGIN(ram_ahb2); - - .text : { - . = ALIGN(0x400); - *(.vectors) /* Vector table */ - *(.text*) /* Program code */ - . = ALIGN(4); - *(.rodata*) /* Read-only data */ - . = ALIGN(4); - } >ram_ahb2 - - /* exception index - required due to libgcc.a issuing /0 exceptions */ - __exidx_start = .; - .ARM.exidx : { - *(.ARM.exidx*) - } > ram_ahb2 - __exidx_end = .; - - _etext = .; - - . = ORIGIN(ram_ahb2); - - .data : { - *(.data*) /* Read-write initialized data */ - . = ALIGN(4); - } >ram_ahb2 - - _data = .; - _edata = .; - - .bss : { - _bss = .; - *(.bss*) /* Read-write zero initialized data */ - *(COMMON) - . = ALIGN(4); - _ebss = .; - } >ram_ahb2 - - /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ - .ARM.extab : { - *(.ARM.extab*) - } >ram_ahb2 - - /* - * 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) } - - end = .; - - /* Leave room above stack for IAP to run. */ - __StackTop = ORIGIN(ram_ahb2) + LENGTH(ram_ahb2) - 32; - PROVIDE(_stack = __StackTop); -} diff --git a/lib/lpc43xx/m4/libopencm3_lpc43xx.ld b/lib/lpc43xx/m4/libopencm3_lpc43xx.ld deleted file mode 100644 index c289b351..00000000 --- a/lib/lpc43xx/m4/libopencm3_lpc43xx.ld +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2012 Michael Ossmann - * Copyright (C) 2012 Benjamin Vernoux - * Copyright (C) 2012 Jared Boone - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Generic linker script for LPC43XX targets using libopencm3. */ - -/* Memory regions must be defined in the ld script which includes this one. */ - -/* Enforce emmition of the vector table. */ -EXTERN (vector_table) - -/* Define the entry point of the output file. */ -ENTRY(reset_handler) - -/* Define sections. */ -SECTIONS -{ - .text : { - . = ALIGN(0x400); - _text_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ - *(.vectors) /* Vector table */ - *(.text*) /* Program code */ - . = ALIGN(4); - *(.rodata*) /* Read-only data */ - . = ALIGN(4); - } >rom - - /* C++ Static constructors/destructors, also used for __attribute__ - * ((constructor)) and the likes */ - .preinit_array : { - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - } >rom - .init_array : { - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - } >rom - .fini_array : { - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - } >rom - - /* - * Another section used by C++ stuff, appears when using newlib with - * 64bit (long long) printf support - */ - .ARM.extab : { - *(.ARM.extab*) - } >rom - - /* exception index - required due to libgcc.a issuing /0 exceptions */ - .ARM.exidx : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >rom - - . = ALIGN(4); - _etext = .; - _etext_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ - _etext_rom = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ - - . = ORIGIN(ram_local2); - - .data : { - _data = .; - *(.data*) /* Read-write initialized data */ - . = ALIGN(4); - _edata = .; - } >ram_local2 AT >rom - _data_loadaddr = LOADADDR(.data); - - _data_rom = LOADADDR (.data) + ORIGIN(rom); - _edata_rom = _data_rom + SIZEOF (.data); - - .bss : { - _bss = .; - *(.bss*) /* Read-write zero initialized data */ - *(COMMON) - . = ALIGN(4); - _ebss = .; - } >ram_local2 - - /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ - .ARM.extab : { - *(.ARM.extab*) - } >ram_local2 - - /* - * The .eh_frame section appears to be used for C++ exception handling. - * You may need to fix this if you're using C++. - */ - /DISCARD/ : { *(.eh_frame) } - - . = ALIGN(4); - end = .; - - /* Leave room above stack for IAP to run. */ - __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32; - PROVIDE(_stack = __StackTop); -} diff --git a/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld b/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld deleted file mode 100644 index 5bcdea61..00000000 --- a/lib/lpc43xx/m4/libopencm3_lpc43xx_ram_only.ld +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2012 Michael Ossmann - * Copyright (C) 2012 Benjamin Vernoux - * Copyright (C) 2012 Jared Boone - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Generic linker script for LPC43XX targets using libopencm3. */ - -/* Memory regions must be defined in the ld script which includes this one. */ - -/* Enforce emmition of the vector table. */ -EXTERN (vector_table) - -/* Define the entry point of the output file. */ -ENTRY(reset_handler) - -/* Define sections. */ -SECTIONS -{ - . = ORIGIN(ram_local1); - - .text : { - . = ALIGN(0x400); - _text_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ - *(.vectors) /* Vector table */ - *(.text*) /* Program code */ - . = ALIGN(4); - *(.rodata*) /* Read-only data */ - . = ALIGN(4); - } >ram_local1 - - /* C++ Static constructors/destructors, also used for __attribute__ - * ((constructor)) and the likes */ - .preinit_array : { - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - } >ram_local1 - .init_array : { - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - } >ram_local1 - .fini_array : { - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - } >ram_local1 - - /* - * Another section used by C++ stuff, appears when using newlib with - * 64bit (long long) printf support - */ - .ARM.extab : { - *(.ARM.extab*) - } >ram_local1 - - /* exception index - required due to libgcc.a issuing /0 exceptions */ - __exidx_start = .; - .ARM.exidx : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } > ram_local1 - - . = ALIGN(4); - _etext = .; - _etext_ram = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ - _etext_rom = 0; /* Start of Code in RAM NULL because Copy of Code from ROM to RAM disabled */ - - . = ORIGIN(ram_local2); - - .data : { - _data = .; - *(.data*) /* Read-write initialized data */ - . = ALIGN(4); - _edata = .; - } >ram_local2 - _data_loadaddr = LOADADDR(.data); - - /* Running from RAM only, loading the .elf will initialize data for us. */ - _data_rom = .; - _edata_rom = .; - - _data = .; - _edata = .; - - .bss : { - _bss = .; - *(.bss*) /* Read-write zero initialized data */ - *(COMMON) - . = ALIGN(4); - _ebss = .; - } >ram_local2 - - /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ - .ARM.extab : { - *(.ARM.extab*) - } >ram_local2 - - /* - * 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) } - - end = .; - - /* Leave room above stack for IAP to run. */ - __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32; - PROVIDE(_stack = __StackTop); -} diff --git a/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld b/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld deleted file mode 100644 index e50040eb..00000000 --- a/lib/lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2012 Michael Ossmann - * Copyright (C) 2012 Benjamin Vernoux - * Copyright (C) 2012 Jared Boone - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Generic linker script for LPC43XX targets using libopencm3. */ - -/* Memory regions must be defined in the ld script which includes this one. */ - -/* Enforce emmition of the vector table. */ -EXTERN (vector_table) - -/* Define the entry point of the output file. */ -ENTRY(reset_handler) - -/* Define sections. */ -SECTIONS -{ - .text : { - . = ALIGN(0x400); - _text_ram = (. - ORIGIN(rom)) + ORIGIN(ram_local1); /* Start of Code in RAM */ - - *(.vectors) /* Vector table */ - *(.text*) /* Program code */ - . = ALIGN(4); - *(.rodata*) /* Read-only data */ - . = ALIGN(4); - } >rom - - /* C++ Static constructors/destructors, also used for __attribute__ - * ((constructor)) and the likes */ - .preinit_array : { - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - } >rom - .init_array : { - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - } >rom - .fini_array : { - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - } >rom - - /* - * Another section used by C++ stuff, appears when using newlib with - * 64bit (long long) printf support - */ - .ARM.extab : { - *(.ARM.extab*) - } >rom - - /* exception index - required due to libgcc.a issuing /0 exceptions */ - .ARM.exidx : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >rom - - . = ALIGN(4); - _etext = .; - _etext_ram = (. - ORIGIN(rom)) + ORIGIN(ram_local1); - _etext_rom = (. - ORIGIN(rom)) + ORIGIN(rom_flash); - - . = ORIGIN(ram_local2); - - .data : { - _data = .; - *(.data*) /* Read-write initialized data */ - . = ALIGN(4); - _edata = .; - } >ram_local2 AT >rom - _data_loadaddr = LOADADDR(.data); - - _data_rom = LOADADDR (.data) + ORIGIN(rom_flash); - _edata_rom = _data_rom + SIZEOF (.data); - - .bss : { - _bss = .; - *(.bss*) /* Read-write zero initialized data */ - *(COMMON) - . = ALIGN(4); - _ebss = .; - } >ram_local2 - - /* exception unwind data - required due to libgcc.a issuing /0 exceptions */ - .ARM.extab : { - *(.ARM.extab*) - } >ram_local2 - - /* - * The .eh_frame section appears to be used for C++ exception handling. - * You may need to fix this if you're using C++. - */ - /DISCARD/ : { *(.eh_frame) } - - . = ALIGN(4); - end = .; - - /* Leave room above stack for IAP to run. */ - __StackTop = ORIGIN(ram_local2) + LENGTH(ram_local2) - 32; - PROVIDE(_stack = __StackTop); -} diff --git a/lib/sam/4l/libopencm3_sam4l.ld b/lib/sam/4l/libopencm3_sam4l.ld deleted file mode 100644 index 5dea121b..00000000 --- a/lib/sam/4l/libopencm3_sam4l.ld +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Generic linker script for SAM4L 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 - - /* C++ Static constructors/destructors, also used for __attribute__ - * ((constructor)) and the likes */ - .preinit_array : { - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - } >rom - .init_array : { - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - } >rom - .fini_array : { - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - } >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/f0/stm32f03xz6.ld b/lib/stm32/f0/stm32f03xz6.ld deleted file mode 100644 index f564dbfd..00000000 --- a/lib/stm32/f0/stm32f03xz6.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F03xz6, 32k flash, 4k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f0/stm32f04xz6.ld b/lib/stm32/f0/stm32f04xz6.ld deleted file mode 100644 index 164d0e84..00000000 --- a/lib/stm32/f0/stm32f04xz6.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F04xz6, 32k flash, 6k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f0/stm32f05xz6.ld b/lib/stm32/f0/stm32f05xz6.ld deleted file mode 100644 index b8bd7b9b..00000000 --- a/lib/stm32/f0/stm32f05xz6.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F05xz6, 32k flash, 8k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f0/stm32f05xz8.ld b/lib/stm32/f0/stm32f05xz8.ld deleted file mode 100644 index dd0ce931..00000000 --- a/lib/stm32/f0/stm32f05xz8.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F05xz8, 64k flash, 8k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f0/stm32f07xz8.ld b/lib/stm32/f0/stm32f07xz8.ld deleted file mode 100644 index af45ae78..00000000 --- a/lib/stm32/f0/stm32f07xz8.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F07xz8, 64k flash, 16k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f0/stm32f07xzb.ld b/lib/stm32/f0/stm32f07xzb.ld deleted file mode 100644 index b55510ec..00000000 --- a/lib/stm32/f0/stm32f07xzb.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F07xzB, 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 cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f100x4.ld b/lib/stm32/f1/stm32f100x4.ld deleted file mode 100644 index 4b1af96e..00000000 --- a/lib/stm32/f1/stm32f100x4.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f100x6.ld b/lib/stm32/f1/stm32f100x6.ld deleted file mode 100644 index 6abe9034..00000000 --- a/lib/stm32/f1/stm32f100x6.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F100x6, 32K flash, 4K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f100x8.ld b/lib/stm32/f1/stm32f100x8.ld deleted file mode 100644 index 9a037f09..00000000 --- a/lib/stm32/f1/stm32f100x8.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F100x8, 64K flash, 8K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f100xb.ld b/lib/stm32/f1/stm32f100xb.ld deleted file mode 100644 index 0874999e..00000000 --- a/lib/stm32/f1/stm32f100xb.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F100xB, 128K flash, 8K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f100xc.ld b/lib/stm32/f1/stm32f100xc.ld deleted file mode 100644 index b6c38c05..00000000 --- a/lib/stm32/f1/stm32f100xc.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F100xC, 256K flash, 24K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 24K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f100xd.ld b/lib/stm32/f1/stm32f100xd.ld deleted file mode 100644 index 2dbd7bdb..00000000 --- a/lib/stm32/f1/stm32f100xd.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F100xD, 384K flash, 32K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f100xe.ld b/lib/stm32/f1/stm32f100xe.ld deleted file mode 100644 index c181c447..00000000 --- a/lib/stm32/f1/stm32f100xe.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F100xE, 512K flash, 32K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f103x8.ld b/lib/stm32/f1/stm32f103x8.ld deleted file mode 100644 index 3ae984d8..00000000 --- a/lib/stm32/f1/stm32f103x8.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F103x8, 64k flash, 20k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f103xb.ld b/lib/stm32/f1/stm32f103xb.ld deleted file mode 100644 index 4ec8235d..00000000 --- a/lib/stm32/f1/stm32f103xb.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F103xB, 128k flash, 20k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f103xc.ld b/lib/stm32/f1/stm32f103xc.ld deleted file mode 100644 index de30d14c..00000000 --- a/lib/stm32/f1/stm32f103xc.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F103xC, 256K flash, 48k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f103xd.ld b/lib/stm32/f1/stm32f103xd.ld deleted file mode 100644 index cfc6ee41..00000000 --- a/lib/stm32/f1/stm32f103xd.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F103xD, 384K flash, 64k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f1/stm32f103xe.ld b/lib/stm32/f1/stm32f103xe.ld deleted file mode 100644 index 78f68797..00000000 --- a/lib/stm32/f1/stm32f103xe.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32F103xE, 512K flash, 64k RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f3/stm32f303xc.ld b/lib/stm32/f3/stm32f303xc.ld deleted file mode 100644 index c1e1137a..00000000 --- a/lib/stm32/f3/stm32f303xc.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2015 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for the STM32F303xC chip. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 40K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/f4/stm32f405x6.ld b/lib/stm32/f4/stm32f405x6.ld deleted file mode 100644 index 4c43a279..00000000 --- a/lib/stm32/f4/stm32f405x6.ld +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2011 Stephen Caudle - * Copyright (C) 2013 Sergey Krukowski - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for the STM32F40xxG chip (1024K flash, 128K RAM). */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K - ccm (rwx) : ORIGIN = 0x10000000, LENGTH = 64K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/l0/stm32l0xx6.ld b/lib/stm32/l0/stm32l0xx6.ld deleted file mode 100644 index 17307b77..00000000 --- a/lib/stm32/l0/stm32l0xx6.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32L0xx6, 32K flash, 8K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K - eep (r) : ORIGIN = 0x08080000, LENGTH = 2K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/l0/stm32l0xx8.ld b/lib/stm32/l0/stm32l0xx8.ld deleted file mode 100644 index 13d43e10..00000000 --- a/lib/stm32/l0/stm32l0xx8.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32L0xx8, 64K flash, 8K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K - eep (r) : ORIGIN = 0x08080000, LENGTH = 2K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/l1/stm32l100xc.ld b/lib/stm32/l1/stm32l100xc.ld deleted file mode 100644 index 28f03667..00000000 --- a/lib/stm32/l1/stm32l100xc.ld +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2013 Karl Palsson - * Copyright (C) 2015 Joost Rijneveld - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32L100xC, 256K flash, 16K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K - eep (r) : ORIGIN = 0x08080000, LENGTH = 4K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/l1/stm32l15xx6.ld b/lib/stm32/l1/stm32l15xx6.ld deleted file mode 100644 index fa22b492..00000000 --- a/lib/stm32/l1/stm32l15xx6.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2013 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32L15xx6, 32K flash, 10K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K - eep (r) : ORIGIN = 0x08080000, LENGTH = 4K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/l1/stm32l15xx8.ld b/lib/stm32/l1/stm32l15xx8.ld deleted file mode 100644 index dc62f7a3..00000000 --- a/lib/stm32/l1/stm32l15xx8.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32L15xx8, 64K flash, 10K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K - eep (r) : ORIGIN = 0x08080000, LENGTH = 4K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/l1/stm32l15xxb.ld b/lib/stm32/l1/stm32l15xxb.ld deleted file mode 100644 index 694da9ec..00000000 --- a/lib/stm32/l1/stm32l15xxb.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32L15xxB, 128K flash, 16K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K - eep (r) : ORIGIN = 0x08080000, LENGTH = 4K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/l1/stm32l15xxc.ld b/lib/stm32/l1/stm32l15xxc.ld deleted file mode 100644 index e0569a29..00000000 --- a/lib/stm32/l1/stm32l15xxc.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2013 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32L15xxC, 256k flash, 32K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K - eep (r) : ORIGIN = 0x08080000, LENGTH = 8K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - diff --git a/lib/stm32/l1/stm32l15xxd.ld b/lib/stm32/l1/stm32l15xxd.ld deleted file mode 100644 index 8020841b..00000000 --- a/lib/stm32/l1/stm32l15xxd.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2013 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for STM32L15xxD, 384K flash, 38K RAM. */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K - eep (r) : ORIGIN = 0x08080000, LENGTH = 12K -} - -/* Include the common ld script. */ -INCLUDE cortex-m-generic.ld - From 636918732db9826f95669de3ea2e87775fd74102 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 11 Oct 2020 22:35:55 +0000 Subject: [PATCH 007/206] stm32: i2c: drop useless integer defines I2C_CR2_FREQ_ These defines were simply a word containing the number, instead of the number itself. This provides no value, and implies that there's a limited set of values. The list was _already_ incomplete, so misleading, _and_ just noise to maintain. Burn it all. (well, burn it just a little bit, provide deprecated aliases on the old values so that code keeps compiling) --- .../libopencm3/stm32/common/i2c_common_v1.h | 91 +++++++++---------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/include/libopencm3/stm32/common/i2c_common_v1.h b/include/libopencm3/stm32/common/i2c_common_v1.h index 16c8982a..9892abf8 100644 --- a/include/libopencm3/stm32/common/i2c_common_v1.h +++ b/include/libopencm3/stm32/common/i2c_common_v1.h @@ -181,55 +181,50 @@ specific memorymap.h header before including this header file.*/ /* Note: Bits [7:6] are reserved, and forced to 0 by hardware. */ -/* FREQ[5:0]: Peripheral clock frequency (valid values: 2-36 MHz, 2-42 MHz for - * STM32F4 respectively) */ -/****************************************************************************/ -/** @defgroup i2c_clock I2C clock frequency settings -@ingroup i2c_defines +enum i2c_cr2_freq_values { + I2C_CR2_FREQ_2MHZ __attribute__ ((deprecated("Replace with 2 directly"))) = 2, + I2C_CR2_FREQ_3MHZ __attribute__ ((deprecated("Replace with 3 directly"))), + I2C_CR2_FREQ_4MHZ __attribute__ ((deprecated("Replace with 4 directly"))), + I2C_CR2_FREQ_5MHZ __attribute__ ((deprecated("Replace with 5 directly"))), + I2C_CR2_FREQ_6MHZ __attribute__ ((deprecated("Replace with 6 directly"))), + I2C_CR2_FREQ_7MHZ __attribute__ ((deprecated("Replace with 7 directly"))), + I2C_CR2_FREQ_8MHZ __attribute__ ((deprecated("Replace with 8 directly"))), + I2C_CR2_FREQ_9MHZ __attribute__ ((deprecated("Replace with 9 directly"))), + I2C_CR2_FREQ_10MHZ __attribute__ ((deprecated("Replace with 10 directly"))), + I2C_CR2_FREQ_11MHZ __attribute__ ((deprecated("Replace with 11 directly"))), + I2C_CR2_FREQ_12MHZ __attribute__ ((deprecated("Replace with 12 directly"))), + I2C_CR2_FREQ_13MHZ __attribute__ ((deprecated("Replace with 13 directly"))), + I2C_CR2_FREQ_14MHZ __attribute__ ((deprecated("Replace with 14 directly"))), + I2C_CR2_FREQ_15MHZ __attribute__ ((deprecated("Replace with 15 directly"))), + I2C_CR2_FREQ_16MHZ __attribute__ ((deprecated("Replace with 16 directly"))), + I2C_CR2_FREQ_17MHZ __attribute__ ((deprecated("Replace with 17 directly"))), + I2C_CR2_FREQ_18MHZ __attribute__ ((deprecated("Replace with 18 directly"))), + I2C_CR2_FREQ_19MHZ __attribute__ ((deprecated("Replace with 19 directly"))), + I2C_CR2_FREQ_20MHZ __attribute__ ((deprecated("Replace with 20 directly"))), + I2C_CR2_FREQ_21MHZ __attribute__ ((deprecated("Replace with 21 directly"))), + I2C_CR2_FREQ_22MHZ __attribute__ ((deprecated("Replace with 22 directly"))), + I2C_CR2_FREQ_23MHZ __attribute__ ((deprecated("Replace with 23 directly"))), + I2C_CR2_FREQ_24MHZ __attribute__ ((deprecated("Replace with 24 directly"))), + I2C_CR2_FREQ_25MHZ __attribute__ ((deprecated("Replace with 25 directly"))), + I2C_CR2_FREQ_26MHZ __attribute__ ((deprecated("Replace with 26 directly"))), + I2C_CR2_FREQ_27MHZ __attribute__ ((deprecated("Replace with 27 directly"))), + I2C_CR2_FREQ_28MHZ __attribute__ ((deprecated("Replace with 28 directly"))), + I2C_CR2_FREQ_29MHZ __attribute__ ((deprecated("Replace with 29 directly"))), + I2C_CR2_FREQ_30MHZ __attribute__ ((deprecated("Replace with 30 directly"))), + I2C_CR2_FREQ_31MHZ __attribute__ ((deprecated("Replace with 31 directly"))), + I2C_CR2_FREQ_32MHZ __attribute__ ((deprecated("Replace with 32 directly"))), + I2C_CR2_FREQ_33MHZ __attribute__ ((deprecated("Replace with 33 directly"))), + I2C_CR2_FREQ_34MHZ __attribute__ ((deprecated("Replace with 34 directly"))), + I2C_CR2_FREQ_35MHZ __attribute__ ((deprecated("Replace with 35 directly"))), + I2C_CR2_FREQ_36MHZ __attribute__ ((deprecated("Replace with 36 directly"))), + I2C_CR2_FREQ_37MHZ __attribute__ ((deprecated("Replace with 37 directly"))), + I2C_CR2_FREQ_38MHZ __attribute__ ((deprecated("Replace with 38 directly"))), + I2C_CR2_FREQ_39MHZ __attribute__ ((deprecated("Replace with 39 directly"))), + I2C_CR2_FREQ_40MHZ __attribute__ ((deprecated("Replace with 40 directly"))), + I2C_CR2_FREQ_41MHZ __attribute__ ((deprecated("Replace with 41 directly"))), + I2C_CR2_FREQ_42MHZ __attribute__ ((deprecated("Replace with 42 directly"))), +} __attribute__ ((deprecated("Replace _nMHZ with n directly"))); -@{*/ -#define I2C_CR2_FREQ_2MHZ 0x02 -#define I2C_CR2_FREQ_3MHZ 0x03 -#define I2C_CR2_FREQ_4MHZ 0x04 -#define I2C_CR2_FREQ_5MHZ 0x05 -#define I2C_CR2_FREQ_6MHZ 0x06 -#define I2C_CR2_FREQ_7MHZ 0x07 -#define I2C_CR2_FREQ_8MHZ 0x08 -#define I2C_CR2_FREQ_9MHZ 0x09 -#define I2C_CR2_FREQ_10MHZ 0x0a -#define I2C_CR2_FREQ_11MHZ 0x0b -#define I2C_CR2_FREQ_12MHZ 0x0c -#define I2C_CR2_FREQ_13MHZ 0x0d -#define I2C_CR2_FREQ_14MHZ 0x0e -#define I2C_CR2_FREQ_15MHZ 0x0f -#define I2C_CR2_FREQ_16MHZ 0x10 -#define I2C_CR2_FREQ_17MHZ 0x11 -#define I2C_CR2_FREQ_18MHZ 0x12 -#define I2C_CR2_FREQ_19MHZ 0x13 -#define I2C_CR2_FREQ_20MHZ 0x14 -#define I2C_CR2_FREQ_21MHZ 0x15 -#define I2C_CR2_FREQ_22MHZ 0x16 -#define I2C_CR2_FREQ_23MHZ 0x17 -#define I2C_CR2_FREQ_24MHZ 0x18 -#define I2C_CR2_FREQ_25MHZ 0x19 -#define I2C_CR2_FREQ_26MHZ 0x1a -#define I2C_CR2_FREQ_27MHZ 0x1b -#define I2C_CR2_FREQ_28MHZ 0x1c -#define I2C_CR2_FREQ_29MHZ 0x1d -#define I2C_CR2_FREQ_30MHZ 0x1e -#define I2C_CR2_FREQ_31MHZ 0x1f -#define I2C_CR2_FREQ_32MHZ 0x20 -#define I2C_CR2_FREQ_33MHZ 0x21 -#define I2C_CR2_FREQ_34MHZ 0x22 -#define I2C_CR2_FREQ_35MHZ 0x23 -#define I2C_CR2_FREQ_36MHZ 0x24 -#define I2C_CR2_FREQ_37MHZ 0x25 -#define I2C_CR2_FREQ_38MHZ 0x26 -#define I2C_CR2_FREQ_39MHZ 0x27 -#define I2C_CR2_FREQ_40MHZ 0x28 -#define I2C_CR2_FREQ_41MHZ 0x29 -#define I2C_CR2_FREQ_42MHZ 0x2a -/**@}*/ /* --- I2Cx_OAR1 values ---------------------------------------------------- */ From 1acfa1c9178c1943124d9dd5275cb1063ba4cbd7 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 16 Oct 2020 10:35:57 +0000 Subject: [PATCH 008/206] stm32l1: desig: handle flash size footnotes from refman Some of the chipid variants have some footnotes on reading the flash size register, make sure we report things nicely. --- lib/stm32/l1/desig.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/stm32/l1/desig.c b/lib/stm32/l1/desig.c index 0bdf98b4..80a12500 100644 --- a/lib/stm32/l1/desig.c +++ b/lib/stm32/l1/desig.c @@ -23,15 +23,20 @@ uint16_t desig_get_flash_size(void) { + uint32_t v; uint32_t device_id = DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK; switch (device_id) { case 0x416: - case 0x429: return *(uint32_t*)DESIG_FLASH_SIZE_BASE_CAT12; + case 0x429: + v = *(uint32_t*)DESIG_FLASH_SIZE_BASE_CAT12; + return v & 0xff; case 0x427: - case 0x436: case 0x437: return *(uint32_t*)DESIG_FLASH_SIZE_BASE_CAT3456; + case 0x436: + v = *(uint32_t*)DESIG_FLASH_SIZE_BASE_CAT3456; + return v ? 256 : 384; } cm3_assert_not_reached(); From 54319107b0d2a89d5b998bbe87d2470adf18c4c5 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 11 Oct 2020 22:39:00 +0000 Subject: [PATCH 009/206] ld: support ".noinit*" uninitialized ram section Add support for a section(s) ".noinit*" that will be allocated in ram, but not cleared or initialized. This can be used for passing variables between a bootloader and an app for instance, or even just between restarts of your application. Without any assigned usages of the section, there is zero change in ram usage. The align does nothing when the prior section was already aligned. --- ld/linker.ld.S | 6 ++++++ lib/cortex-m-generic.ld | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/ld/linker.ld.S b/ld/linker.ld.S index 908ad9ea..84c1cd18 100644 --- a/ld/linker.ld.S +++ b/ld/linker.ld.S @@ -118,6 +118,12 @@ SECTIONS . = ALIGN(4); _etext = .; + /* ram, but not cleared on reset, eg boot/app comms */ + .noinit (NOLOAD) : { + *(.noinit*) + } >ram + . = ALIGN(4); + .data : { _data = .; *(.data*) /* Read-write initialized data */ diff --git a/lib/cortex-m-generic.ld b/lib/cortex-m-generic.ld index fc169764..8b995d35 100644 --- a/lib/cortex-m-generic.ld +++ b/lib/cortex-m-generic.ld @@ -89,6 +89,12 @@ SECTIONS . = ALIGN(4); _etext = .; + /* ram, but not cleared on reset, eg boot/app comms */ + .noinit (NOLOAD) : { + *(.noinit*) + } >ram + . = ALIGN(4); + .data : { _data = .; *(.data*) /* Read-write initialized data */ From b88196f8074751cbcef3e3cf7e272bd518aab475 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 16 Oct 2020 12:08:14 +0000 Subject: [PATCH 010/206] ld: support ".ramtext" section hook to place functions in ram We already had the hooks for ccmram and ram1 and ram2 and ram3 and xsram for "other" ram sections, but there was no method, out of the box, for placing a function in "normal" ram. The "easy" method of labelling a function as ".data.someramfunc" causes warnings because code isn't meant to have a name like ".data*" so we must explicitly add a new code section. Signed-off-by: Karl Palsson --- ld/linker.ld.S | 1 + lib/cortex-m-generic.ld | 1 + 2 files changed, 2 insertions(+) diff --git a/ld/linker.ld.S b/ld/linker.ld.S index 84c1cd18..20aaf024 100644 --- a/ld/linker.ld.S +++ b/ld/linker.ld.S @@ -127,6 +127,7 @@ SECTIONS .data : { _data = .; *(.data*) /* Read-write initialized data */ + *(.ramtext*) /* "text" functions to run in ram */ . = ALIGN(4); _edata = .; } >ram AT >rom diff --git a/lib/cortex-m-generic.ld b/lib/cortex-m-generic.ld index 8b995d35..f7b1da01 100644 --- a/lib/cortex-m-generic.ld +++ b/lib/cortex-m-generic.ld @@ -98,6 +98,7 @@ SECTIONS .data : { _data = .; *(.data*) /* Read-write initialized data */ + *(.ramtext*) /* "text" functions to run in ram */ . = ALIGN(4); _edata = .; } >ram AT >rom From 43b3fa5ddc6a1414afb503fe68f2786c87a9aecf Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 16 Oct 2020 10:35:07 +0000 Subject: [PATCH 011/206] stm32l0/l1: flash: support half page flashing Tested on L1 and L0 using the "dapboot" project, see https://github.com/devanlai/dapboot/pull/27 for L1 and https://github.com/devanlai/dapboot/pull/30 for L0 --- .../stm32/common/flash_common_l01.h | 13 ++++++++ include/libopencm3/stm32/l0/flash.h | 2 ++ include/libopencm3/stm32/l1/flash.h | 2 +- lib/stm32/common/flash_common_l01.c | 30 +++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/common/flash_common_l01.h b/include/libopencm3/stm32/common/flash_common_l01.h index 442c000f..4f7a5524 100644 --- a/include/libopencm3/stm32/common/flash_common_l01.h +++ b/include/libopencm3/stm32/common/flash_common_l01.h @@ -120,6 +120,19 @@ void flash_unlock_progmem(void); void flash_lock_progmem(void); void flash_lock_option_bytes(void); void flash_unlock_acr(void); +/** Erase a page in flash. + * @param page_address For L1, must be first word in page, L0 doesn't care + * Takes 1 tprog. Flash must already be unlocked! + */ +void flash_erase_page(uint32_t page_address); + +/** + * Write a half page from buf to dst. + * This function _must_ be in ram! (See the Ref Man for more details) + * @param dst where to write to, expected to be aligned and erased. + * @param buf the half page to write, size required depends on target + */ +void flash_program_half_page(uint32_t *dst, void *buf); void eeprom_program_word(uint32_t address, uint32_t data); void eeprom_program_words(uint32_t address, uint32_t *data, int length_in_words); diff --git a/include/libopencm3/stm32/l0/flash.h b/include/libopencm3/stm32/l0/flash.h index ef1d1883..a0be623b 100644 --- a/include/libopencm3/stm32/l0/flash.h +++ b/include/libopencm3/stm32/l0/flash.h @@ -55,6 +55,8 @@ /* --- FLASH_OPTR values ----------------------------------------------------- */ #define FLASH_OPTR_NBOOT1 (1 << 31) +#define FLASH_HALF_PAGE_SIZE 16 + BEGIN_DECLS END_DECLS diff --git a/include/libopencm3/stm32/l1/flash.h b/include/libopencm3/stm32/l1/flash.h index a84a55b3..2a163d0b 100644 --- a/include/libopencm3/stm32/l1/flash.h +++ b/include/libopencm3/stm32/l1/flash.h @@ -56,7 +56,7 @@ /* --- FLASH_SR values ----------------------------------------------------- */ #define FLASH_SR_OPTVERRUSR (1 << 12) -/* --- Function prototypes ------------------------------------------------- */ +#define FLASH_HALF_PAGE_SIZE 32 BEGIN_DECLS diff --git a/lib/stm32/common/flash_common_l01.c b/lib/stm32/common/flash_common_l01.c index 9fb1212b..6415f728 100644 --- a/lib/stm32/common/flash_common_l01.c +++ b/lib/stm32/common/flash_common_l01.c @@ -97,6 +97,36 @@ void flash_unlock_acr(void) FLASH_PDKEYR = FLASH_PDKEYR_PDKEY2; } +/** + * Erase a page in ram. + * @param page_address must be first word in page for L1, any address in page for L0 + */ +void flash_erase_page(uint32_t page_address) +{ + FLASH_PECR |= FLASH_PECR_ERASE | FLASH_PECR_PROG; + MMIO32(page_address) = 0; + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); + FLASH_PECR &= ~(FLASH_PECR_ERASE | FLASH_PECR_PROG); +} + +/* Must be run from RAM (per ref manual), and because it's in ram, more + * than 64MB away from flash address space, must be a long_call. */ +__attribute__ ((long_call, section (".ramtext"))) +void flash_program_half_page(uint32_t *dst, void *buf) +{ + uint32_t *src = buf; + + /* Enable half page writes to program memory */ + FLASH_PECR |= FLASH_PECR_FPRG | FLASH_PECR_PROG; + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); + for (int i = 0; i < FLASH_HALF_PAGE_SIZE; i++) { + *dst++ = *src++; + } + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); + FLASH_PECR &= ~(FLASH_PECR_FPRG | FLASH_PECR_PROG); +} + + /** @brief Write a word to eeprom * * @param address assumed to be in the eeprom space, no checking From c7d7a18dd79bbd188fb80b12843bad28ef4e0e48 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 18 Oct 2020 14:48:45 +0000 Subject: [PATCH 012/206] stm32: rcc: Standardize prescaler define names We did have * _HPRE_SYSCLK_DIVN (3 parts) * _HPRE_DIVN (5 parts) * _HPRE_DIV_N (4 parts) Unify all on _HPRE_DIVN. Provide deprecated definitions to not break everything at once. Also, standardize on "NODIV" instead of DIVNONE. --- include/libopencm3/gd32/f1x0/rcc.h | 86 ++++++++++++++++++--------- include/libopencm3/stm32/f1/rcc.h | 95 +++++++++++++++++++----------- include/libopencm3/stm32/f2/rcc.h | 63 +++++++++++++++----- include/libopencm3/stm32/f3/rcc.h | 77 +++++++++++++++--------- include/libopencm3/stm32/f4/rcc.h | 60 ++++++++++++++----- include/libopencm3/stm32/f7/rcc.h | 60 ++++++++++++++----- include/libopencm3/stm32/l0/rcc.h | 53 ++++++++++------- include/libopencm3/stm32/l1/rcc.h | 78 ++++++++++++++++-------- 8 files changed, 386 insertions(+), 186 deletions(-) diff --git a/include/libopencm3/gd32/f1x0/rcc.h b/include/libopencm3/gd32/f1x0/rcc.h index 63778317..935d9e18 100644 --- a/include/libopencm3/gd32/f1x0/rcc.h +++ b/include/libopencm3/gd32/f1x0/rcc.h @@ -174,44 +174,39 @@ /** @defgroup rcc_cfgr_adcpre ADCPRE: ADC prescaler * @{ */ -#define RCC_CFGR_ADCPRE_PCLK2_DIV2 0x0 -#define RCC_CFGR_ADCPRE_PCLK2_DIV4 0x1 -#define RCC_CFGR_ADCPRE_PCLK2_DIV6 0x2 -#define RCC_CFGR_ADCPRE_PCLK2_DIV8 0x3 +#define RCC_CFGR_ADCPRE_DIV2 0x0 +#define RCC_CFGR_ADCPRE_DIV4 0x1 +#define RCC_CFGR_ADCPRE_DIV6 0x2 +#define RCC_CFGR_ADCPRE_DIV8 0x3 /**@}*/ -/** @defgroup rcc_cfgr_apb2pre PPRE2: APB high-speed prescaler (APB2) +#define RCC_CFGR_PPRE2_SHIFT 11 +#define RCC_CFGR_PPRE2_MASK 0x7 +#define RCC_CFGR_PPRE1_SHIFT 8 +#define RCC_CFGR_PPRE1_MASK 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling * @{ */ -#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 -/**@}*/ - -/** @defgroup rcc_cfgr_apb1pre 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 +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_DIV16 0x7 /**@}*/ /** @defgroup rcc_cfgr_ahbpre 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 +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 0x8 +#define RCC_CFGR_HPRE_DIV4 0x9 +#define RCC_CFGR_HPRE_DIV8 0xa +#define RCC_CFGR_HPRE_DIV16 0xb +#define RCC_CFGR_HPRE_DIV64 0xc +#define RCC_CFGR_HPRE_DIV128 0xd +#define RCC_CFGR_HPRE_DIV256 0xe +#define RCC_CFGR_HPRE_DIV512 0xf /**@}*/ /* SWS: System clock switch status */ @@ -227,6 +222,39 @@ #define RCC_CFGR_SW_SYSCLKSEL_PLLCLK 0x2 /**@}*/ +/** Older compatible definitions to ease migration + * @defgroup rcc_cfgr_deprecated RCC_CFGR Deprecated dividers + * @deprecated Use _CFGR_xPRE_DIVn form instead, across all families + * @{ + */ +#define RCC_CFGR_ADCPRE_PCLK2_DIV2 0x0 +#define RCC_CFGR_ADCPRE_PCLK2_DIV4 0x1 +#define RCC_CFGR_ADCPRE_PCLK2_DIV6 0x2 +#define RCC_CFGR_ADCPRE_PCLK2_DIV8 0x3 + +#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 + +#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 + +#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 +/**@}*/ + /* --- RCC_CIR values ------------------------------------------------------ */ /* Clock security system interrupt clear bit */ diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index 3b066f1a..c3efced0 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -186,34 +186,25 @@ @ingroup STM32F1xx_rcc_defines @{*/ -#define RCC_CFGR_ADCPRE_PCLK2_DIV2 0x0 -#define RCC_CFGR_ADCPRE_PCLK2_DIV4 0x1 -#define RCC_CFGR_ADCPRE_PCLK2_DIV6 0x2 -#define RCC_CFGR_ADCPRE_PCLK2_DIV8 0x3 +#define RCC_CFGR_ADCPRE_DIV2 0x0 +#define RCC_CFGR_ADCPRE_DIV4 0x1 +#define RCC_CFGR_ADCPRE_DIV6 0x2 +#define RCC_CFGR_ADCPRE_DIV8 0x3 /**@}*/ -/* PPRE2: APB high-speed prescaler (APB2) */ -/** @defgroup rcc_cfgr_apb2pre RCC_CFGR APB2 prescale Factors -@ingroup STM32F1xx_rcc_defines - -@{*/ -#define RCC_CFGR_PPRE2_HCLK_NODIV 0x0 -#define RCC_CFGR_PPRE2_HCLK_DIV2 0x4 -#define RCC_CFGR_PPRE2_HCLK_DIV4 0x5 -#define RCC_CFGR_PPRE2_HCLK_DIV8 0x6 -#define RCC_CFGR_PPRE2_HCLK_DIV16 0x7 -/**@}*/ - -/* PPRE1: APB low-speed prescaler (APB1) */ -/** @defgroup rcc_cfgr_apb1pre RCC_CFGR APB1 prescale Factors -@ingroup STM32F1xx_rcc_defines - -@{*/ -#define RCC_CFGR_PPRE1_HCLK_NODIV 0x0 -#define RCC_CFGR_PPRE1_HCLK_DIV2 0x4 -#define RCC_CFGR_PPRE1_HCLK_DIV4 0x5 -#define RCC_CFGR_PPRE1_HCLK_DIV8 0x6 -#define RCC_CFGR_PPRE1_HCLK_DIV16 0x7 +#define RCC_CFGR_PPRE2_SHIFT 11 +#define RCC_CFGR_PPRE2_MASK 0x7 +#define RCC_CFGR_PPRE1_SHIFT 8 +#define RCC_CFGR_PPRE1_MASK 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling + * @{ + */ +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_DIV16 0x7 /**@}*/ /* HPRE: AHB prescaler */ @@ -221,15 +212,15 @@ @ingroup STM32F1xx_rcc_defines @{*/ -#define RCC_CFGR_HPRE_SYSCLK_NODIV 0x0 -#define RCC_CFGR_HPRE_SYSCLK_DIV2 0x8 -#define RCC_CFGR_HPRE_SYSCLK_DIV4 0x9 -#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 +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 0x8 +#define RCC_CFGR_HPRE_DIV4 0x9 +#define RCC_CFGR_HPRE_DIV8 0xa +#define RCC_CFGR_HPRE_DIV16 0xb +#define RCC_CFGR_HPRE_DIV64 0xc +#define RCC_CFGR_HPRE_DIV128 0xd +#define RCC_CFGR_HPRE_DIV256 0xe +#define RCC_CFGR_HPRE_DIV512 0xf /**@}*/ /* SWS: System clock switch status */ @@ -247,6 +238,40 @@ #define RCC_CFGR_SW_SYSCLKSEL_PLLCLK 0x2 /**@}*/ +/** Older compatible definitions to ease migration + * @defgroup rcc_cfgr_deprecated RCC_CFGR Deprecated dividers + * @deprecated Use _CFGR_xPRE_DIVn form instead, across all families + * @{ + */ +#define RCC_CFGR_ADCPRE_PCLK2_DIV2 0x0 +#define RCC_CFGR_ADCPRE_PCLK2_DIV4 0x1 +#define RCC_CFGR_ADCPRE_PCLK2_DIV6 0x2 +#define RCC_CFGR_ADCPRE_PCLK2_DIV8 0x3 + +#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 + +#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 + +#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 + +/** @}*/ + /* --- RCC_CIR values ------------------------------------------------------ */ /* Clock security system interrupt clear bit */ diff --git a/include/libopencm3/stm32/f2/rcc.h b/include/libopencm3/stm32/f2/rcc.h index 923ac81e..1831feb0 100644 --- a/include/libopencm3/stm32/f2/rcc.h +++ b/include/libopencm3/stm32/f2/rcc.h @@ -142,26 +142,35 @@ #define RCC_CFGR_RTCPRE_SHIFT 16 #define RCC_CFGR_RTCPRE_MASK 0x1f -/* PPRE1/2: APB high-speed prescalers */ #define RCC_CFGR_PPRE2_SHIFT 13 +#define RCC_CFGR_PPRE2_MASK 0x7 #define RCC_CFGR_PPRE1_SHIFT 10 -#define RCC_CFGR_PPRE_DIV_NONE 0x0 -#define RCC_CFGR_PPRE_DIV_2 0x4 -#define RCC_CFGR_PPRE_DIV_4 0x5 -#define RCC_CFGR_PPRE_DIV_8 0x6 -#define RCC_CFGR_PPRE_DIV_16 0x7 +#define RCC_CFGR_PPRE1_MASK 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling + * @{ + */ +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_DIV16 0x7 +/**@}*/ -/* HPRE: AHB high-speed prescaler */ #define RCC_CFGR_HPRE_SHIFT 4 -#define RCC_CFGR_HPRE_DIV_NONE 0x0 -#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) -#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) -#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) -#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) -#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) -#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) -#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) -#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) +#define RCC_CFGR_HPRE_MASK 0xf +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale factors +@{*/ +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV512 (0x8 + 7) +/**@}*/ /* SWS: System clock switch status */ #define RCC_CFGR_SWS_SHIFT 2 @@ -176,6 +185,28 @@ #define RCC_CFGR_SW_HSE 0x1 #define RCC_CFGR_SW_PLL 0x2 +/** Older compatible definitions to ease migration + * @defgroup rcc_cfgr_deprecated RCC_CFGR Deprecated dividers + * @deprecated Use _CFGR_xPRE_DIVn form instead, across all families + * @{ + */ +#define RCC_CFGR_PPRE_DIV_NONE 0x0 +#define RCC_CFGR_PPRE_DIV_2 0x4 +#define RCC_CFGR_PPRE_DIV_4 0x5 +#define RCC_CFGR_PPRE_DIV_8 0x6 +#define RCC_CFGR_PPRE_DIV_16 0x7 + +#define RCC_CFGR_HPRE_DIV_NONE 0x0 +#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) +/**@}*/ + /* --- RCC_CIR values ------------------------------------------------------ */ /* Clock security system interrupt clear bit */ diff --git a/include/libopencm3/stm32/f3/rcc.h b/include/libopencm3/stm32/f3/rcc.h index c83b2ac6..fd6fe286 100644 --- a/include/libopencm3/stm32/f3/rcc.h +++ b/include/libopencm3/stm32/f3/rcc.h @@ -124,40 +124,35 @@ #define RCC_CFGR_PLLMUL_MUL15 0xD #define RCC_CFGR_PLLMUL_MUL16 0xE -/* PPRE2: APB high-speed prescaler (APB2) */ #define RCC_CFGR_PPRE2_SHIFT 11 #define RCC_CFGR_PPRE2_MASK 0x7 -/* 0XX: HCLK not divided */ -#define RCC_CFGR_PPRE2_DIV_NONE 0x0 - -#define RCC_CFGR_PPRE2_DIV_2 0x4 -#define RCC_CFGR_PPRE2_DIV_4 0x5 -#define RCC_CFGR_PPRE2_DIV_8 0x6 -#define RCC_CFGR_PPRE2_DIV_16 0x7 - -/* PPRE1:APB Low-speed prescaler (APB1) */ #define RCC_CFGR_PPRE1_SHIFT 8 #define RCC_CFGR_PPRE1_MASK 0x7 -/* 0XX: HCLK not divided */ -#define RCC_CFGR_PPRE1_DIV_NONE 0x0 -#define RCC_CFGR_PPRE1_DIV_2 0x4 -#define RCC_CFGR_PPRE1_DIV_4 0x5 -#define RCC_CFGR_PPRE1_DIV_8 0x6 -#define RCC_CFGR_PPRE1_DIV_16 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling + * @{ + */ +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_DIV16 0x7 +/**@}*/ -/* HPRE: HLCK prescaler */ #define RCC_CFGR_HPRE_SHIFT 4 #define RCC_CFGR_HPRE_MASK 0xf -/* 0XXX: SYSCLK not divided */ -#define RCC_CFGR_HPRE_DIV_NONE 0x0 -#define RCC_CFGR_HPRE_DIV_2 0x8 -#define RCC_CFGR_HPRE_DIV_4 0x9 -#define RCC_CFGR_HPRE_DIV_8 0xA -#define RCC_CFGR_HPRE_DIV_16 0xB -#define RCC_CFGR_HPRE_DIV_64 0xC -#define RCC_CFGR_HPRE_DIV_128 0xD -#define RCC_CFGR_HPRE_DIV_256 0xE -#define RCC_CFGR_HPRE_DIV_512 0xF +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale factors +@{*/ +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 0x8 +#define RCC_CFGR_HPRE_DIV4 0x9 +#define RCC_CFGR_HPRE_DIV8 0xA +#define RCC_CFGR_HPRE_DIV16 0xB +#define RCC_CFGR_HPRE_DIV64 0xC +#define RCC_CFGR_HPRE_DIV128 0xD +#define RCC_CFGR_HPRE_DIV256 0xE +#define RCC_CFGR_HPRE_DIV512 0xF +/**@}*/ /* SWS: System clock switch status */ #define RCC_CFGR_SWS_SHIFT 2 @@ -172,6 +167,34 @@ #define RCC_CFGR_SW_HSE 0x1 #define RCC_CFGR_SW_PLL 0x2 +/** Older compatible definitions to ease migration + * @defgroup rcc_cfgr_deprecated RCC_CFGR Deprecated dividers + * @deprecated Use _CFGR_xPRE_DIVn form instead, across all families + * @{ + */ +#define RCC_CFGR_PPRE2_DIV_NONE 0x0 +#define RCC_CFGR_PPRE2_DIV_2 0x4 +#define RCC_CFGR_PPRE2_DIV_4 0x5 +#define RCC_CFGR_PPRE2_DIV_8 0x6 +#define RCC_CFGR_PPRE2_DIV_16 0x7 + +#define RCC_CFGR_PPRE1_DIV_NONE 0x0 +#define RCC_CFGR_PPRE1_DIV_2 0x4 +#define RCC_CFGR_PPRE1_DIV_4 0x5 +#define RCC_CFGR_PPRE1_DIV_8 0x6 +#define RCC_CFGR_PPRE1_DIV_16 0x7 + +#define RCC_CFGR_HPRE_DIV_NONE 0x0 +#define RCC_CFGR_HPRE_DIV_2 0x8 +#define RCC_CFGR_HPRE_DIV_4 0x9 +#define RCC_CFGR_HPRE_DIV_8 0xA +#define RCC_CFGR_HPRE_DIV_16 0xB +#define RCC_CFGR_HPRE_DIV_64 0xC +#define RCC_CFGR_HPRE_DIV_128 0xD +#define RCC_CFGR_HPRE_DIV_256 0xE +#define RCC_CFGR_HPRE_DIV_512 0xF +/**@}*/ + /* --- RCC_CIR values ------------------------------------------------------ */ /* Clock security system interrupt clear bit */ diff --git a/include/libopencm3/stm32/f4/rcc.h b/include/libopencm3/stm32/f4/rcc.h index 8e39f064..e957b06c 100644 --- a/include/libopencm3/stm32/f4/rcc.h +++ b/include/libopencm3/stm32/f4/rcc.h @@ -206,29 +206,35 @@ #define RCC_CFGR_RTCPRE_SHIFT 16 #define RCC_CFGR_RTCPRE_MASK 0x1f -/* PPRE1/2: APB high-speed prescalers */ #define RCC_CFGR_PPRE2_SHIFT 13 #define RCC_CFGR_PPRE2_MASK 0x7 #define RCC_CFGR_PPRE1_SHIFT 10 #define RCC_CFGR_PPRE1_MASK 0x7 -#define RCC_CFGR_PPRE_DIV_NONE 0x0 -#define RCC_CFGR_PPRE_DIV_2 0x4 -#define RCC_CFGR_PPRE_DIV_4 0x5 -#define RCC_CFGR_PPRE_DIV_8 0x6 -#define RCC_CFGR_PPRE_DIV_16 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling + * @{ + */ +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_DIV16 0x7 +/**@}*/ -/* HPRE: AHB high-speed prescaler */ #define RCC_CFGR_HPRE_SHIFT 4 #define RCC_CFGR_HPRE_MASK 0xf -#define RCC_CFGR_HPRE_DIV_NONE 0x0 -#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) -#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) -#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) -#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) -#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) -#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) -#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) -#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale factors +@{*/ +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV512 (0x8 + 7) +/**@}*/ /* SWS: System clock switch status */ #define RCC_CFGR_SWS_SHIFT 2 @@ -244,6 +250,28 @@ #define RCC_CFGR_SW_PLL 0x2 /**@}*/ +/** Older compatible definitions to ease migration + * @defgroup rcc_cfgr_deprecated RCC_CFGR Deprecated dividers + * @deprecated Use _CFGR_xPRE_DIVn form instead, across all families + * @{ + */ +#define RCC_CFGR_PPRE_DIV_NONE 0x0 +#define RCC_CFGR_PPRE_DIV_2 0x4 +#define RCC_CFGR_PPRE_DIV_4 0x5 +#define RCC_CFGR_PPRE_DIV_8 0x6 +#define RCC_CFGR_PPRE_DIV_16 0x7 + +#define RCC_CFGR_HPRE_DIV_NONE 0x0 +#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) +/**@}*/ + /** @defgroup rcc_cir_values RCC_CIR values * @ingroup rcc_registers * @brief Clock Interrupt register values diff --git a/include/libopencm3/stm32/f7/rcc.h b/include/libopencm3/stm32/f7/rcc.h index 20ed3a5d..bace1c3a 100644 --- a/include/libopencm3/stm32/f7/rcc.h +++ b/include/libopencm3/stm32/f7/rcc.h @@ -137,29 +137,35 @@ #define RCC_CFGR_RTCPRE_SHIFT 16 #define RCC_CFGR_RTCPRE_MASK 0x1f -/* PPRE1/2: APB high-speed prescalers */ #define RCC_CFGR_PPRE2_SHIFT 13 #define RCC_CFGR_PPRE2_MASK 0x7 #define RCC_CFGR_PPRE1_SHIFT 10 #define RCC_CFGR_PPRE1_MASK 0x7 -#define RCC_CFGR_PPRE_DIV_NONE 0x0 -#define RCC_CFGR_PPRE_DIV_2 0x4 -#define RCC_CFGR_PPRE_DIV_4 0x5 -#define RCC_CFGR_PPRE_DIV_8 0x6 -#define RCC_CFGR_PPRE_DIV_16 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling + * @{ + */ +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_DIV16 0x7 +/**@}*/ -/* HPRE: AHB high-speed prescaler */ #define RCC_CFGR_HPRE_SHIFT 4 #define RCC_CFGR_HPRE_MASK 0xf -#define RCC_CFGR_HPRE_DIV_NONE 0x0 -#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) -#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) -#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) -#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) -#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) -#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) -#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) -#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale factors +@{*/ +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV512 (0x8 + 7) +/**@}*/ /* SWS: System clock switch status */ #define RCC_CFGR_SWS_SHIFT 2 @@ -175,6 +181,28 @@ #define RCC_CFGR_SW_HSE 0x1 #define RCC_CFGR_SW_PLL 0x2 +/** Older compatible definitions to ease migration + * @defgroup rcc_cfgr_deprecated RCC_CFGR Deprecated dividers + * @deprecated Use _CFGR_xPRE_DIVn form instead, across all families + * @{ + */ +#define RCC_CFGR_PPRE_DIV_NONE 0x0 +#define RCC_CFGR_PPRE_DIV_2 0x4 +#define RCC_CFGR_PPRE_DIV_4 0x5 +#define RCC_CFGR_PPRE_DIV_8 0x6 +#define RCC_CFGR_PPRE_DIV_16 0x7 + +#define RCC_CFGR_HPRE_DIV_NONE 0x0 +#define RCC_CFGR_HPRE_DIV_2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV_4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV_8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV_16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV_64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV_128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV_256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV_512 (0x8 + 7) +/**@}*/ + /* --- RCC_CIR values ------------------------------------------------------ */ /* Clock security system interrupt clear bit */ diff --git a/include/libopencm3/stm32/l0/rcc.h b/include/libopencm3/stm32/l0/rcc.h index 59194425..287f6b99 100644 --- a/include/libopencm3/stm32/l0/rcc.h +++ b/include/libopencm3/stm32/l0/rcc.h @@ -174,29 +174,20 @@ #define RCC_CFGR_STOPWUCK_MSI (0<<15) #define RCC_CFGR_STOPWUCK_HSI16 (1<<15) -/* PPRE2: APB high-speed prescaler (APB2) */ -/** @defgroup rcc_cfgr_apb2pre RCC_CFGR APB2 prescale Factors -@{*/ -#define RCC_CFGR_PPRE2_NODIV 0x0 -#define RCC_CFGR_PPRE2_DIV2 0x4 -#define RCC_CFGR_PPRE2_DIV4 0x5 -#define RCC_CFGR_PPRE2_DIV8 0x6 -#define RCC_CFGR_PPRE2_DIV16 0x7 +#define RCC_CFGR_PPRE2_SHIFT 11 +#define RCC_CFGR_PPRE2_MASK 0x7 +#define RCC_CFGR_PPRE1_SHIFT 8 +#define RCC_CFGR_PPRE1_MASK 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling + * @{ + */ +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_DIV16 0x7 /**@}*/ -#define RCC_CFGR_PPRE2_MASK 0x7 -#define RCC_CFGR_PPRE2_SHIFT 11 - -/* PPRE1: APB low-speed prescaler (APB1) */ -/** @defgroup rcc_cfgr_apb1pre RCC_CFGR APB1 prescale Factors -@{*/ -#define RCC_CFGR_PPRE1_NODIV 0x0 -#define RCC_CFGR_PPRE1_DIV2 0x4 -#define RCC_CFGR_PPRE1_DIV4 0x5 -#define RCC_CFGR_PPRE1_DIV8 0x6 -#define RCC_CFGR_PPRE1_DIV16 0x7 -/**@}*/ -#define RCC_CFGR_PPRE1_MASK 0x7 -#define RCC_CFGR_PPRE1_SHIFT 8 /* HPRE: AHB prescaler */ /** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale Factors @@ -230,6 +221,24 @@ #define RCC_CFGR_SW_MASK 0x3 #define RCC_CFGR_SW_SHIFT 0 +/** Older compatible definitions to ease migration + * @defgroup rcc_cfgr_deprecated RCC_CFGR Deprecated dividers + * @deprecated Use _CFGR_xPRE_DIVn form instead, across all families + * @{ + */ +#define RCC_CFGR_PPRE2_NODIV 0x0 +#define RCC_CFGR_PPRE2_DIV2 0x4 +#define RCC_CFGR_PPRE2_DIV4 0x5 +#define RCC_CFGR_PPRE2_DIV8 0x6 +#define RCC_CFGR_PPRE2_DIV16 0x7 + +#define RCC_CFGR_PPRE1_NODIV 0x0 +#define RCC_CFGR_PPRE1_DIV2 0x4 +#define RCC_CFGR_PPRE1_DIV4 0x5 +#define RCC_CFGR_PPRE1_DIV8 0x6 +#define RCC_CFGR_PPRE1_DIV16 0x7 +/**@}*/ + /* --- RCC_CIER - Clock interrupt enable register */ #define RCC_CIER_CSSLSE (1 << 7) diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h index 6540c6a6..b688a34f 100644 --- a/include/libopencm3/stm32/l1/rcc.h +++ b/include/libopencm3/stm32/l1/rcc.h @@ -164,34 +164,33 @@ #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 -#define RCC_CFGR_PPRE2_MASK 0x7 #define RCC_CFGR_PPRE2_SHIFT 11 - -/* 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 -#define RCC_CFGR_PPRE1_MASK 0x7 +#define RCC_CFGR_PPRE2_MASK 0x7 #define RCC_CFGR_PPRE1_SHIFT 8 +#define RCC_CFGR_PPRE1_MASK 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling + * @{ + */ +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_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 +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale factors +@{*/ +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 0x8 +#define RCC_CFGR_HPRE_DIV4 0x9 +#define RCC_CFGR_HPRE_DIV8 0xa +#define RCC_CFGR_HPRE_DIV16 0xb +#define RCC_CFGR_HPRE_DIV64 0xc +#define RCC_CFGR_HPRE_DIV128 0xd +#define RCC_CFGR_HPRE_DIV256 0xe +#define RCC_CFGR_HPRE_DIV512 0xf +/**@}*/ #define RCC_CFGR_HPRE_MASK 0xf #define RCC_CFGR_HPRE_SHIFT 4 @@ -211,6 +210,35 @@ #define RCC_CFGR_SW_MASK 0x3 #define RCC_CFGR_SW_SHIFT 0 +/** Older compatible definitions to ease migration + * @defgroup rcc_cfgr_deprecated RCC_CFGR Deprecated dividers + * @deprecated Use _CFGR_xPRE_DIVn form instead, across all families + * @{ + */ +#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 + +#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 + +#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 + +/**@}*/ + /* --- RCC_CIR values ------------------------------------------------------ */ /* Clock security system interrupt clear bit */ From 76c0a8c289488a6f6dbf74f7dbf12ac850c7782e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 18 Oct 2020 15:08:33 +0000 Subject: [PATCH 013/206] stm32: rcc: convert to use new standard defines --- lib/gd32/f1x0/rcc.c | 24 ++++++------ lib/stm32/f1/rcc.c | 64 ++++++++++++++++---------------- lib/stm32/f2/rcc.c | 6 +-- lib/stm32/f3/rcc.c | 18 ++++----- lib/stm32/f4/rcc.c | 90 ++++++++++++++++++++++----------------------- lib/stm32/f7/rcc.c | 36 +++++++++--------- lib/stm32/l1/rcc.c | 36 +++++++++--------- 7 files changed, 137 insertions(+), 137 deletions(-) diff --git a/lib/gd32/f1x0/rcc.c b/lib/gd32/f1x0/rcc.c index 729a71eb..867079dc 100644 --- a/lib/gd32/f1x0/rcc.c +++ b/lib/gd32/f1x0/rcc.c @@ -62,10 +62,10 @@ uint32_t rcc_ahb_frequency = 8000000; const struct rcc_clock_scale rcc_hsi_configs[] = { { /* 48MHz */ .pllmul = RCC_CFGR_PLLMUL_PLL_CLK_MUL12, - .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, - .ppre1 = RCC_CFGR_PPRE1_HCLK_DIV2, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, - .adcpre = RCC_CFGR_ADCPRE_PCLK2_DIV8, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV8, .use_hse = false, .ahb_frequency = 48000000, .apb1_frequency = 24000000, @@ -73,10 +73,10 @@ const struct rcc_clock_scale rcc_hsi_configs[] = { }, { /* 64MHz */ .pllmul = RCC_CFGR_PLLMUL_PLL_CLK_MUL16, - .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, - .ppre1 = RCC_CFGR_PPRE1_HCLK_DIV2, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, - .adcpre = RCC_CFGR_ADCPRE_PCLK2_DIV8, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV8, .use_hse = false, .ahb_frequency = 64000000, .apb1_frequency = 32000000, @@ -87,10 +87,10 @@ const struct rcc_clock_scale rcc_hsi_configs[] = { const struct rcc_clock_scale rcc_hse8_configs[] = { { /* 72MHz */ .pllmul = RCC_CFGR_PLLMUL_PLL_CLK_MUL9, - .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, - .ppre1 = RCC_CFGR_PPRE1_HCLK_DIV2, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, - .adcpre = RCC_CFGR_ADCPRE_PCLK2_DIV8, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV8, .usbpre = RCC_CFGR_USBPRE_PLL_CLK_DIV1_5, .use_hse = true, .pll_hse_prediv = RCC_CFGR2_PREDIV_NODIV, diff --git a/lib/stm32/f1/rcc.c b/lib/stm32/f1/rcc.c index bab64b51..ddd24e6a 100644 --- a/lib/stm32/f1/rcc.c +++ b/lib/stm32/f1/rcc.c @@ -631,10 +631,10 @@ void rcc_clock_setup_in_hsi_out_64mhz(void) * Set prescalers for AHB, ADC, APB1, APB2. * Do this before touching the PLL (TODO: why?). */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 64MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 8MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 32MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 64MHz Max. 72MHz */ + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); /* Set. 64MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_DIV8); /* Set. 8MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_DIV2); /* Set. 32MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_NODIV); /* Set. 64MHz Max. 72MHz */ /* * Sysclk is running with 64MHz -> 2 waitstates. @@ -684,10 +684,10 @@ void rcc_clock_setup_in_hsi_out_48mhz(void) * Set prescalers for AHB, ADC, APB1, APB2. * Do this before touching the PLL (TODO: why?). */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /*Set.48MHz Max.72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /*Set. 6MHz Max.14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /*Set.24MHz Max.36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /*Set.48MHz Max.72MHz */ + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); /*Set.48MHz Max.72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_DIV8); /*Set. 6MHz Max.14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_DIV2); /*Set.24MHz Max.36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_NODIV); /*Set.48MHz Max.72MHz */ rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_CLK_NODIV); /*Set.48MHz Max.48MHz */ /* @@ -738,10 +738,10 @@ void rcc_clock_setup_in_hsi_out_24mhz(void) * Set prescalers for AHB, ADC, APB1, APB2. * Do this before touching the PLL (TODO: why?). */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 24MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 12MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 24MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_DIV2); /* Set. 12MHz Max. 12MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_NODIV); /* Set. 24MHz Max. 24MHz */ /* * Sysclk is (will be) running with 24MHz -> 0 waitstates. @@ -796,10 +796,10 @@ void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) * Set prescalers for AHB, ADC, APB1, APB2. * Do this before touching the PLL (TODO: why?). */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 72MHz */ + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); /* Set. 24MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_DIV2); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_NODIV); /* Set. 24MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_NODIV); /* Set. 24MHz Max. 72MHz */ /* * Sysclk runs with 24MHz -> 0 waitstates. @@ -860,10 +860,10 @@ void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) * Set prescalers for AHB, ADC, APB1, APB2. * Do this before touching the PLL (TODO: why?). */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 9MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_DIV8); /* Set. 9MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_NODIV); /* Set. 72MHz Max. 72MHz */ /* * Sysclk runs with 72MHz -> 2 waitstates. @@ -924,10 +924,10 @@ void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) * Set prescalers for AHB, ADC, APB1, APB2. * Do this before touching the PLL (TODO: why?). */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_DIV6); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_NODIV); /* Set. 72MHz Max. 72MHz */ /* * Sysclk runs with 72MHz -> 2 waitstates. @@ -988,10 +988,10 @@ void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) * Set prescalers for AHB, ADC, APB1, APB2. * Do this before touching the PLL (TODO: why?). */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_DIV6); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_NODIV); /* Set. 72MHz Max. 72MHz */ /* * Sysclk runs with 72MHz -> 2 waitstates. @@ -1053,10 +1053,10 @@ void rcc_clock_setup_in_hse_25mhz_out_72mhz(void) * Set prescalers for AHB, ADC, APB1, APB2. * Do this before touching the PLL (TODO: why?). */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_DIV6); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_NODIV); /* Set. 72MHz Max. 72MHz */ /* Set pll2 prediv and multiplier */ rcc_set_prediv2(RCC_CFGR2_PREDIV2_DIV5); diff --git a/lib/stm32/f2/rcc.c b/lib/stm32/f2/rcc.c index bb091f6a..80db1935 100644 --- a/lib/stm32/f2/rcc.c +++ b/lib/stm32/f2/rcc.c @@ -54,9 +54,9 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .plln = 240, .pllp = 2, .pllq = 5, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, .apb1_frequency = 30000000, diff --git a/lib/stm32/f3/rcc.c b/lib/stm32/f3/rcc.c index 75e92647..9d5fc6d5 100644 --- a/lib/stm32/f3/rcc.c +++ b/lib/stm32/f3/rcc.c @@ -48,9 +48,9 @@ const struct rcc_clock_scale rcc_hsi_configs[] = { { /* 48MHz */ .pllmul = RCC_CFGR_PLLMUL_MUL12, .pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE1_DIV_2, - .ppre2 = RCC_CFGR_PPRE2_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, .flash_waitstates = 1, .ahb_frequency = 48000000, .apb1_frequency = 24000000, @@ -59,9 +59,9 @@ const struct rcc_clock_scale rcc_hsi_configs[] = { { /* 64MHz */ .pllmul = RCC_CFGR_PLLMUL_MUL16, .pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE1_DIV_2, - .ppre2 = RCC_CFGR_PPRE2_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, .flash_waitstates = 2, .ahb_frequency = 64000000, .apb1_frequency = 32000000, @@ -76,9 +76,9 @@ const struct rcc_clock_scale rcc_hse8mhz_configs[] = { .plldiv = RCC_CFGR2_PREDIV_NODIV, .usbdiv1 = false, .flash_waitstates = 2, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE1_DIV_2, - .ppre2 = RCC_CFGR_PPRE2_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, .ahb_frequency = 72e6, .apb1_frequency = 36e6, .apb2_frequency = 72e6, diff --git a/lib/stm32/f4/rcc.c b/lib/stm32/f4/rcc.c index f729312c..ba3f2469 100644 --- a/lib/stm32/f4/rcc.c +++ b/lib/stm32/f4/rcc.c @@ -57,9 +57,9 @@ const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_2, - .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, @@ -74,9 +74,9 @@ const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -91,9 +91,9 @@ const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_3V3_END] = { .pllq = 8, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -111,9 +111,9 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_2, - .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, @@ -128,9 +128,9 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -145,9 +145,9 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 8, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -165,9 +165,9 @@ const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_2, - .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, @@ -182,9 +182,9 @@ const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -199,9 +199,9 @@ const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 8, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -219,9 +219,9 @@ const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_2, - .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, @@ -236,9 +236,9 @@ const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -253,9 +253,9 @@ const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 8, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -273,9 +273,9 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_2, - .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, @@ -290,9 +290,9 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 7, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, @@ -307,9 +307,9 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { .pllq = 8, .pllr = 0, .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, diff --git a/lib/stm32/f7/rcc.c b/lib/stm32/f7/rcc.c index b95545d8..4246036a 100644 --- a/lib/stm32/f7/rcc.c +++ b/lib/stm32/f7/rcc.c @@ -25,9 +25,9 @@ const struct rcc_clock_scale rcc_3v3[RCC_CLOCK_3V3_END] = { .plln = 432, .pllp = 2, .pllq = 9, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .vos_scale = PWR_SCALE1, .overdrive = 1, .flash_waitstates = 7, @@ -39,9 +39,9 @@ const struct rcc_clock_scale rcc_3v3[RCC_CLOCK_3V3_END] = { .plln = 336, .pllp = 2, .pllq = 7, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .vos_scale = PWR_SCALE2, .overdrive = 1, .flash_waitstates = 5, @@ -53,9 +53,9 @@ const struct rcc_clock_scale rcc_3v3[RCC_CLOCK_3V3_END] = { .plln = 240, .pllp = 2, .pllq = 5, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .vos_scale = PWR_SCALE3, .overdrive = 0, .flash_waitstates = 3, @@ -67,9 +67,9 @@ const struct rcc_clock_scale rcc_3v3[RCC_CLOCK_3V3_END] = { .plln = 144, .pllp = 2, .pllq = 3, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_4, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV4, + .ppre2 = RCC_CFGR_PPRE_DIV2, .vos_scale = PWR_SCALE3, .overdrive = 0, .flash_waitstates = 2, @@ -81,9 +81,9 @@ const struct rcc_clock_scale rcc_3v3[RCC_CLOCK_3V3_END] = { .plln = 192, .pllp = 4, .pllq = 4, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_2, - .ppre2 = RCC_CFGR_PPRE_DIV_2, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_DIV2, .vos_scale = PWR_SCALE3, .overdrive = 0, .flash_waitstates = 1, @@ -95,9 +95,9 @@ const struct rcc_clock_scale rcc_3v3[RCC_CLOCK_3V3_END] = { .plln = 192, .pllp = 8, .pllq = 4, - .hpre = RCC_CFGR_HPRE_DIV_NONE, - .ppre1 = RCC_CFGR_PPRE_DIV_NONE, - .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, .vos_scale = PWR_SCALE3, .overdrive = 0, .flash_waitstates = 0, diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c index 5865abbb..06898d00 100644 --- a/lib/stm32/l1/rcc.c +++ b/lib/stm32/l1/rcc.c @@ -53,9 +53,9 @@ const struct rcc_clock_scale rcc_clock_config[RCC_CLOCK_CONFIG_END] = { .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, .pll_mul = RCC_CFGR_PLLMUL_MUL3, .pll_div = RCC_CFGR_PLLDIV_DIV2, - .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, - .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_waitstates = 1, .ahb_frequency = 24000000, @@ -66,9 +66,9 @@ const struct rcc_clock_scale rcc_clock_config[RCC_CLOCK_CONFIG_END] = { .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, .pll_mul = RCC_CFGR_PLLMUL_MUL6, .pll_div = RCC_CFGR_PLLDIV_DIV3, - .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, - .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_waitstates = 1, .ahb_frequency = 32000000, @@ -76,9 +76,9 @@ const struct rcc_clock_scale rcc_clock_config[RCC_CLOCK_CONFIG_END] = { .apb2_frequency = 32000000, }, { /* 16MHz HSI raw */ - .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, - .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_waitstates = 0, .ahb_frequency = 16000000, @@ -86,9 +86,9 @@ const struct rcc_clock_scale rcc_clock_config[RCC_CLOCK_CONFIG_END] = { .apb2_frequency = 16000000, }, { /* 4MHz HSI raw */ - .hpre = RCC_CFGR_HPRE_SYSCLK_DIV4, - .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .hpre = RCC_CFGR_HPRE_DIV4, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_waitstates = 0, .ahb_frequency = 4000000, @@ -96,9 +96,9 @@ const struct rcc_clock_scale rcc_clock_config[RCC_CLOCK_CONFIG_END] = { .apb2_frequency = 4000000, }, { /* 4MHz MSI raw */ - .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, - .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_waitstates = 0, .ahb_frequency = 4194000, @@ -107,9 +107,9 @@ const struct rcc_clock_scale rcc_clock_config[RCC_CLOCK_CONFIG_END] = { .msi_range = RCC_ICSCR_MSIRANGE_4MHZ, }, { /* 2MHz MSI raw */ - .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, - .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, .voltage_scale = PWR_SCALE1, .flash_waitstates = 0, .ahb_frequency = 2097000, From e9c94760e6e60a0d6e2bcafbf871894dbdf1c4ed Mon Sep 17 00:00:00 2001 From: Manuel Bl <10954524+manuelbl@users.noreply.github.com> Date: Sun, 18 Oct 2020 17:10:55 +0200 Subject: [PATCH 014/206] stm32l4: enable USB OTG driver --- include/libopencm3/stm32/l4/memorymap.h | 1 + include/libopencm3/usb/dwc/otg_fs.h | 2 +- lib/stm32/l4/Makefile | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/l4/memorymap.h b/include/libopencm3/stm32/l4/memorymap.h index baaa32f5..7d0f310b 100644 --- a/include/libopencm3/stm32/l4/memorymap.h +++ b/include/libopencm3/stm32/l4/memorymap.h @@ -106,6 +106,7 @@ #define GPIO_PORT_H_BASE (PERIPH_BASE_AHB2 + 0x1c00) /* Still AHB2, good job ST */ #define OTG_FS_BASE (0x50000000U + 0x00000) +#define USB_OTG_FS_BASE OTG_FS_BASE #define ADC1_BASE (0x50000000U + 0x40000) #define AES_BASE (0x50000000U + 0x60000) #define RNG_BASE (0x50000000U + 0x60800) diff --git a/include/libopencm3/usb/dwc/otg_fs.h b/include/libopencm3/usb/dwc/otg_fs.h index 6736c0ee..4510a849 100644 --- a/include/libopencm3/usb/dwc/otg_fs.h +++ b/include/libopencm3/usb/dwc/otg_fs.h @@ -28,7 +28,7 @@ #include /* Memory map is required for USB_OTG_FS_BASE address */ -#if defined(STM32F1) || defined(STM32F2) || defined(STM32F4) +#if defined(STM32F1) || defined(STM32F2) || defined(STM32F4) || defined(STM32L4) # include #elif defined(EFM32HG) # include diff --git a/lib/stm32/l4/Makefile b/lib/stm32/l4/Makefile index 9dc9e8d8..2f26dfd0 100644 --- a/lib/stm32/l4/Makefile +++ b/lib/stm32/l4/Makefile @@ -58,6 +58,7 @@ OBJS += usart_common_all.o usart_common_v2.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o OBJS += st_usbfs_core.o st_usbfs_v2.o +OBJS += usb_dwc_common.o usb_f107.o VPATH += ../../usb:../:../../cm3:../common VPATH += ../../ethernet From ffe8ddfca2cd8f405a43959c607e91b245f9673e Mon Sep 17 00:00:00 2001 From: Manuel Bl <10954524+manuelbl@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:32:31 +0200 Subject: [PATCH 015/206] stm32l4: Use USB_OTG_FS_BASE instead of OTG_FS_BASE Use the standard definition name, so that all standard shared code for this peripheral works. Reviewed-by: Karl Palsson --- include/libopencm3/stm32/l4/memorymap.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/libopencm3/stm32/l4/memorymap.h b/include/libopencm3/stm32/l4/memorymap.h index 7d0f310b..2510466c 100644 --- a/include/libopencm3/stm32/l4/memorymap.h +++ b/include/libopencm3/stm32/l4/memorymap.h @@ -105,8 +105,7 @@ #define GPIO_PORT_G_BASE (PERIPH_BASE_AHB2 + 0x1800) #define GPIO_PORT_H_BASE (PERIPH_BASE_AHB2 + 0x1c00) /* Still AHB2, good job ST */ -#define OTG_FS_BASE (0x50000000U + 0x00000) -#define USB_OTG_FS_BASE OTG_FS_BASE +#define USB_OTG_FS_BASE (0x50000000U + 0x00000) #define ADC1_BASE (0x50000000U + 0x40000) #define AES_BASE (0x50000000U + 0x60000) #define RNG_BASE (0x50000000U + 0x60800) From c13c2b3b3c41b71586209bd8a9615b0c34cb296c Mon Sep 17 00:00:00 2001 From: Devan Lai Date: Sat, 17 Oct 2020 17:12:20 +0000 Subject: [PATCH 016/206] usb: Allow registration of a single non-contiguous string descriptor for WinUSB Classic WinUSB support is detected by probing for a string descriptor at index 0xEE with a special string. usbd_register_extra_string() allows registration of a string at this index without having to provide 237 other string descriptors Originally filed as https://github.com/libopencm3/libopencm3/pull/849 WCID reference: https://github.com/pbatard/libwdi/wiki/WCID-Devices --- include/libopencm3/usb/usbd.h | 3 +++ lib/usb/usb.c | 16 ++++++++++++++++ lib/usb/usb_private.h | 4 ++++ lib/usb/usb_standard.c | 16 +++++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index d2451010..3576d2b2 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -165,6 +165,9 @@ extern int usbd_register_set_config_callback(usbd_device *usbd_dev, extern void usbd_register_set_altsetting_callback(usbd_device *usbd_dev, usbd_set_altsetting_callback callback); +/** Registers a non-contiguous string descriptor */ +extern void usbd_register_extra_string(usbd_device *usbd_dev, int index, const char* string); + /* Functions to be provided by the hardware abstraction layer */ extern void usbd_poll(usbd_device *usbd_dev); diff --git a/lib/usb/usb.c b/lib/usb/usb.c index e2dd0c27..12bc431c 100644 --- a/lib/usb/usb.c +++ b/lib/usb/usb.c @@ -54,6 +54,8 @@ usbd_device *usbd_init(const usbd_driver *driver, usbd_dev->config = conf; usbd_dev->strings = strings; usbd_dev->num_strings = num_strings; + usbd_dev->extra_string_idx = 0; + usbd_dev->extra_string = NULL; usbd_dev->ctrl_buf = control_buffer; usbd_dev->ctrl_buf_len = control_buffer_size; @@ -94,6 +96,20 @@ void usbd_register_sof_callback(usbd_device *usbd_dev, void (*callback)(void)) usbd_dev->user_callback_sof = callback; } +void usbd_register_extra_string(usbd_device *usbd_dev, int index, const char* string) +{ + /* + * Note: string index 0 is reserved for LANGID requests and cannot + * be overwritten using this functionality. + */ + if (string != NULL && index > 0) { + usbd_dev->extra_string_idx = index; + usbd_dev->extra_string = string; + } else { + usbd_dev->extra_string_idx = 0; + } +} + void _usbd_reset(usbd_device *usbd_dev) { usbd_dev->current_address = 0; diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h index 3aa3f9ee..9e5e1181 100644 --- a/lib/usb/usb_private.h +++ b/lib/usb/usb_private.h @@ -92,6 +92,10 @@ struct _usbd_device { const struct _usbd_driver *driver; + /* Extra, non-contiguous user string descriptor index and value */ + int extra_string_idx; + const char* extra_string; + /* private driver data */ uint16_t fifo_mem_top; diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c index 4ce7a8b1..7057f2de 100644 --- a/lib/usb/usb_standard.c +++ b/lib/usb/usb_standard.c @@ -179,7 +179,21 @@ usb_standard_get_descriptor(usbd_device *usbd_dev, sizeof(sd->wData[0]); *len = MIN(*len, sd->bLength); - } else { + } else if (descr_idx == usbd_dev->extra_string_idx) { + /* This string is returned as UTF16, hence the + * multiplication + */ + sd->bLength = strlen(usbd_dev->extra_string) * 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->extra_string[i]; + } + } else { array_idx = descr_idx - 1; if (!usbd_dev->strings) { From a7902aa4d0f597f2b5821dfebceeffb39213d67f Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 23 Oct 2020 15:53:13 +0000 Subject: [PATCH 017/206] stm32l1: rcc/lcd: fix RTCSEL HSE definition Wrong since original commit in 2013. LCD code can't actually automatically determine clock speed if it's HSE, as we don't know here whether what HSE is, nor what it's divided by. For more fun, that old 2014 API doesn't have any way of flagging that it failed either. Hooray. --- include/libopencm3/stm32/l1/rcc.h | 2 +- lib/stm32/l1/lcd.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h index b688a34f..cf8a7197 100644 --- a/include/libopencm3/stm32/l1/rcc.h +++ b/include/libopencm3/stm32/l1/rcc.h @@ -430,7 +430,7 @@ #define RCC_CSR_RTCSEL_NONE (0x0) #define RCC_CSR_RTCSEL_LSE (0x1) #define RCC_CSR_RTCSEL_LSI (0x2) -#define RCC_CSR_RTCSEL_HSI (0x3) +#define RCC_CSR_RTCSEL_HSE (0x3) #define RCC_CSR_LSECSSD (1 << 12) #define RCC_CSR_LSECSSON (1 << 11) #define RCC_CSR_LSEBYP (1 << 10) diff --git a/lib/stm32/l1/lcd.c b/lib/stm32/l1/lcd.c index 68173ab8..b013735d 100644 --- a/lib/stm32/l1/lcd.c +++ b/lib/stm32/l1/lcd.c @@ -131,9 +131,9 @@ void lcd_set_refresh_frequency(uint32_t frequency) case RCC_CSR_RTCSEL_LSI: lcd_clock = 37000; break; - case RCC_CSR_RTCSEL_HSI: - lcd_clock = 16000000; - break; + case RCC_CSR_RTCSEL_HSE: + /* no current method of determining clock and divider! */ + return; default: /* RCC Clock not selected */ return; From 5f051241a87cd5b469e4f17083e23d4696b26d10 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 25 Oct 2020 17:33:34 +0000 Subject: [PATCH 018/206] stm32f1: rcc: provide struct based clock helpers As on every other family. Fixes: https://github.com/libopencm3/libopencm3/issues/1172 --- include/libopencm3/stm32/f1/rcc.h | 47 ++++++++ lib/stm32/f1/rcc.c | 186 ++++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+) diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index c3efced0..f0634641 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -704,6 +704,45 @@ enum rcc_periph_rst { #include +enum rcc_clock_hsi { + RCC_CLOCK_HSI_24MHZ, + RCC_CLOCK_HSI_48MHZ, + RCC_CLOCK_HSI_64MHZ, + RCC_CLOCK_HSI_END +}; + +enum rcc_clock_hse { + RCC_CLOCK_HSE12_72MHZ, + RCC_CLOCK_HSE16_72MHZ, + RCC_CLOCK_HSE25_72MHZ, + RCC_CLOCK_HSE8_24MHZ, + RCC_CLOCK_HSE8_72MHZ, + RCC_CLOCK_HSE_END +}; + +/* Union of all options for f100 through to f107 */ +struct rcc_clock_scale { + uint8_t pll_mul; + uint8_t pll_source; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + uint8_t adcpre; + uint8_t flash_waitstates; + uint8_t prediv1; /* aka xtpre, only one bit on smaller parts */ + uint8_t prediv1_source; + uint8_t prediv2; + uint8_t pll2_mul; + uint8_t pll3_mul; + uint8_t usbpre; + uint32_t ahb_frequency; + uint32_t apb1_frequency; + uint32_t apb2_frequency; +}; + +extern const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_HSI_END]; +extern const struct rcc_clock_scale rcc_hse_configs[RCC_CLOCK_HSE_END]; + BEGIN_DECLS void rcc_osc_ready_int_clear(enum rcc_osc osc); @@ -742,6 +781,14 @@ 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_clock_setup_in_hse_25mhz_out_72mhz(void); + +/** + * Switch sysclock to PLL with the given parameters. + * This should be usable from any point in time, but only if you have used + * library functions to manage clocks. + * @param clock full struct with desired parameters + */ +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); void rcc_backupdomain_reset(void); END_DECLS diff --git a/lib/stm32/f1/rcc.c b/lib/stm32/f1/rcc.c index ddd24e6a..78c4f840 100644 --- a/lib/stm32/f1/rcc.c +++ b/lib/stm32/f1/rcc.c @@ -58,6 +58,129 @@ uint32_t rcc_apb1_frequency = 8000000; uint32_t rcc_apb2_frequency = 8000000; uint32_t rcc_ahb_frequency = 8000000; +const struct rcc_clock_scale rcc_hse_configs[RCC_CLOCK_HSE_END] = { + { + /* hse-12, pll to 72 */ + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .pll_mul = RCC_CFGR_PLLMUL_PLL_CLK_MUL6, + .prediv1 = RCC_CFGR2_PREDIV_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV6, + .flash_waitstates = 2, + .ahb_frequency = 72000000, + .apb1_frequency = 36000000, + .apb2_frequency = 72000000, + }, + { + /* hse16, pll to 72 */ + .pll_mul = RCC_CFGR_PLLMUL_PLL_CLK_MUL9, + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV6, + .flash_waitstates = 2, + .prediv1 = RCC_CFGR2_PREDIV_DIV2, + .ahb_frequency = 72e6, + .apb1_frequency = 36e6, + .apb2_frequency = 72e6, + }, + { + /* hse25 to 72, this was a f105 config originally! intention preserved */ + .pll_mul = RCC_CFGR_PLLMUL_PLL_CLK_MUL9, + .pll_source = RCC_CFGR_PLLSRC_PREDIV1_CLK, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV6, + .flash_waitstates = 2, + .prediv1 = RCC_CFGR2_PREDIV_DIV5, + .prediv1_source = RCC_CFGR2_PREDIV1SRC_PLL2_CLK, + .pll2_mul = RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL8, + .prediv2 = RCC_CFGR2_PREDIV2_DIV5, + .usbpre = RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3, + .ahb_frequency = 72e6, + .apb1_frequency = 36e6, + .apb2_frequency = 72e6, + }, + { + /* hse8, pll to 24 (f100 value line max) */ + .pll_mul = RCC_CFGR_PLLMUL_PLL_CLK_MUL3, + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV2, + .flash_waitstates = 0, + .prediv1 = RCC_CFGR2_PREDIV_NODIV, + .ahb_frequency = 24e6, + .apb1_frequency = 24e6, + .apb2_frequency = 24e6, + }, + { + /* hse8, pll to 72 */ + .pll_mul = RCC_CFGR_PLLMUL_PLL_CLK_MUL9, + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV8, + .flash_waitstates = 2, + .prediv1 = RCC_CFGR2_PREDIV_NODIV, + .ahb_frequency = 72e6, + .apb1_frequency = 36e6, + .apb2_frequency = 72e6, + }, +}; + +const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_HSI_END] = { + { + /* hsi to 24Mhz, max for f100 */ + .pll_source = RCC_CFGR_PLLSRC_HSI_CLK_DIV2, + .pll_mul = RCC_CFGR_PLLMUL_PLL_CLK_MUL6, + .prediv1 = RCC_CFGR2_PREDIV_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV2, + .flash_waitstates = 0, + .ahb_frequency = 24e6, + .apb1_frequency = 24e6, + .apb2_frequency = 24e6, + }, + { + /* hsi to 48Mhz, allows usb, but out of spec */ + .pll_source = RCC_CFGR_PLLSRC_HSI_CLK_DIV2, + .pll_mul = RCC_CFGR_PLLMUL_PLL_CLK_MUL12, + .prediv1 = RCC_CFGR2_PREDIV_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV8, + .usbpre = RCC_CFGR_USBPRE_PLL_CLK_NODIV, + .flash_waitstates = 1, + .ahb_frequency = 48e6, + .apb1_frequency = 24e6, + .apb2_frequency = 48e6, + }, + { + /* hsi to 64Mhz, max possible from hsi */ + .pll_source = RCC_CFGR_PLLSRC_HSI_CLK_DIV2, + .pll_mul = RCC_CFGR_PLLMUL_PLL_CLK_MUL16, + .prediv1 = RCC_CFGR2_PREDIV_NODIV, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_DIV2, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .adcpre = RCC_CFGR_ADCPRE_DIV8, + .flash_waitstates = 2, + .ahb_frequency = 64e6, + .apb1_frequency = 32e6, + .apb2_frequency = 64e6, + }, +}; + /*---------------------------------------------------------------------------*/ /** @brief RCC Clear the Oscillator Ready Interrupt Flag @@ -1087,6 +1210,69 @@ void rcc_clock_setup_in_hse_25mhz_out_72mhz(void) rcc_apb2_frequency = 72000000; } +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) +{ + if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) { + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + } else { + rcc_osc_on(RCC_HSI); + rcc_wait_for_osc_ready(RCC_HSI); + } + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + rcc_set_adcpre(clock->adcpre); + rcc_set_usbpre(clock->usbpre); + flash_set_ws(clock->flash_waitstates); + + rcc_set_pll_multiplication_factor(clock->pll_mul); + rcc_set_pll_source(clock->pll_source); + + /* + * Magically handle F105/7 parts too. + * xtpre == prediv1 bit 0. + */ + if (clock->prediv1 > RCC_CFGR2_PREDIV_DIV2) { + rcc_set_prediv1(clock->prediv1); + } else { + rcc_set_pllxtpre(clock->prediv1); + } + if (clock->prediv1_source) { + rcc_set_prediv1_source(clock->prediv1_source); + } + + /* + * Magically handle other plls/prescalers on other parts + */ + if (clock->prediv2) { + rcc_set_prediv2(clock->prediv2); + } + if (clock->pll2_mul) { + rcc_set_pll2_multiplication_factor(clock->pll2_mul); + rcc_osc_on(RCC_PLL2); + rcc_wait_for_osc_ready(RCC_PLL2); + } + if (clock->pll3_mul) { + rcc_set_pll3_multiplication_factor(clock->pll3_mul); + rcc_osc_on(RCC_PLL3); + rcc_wait_for_osc_ready(RCC_PLL3); + } + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; +} + + /*---------------------------------------------------------------------------*/ /** @brief RCC Reset the Backup Domain From a9608c524f9e1b43fdb242532dda3943e4dbb488 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 25 Oct 2020 18:49:26 +0000 Subject: [PATCH 019/206] tests: stm32f1: use new clock struct routines --- tests/gadget-zero/main-stm32f103-generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gadget-zero/main-stm32f103-generic.c b/tests/gadget-zero/main-stm32f103-generic.c index 5e701dea..f6b502a0 100644 --- a/tests/gadget-zero/main-stm32f103-generic.c +++ b/tests/gadget-zero/main-stm32f103-generic.c @@ -35,7 +35,7 @@ int main(void) { - rcc_clock_setup_in_hse_8mhz_out_72mhz(); + rcc_clock_setup_pll(&rcc_hsi_configs[RCC_CLOCK_HSI_48MHZ]); /* LED to indicate boot process */ rcc_periph_clock_enable(RCC_GPIOC); gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, From 4eee1e9bdecf56bc2976c234dde6f5e177e0c69c Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 25 Oct 2020 18:49:40 +0000 Subject: [PATCH 020/206] stm32f1: rcc: mark old style static routines deprecated --- include/libopencm3/stm32/f1/rcc.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index f0634641..f497d110 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -773,14 +773,14 @@ void rcc_set_prediv1(uint32_t prediv); void rcc_set_prediv2(uint32_t prediv); void rcc_set_prediv1_source(uint32_t rccsrc); uint32_t rcc_system_clock_source(void); -void rcc_clock_setup_in_hsi_out_64mhz(void); -void rcc_clock_setup_in_hsi_out_48mhz(void); -void rcc_clock_setup_in_hsi_out_24mhz(void); -void rcc_clock_setup_in_hse_8mhz_out_24mhz(void); -void rcc_clock_setup_in_hse_8mhz_out_72mhz(void); -void rcc_clock_setup_in_hse_12mhz_out_72mhz(void); -void rcc_clock_setup_in_hse_16mhz_out_72mhz(void); -void rcc_clock_setup_in_hse_25mhz_out_72mhz(void); +void rcc_clock_setup_in_hsi_out_64mhz(void) LIBOPENCM3_DEPRECATED("use rcc_clock_setup_pll(&rcc_hsi_configs[RCC_CLOCK_HSI_64MHZ])"); +void rcc_clock_setup_in_hsi_out_48mhz(void) LIBOPENCM3_DEPRECATED("use rcc_clock_setup_pll(&rcc_hsi_configs[RCC_CLOCK_HSI_48MHZ])"); +void rcc_clock_setup_in_hsi_out_24mhz(void) LIBOPENCM3_DEPRECATED("use rcc_clock_setup_pll(&rcc_hsi_configs[RCC_CLOCK_HSI_24MHZ])"); +void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) LIBOPENCM3_DEPRECATED("use rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_24MHZ])"); +void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) LIBOPENCM3_DEPRECATED("use rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ])"); +void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) LIBOPENCM3_DEPRECATED("use rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE12_72MHZ])"); +void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) LIBOPENCM3_DEPRECATED("use rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE16_72MHZ])"); +void rcc_clock_setup_in_hse_25mhz_out_72mhz(void) LIBOPENCM3_DEPRECATED("use rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE25_72MHZ])"); /** * Switch sysclock to PLL with the given parameters. From 5968b8a85603d93efba7f6797eedbd9496bf7ca6 Mon Sep 17 00:00:00 2001 From: Lars Kruse Date: Tue, 24 Nov 2020 19:56:10 +0100 Subject: [PATCH 021/206] Update python references to python3 Python2 is end-of-life [1] since the 1st of January 2020. Some distributions (most notably: Debian and its derivatives) will stop providing a `python` executable in order to encourage users to specify the interpreter language of local scripts explicitly. Users of such environments will be forced to work around this in one of these ways: * create a virtual environment or * manipulate the shebangs of the scripts or * install the python2 package (as long as it is provided by distributions) All currently maintained distribution releases provide python3. In the near future distributions will need to remove python2, since it is not maintained anymore. PEP-394 [2] recommends to reference a specific python version (python2 or python3), if the script is not expected to run in a virtual environment. Closes: #1265 [1] https://www.python.org/dev/peps/pep-0373/#update-april-2014 [2] https://www.python.org/dev/peps/pep-0394/#for-python-script-publishers Amended-by: Karl Palsson * moved lpc43xx scripts to explicitly call python2, they have not been ported, and are effectively unmaintained, but switching them to python3 unconditionally would be unhelpful. --- README.md | 6 +++--- scripts/data/lpc43xx/csv2yaml.py | 2 +- scripts/data/lpc43xx/gen.py | 2 +- scripts/gendoxylayout.py | 2 +- scripts/genlink.py | 2 +- scripts/irq2nvic_h | 2 +- scripts/lpcvtcksum | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b0a42619..ba9819dc 100644 --- a/README.md +++ b/README.md @@ -62,12 +62,12 @@ Building requires Python (some code is generated). Download and install: - msys - http://sourceforge.net/projects/mingw/files/MSYS/Base/msys-core/msys-1.0.11/MSYS-1.0.11.exe - - Python - http://www.python.org/ftp/python/2.7/python-2.7.msi (any 2.7 release) + - Python - https://www.python.org/downloads/windows/ (any release) - arm-none-eabi/arm-elf toolchain (for example this one https://launchpad.net/gcc-arm-embedded) -Run msys shell and set the path without standard Windows paths, so Windows programs such as 'find' won't interfere: +Run msys shell and set the path without standard Windows paths (adjusting to your version of Python), so Windows programs such as 'find' won't interfere: - export PATH="/c//Python27:/c/ARMToolchain/bin:/usr/local/bin:/usr/bin:/bin" + export PATH="/c//Program Files/Python 3.9:/c/ARMToolchain/bin:/usr/local/bin:/usr/bin:/bin" After that you can navigate to the folder where you've extracted libopencm3 and build it. diff --git a/scripts/data/lpc43xx/csv2yaml.py b/scripts/data/lpc43xx/csv2yaml.py index 7b2f8c6d..f8918012 100755 --- a/scripts/data/lpc43xx/csv2yaml.py +++ b/scripts/data/lpc43xx/csv2yaml.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import sys import yaml diff --git a/scripts/data/lpc43xx/gen.py b/scripts/data/lpc43xx/gen.py index af253ddc..286b01ec 100755 --- a/scripts/data/lpc43xx/gen.py +++ b/scripts/data/lpc43xx/gen.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import sys import yaml diff --git a/scripts/gendoxylayout.py b/scripts/gendoxylayout.py index 24154958..5ae63ebb 100755 --- a/scripts/gendoxylayout.py +++ b/scripts/gendoxylayout.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # This python program generates parameters for the linker script generator feature. # This file is part of the libopencm3 project. diff --git a/scripts/genlink.py b/scripts/genlink.py index 96c27e08..9975b132 100755 --- a/scripts/genlink.py +++ b/scripts/genlink.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # This python program generates parameters for the linker script generator feature. # This file is part of the libopencm3 project. diff --git a/scripts/irq2nvic_h b/scripts/irq2nvic_h index 8a1c355c..dbd62018 100755 --- a/scripts/irq2nvic_h +++ b/scripts/irq2nvic_h @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # This file is part of the libopencm3 project. # diff --git a/scripts/lpcvtcksum b/scripts/lpcvtcksum index 27dc8a77..85dfe8b1 100755 --- a/scripts/lpcvtcksum +++ b/scripts/lpcvtcksum @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python2 # # Compute and insert the vector table checksum required for booting the # LPC43xx and some other NXP ARM microcontrollers. From 5d393b17a39d2d8f2ca548ae778b41c486d91c87 Mon Sep 17 00:00:00 2001 From: BOJIT <35117353+BOJIT@users.noreply.github.com> Date: Mon, 16 Nov 2020 19:30:54 +0000 Subject: [PATCH 022/206] ethernet: stm32: PTP naming fixes. Verify all hardware differences between F1 and F4/F7 Ethernet hardware. Flags registers missing on F1 as well. Reviewed-by: Karl Palsson --- include/libopencm3/ethernet/mac_stm32fxx7.h | 65 ++++++++++++--------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/include/libopencm3/ethernet/mac_stm32fxx7.h b/include/libopencm3/ethernet/mac_stm32fxx7.h index bac5e72f..8269fd77 100644 --- a/include/libopencm3/ethernet/mac_stm32fxx7.h +++ b/include/libopencm3/ethernet/mac_stm32fxx7.h @@ -58,8 +58,7 @@ #define ETH_MACVLANTR MMIO32(ETHERNET_BASE + 0x1C) #define ETH_MACRWUFFR MMIO32(ETHERNET_BASE + 0x28) #define ETH_MACPMTCSR MMIO32(ETHERNET_BASE + 0x2C) -/* not available on F1 ?*/ -#define ETH_MACDBGR MMIO32(ETHERNET_BASE + 0x34) +#define ETH_MACDBGR MMIO32(ETHERNET_BASE + 0x34) /* Not on STM32F1 */ #define ETH_MACSR MMIO32(ETHERNET_BASE + 0x38) #define ETH_MACIMR MMIO32(ETHERNET_BASE + 0x3C) @@ -81,7 +80,7 @@ #define ETH_MMCRFAECR MMIO32(ETHERNET_BASE + 0x198) #define ETH_MMCRGUFCR MMIO32(ETHERNET_BASE + 0x1C4) -/* Ethrenet IEEE 1588 time stamp registers */ +/* Ethernet IEEE 1588 time stamp registers */ #define ETH_PTPTSCR MMIO32(ETHERNET_BASE + 0x700) #define ETH_PTPSSIR MMIO32(ETHERNET_BASE + 0x704) #define ETH_PTPTSHR MMIO32(ETHERNET_BASE + 0x708) @@ -91,8 +90,8 @@ #define ETH_PTPTSAR MMIO32(ETHERNET_BASE + 0x718) #define ETH_PTPTTHR MMIO32(ETHERNET_BASE + 0x71C) #define ETH_PTPTTLR MMIO32(ETHERNET_BASE + 0x720) -/* not available on F1 ?*/ -#define ETH_PTPTSSR MMIO32(ETHERNET_BASE + 0x728) +#define ETH_PTPTSSR MMIO32(ETHERNET_BASE + 0x728) /* Not on STM32F1 */ +#define ETH_PTPPPSCR MMIO32(ETHERNET_BASE + 0x72C) /* Not on STM32F1 */ /* Ethernet DMA registers */ #define ETH_DMABMR MMIO32(ETHERNET_BASE + 0x1000) @@ -104,6 +103,7 @@ #define ETH_DMAOMR MMIO32(ETHERNET_BASE + 0x1018) #define ETH_DMAIER MMIO32(ETHERNET_BASE + 0x101C) #define ETH_DMAMFBOCR MMIO32(ETHERNET_BASE + 0x1020) +#define ETH_DMARSWTR MMIO32(ETHERNET_BASE + 0x1024) /* Not on STM32F1 */ #define ETH_DMACHTDR MMIO32(ETHERNET_BASE + 0x1048) #define ETH_DMACHRDR MMIO32(ETHERNET_BASE + 0x104C) #define ETH_DMACHTBAR MMIO32(ETHERNET_BASE + 0x1050) @@ -154,7 +154,7 @@ #define ETH_MACCR_JD (1<<22) #define ETH_MACCR_WD (1<<23) -#define ETH_MACCR_CSTF (1<<25) +#define ETH_MACCR_CSTF (1<<25) /* Not on STM32F1 */ /*---------------------------------------------------------------------------*/ /* MACFFR -------------------------------------------------------------------*/ @@ -247,6 +247,7 @@ /*---------------------------------------------------------------------------*/ /* MACDBGR -------------------------------------------------------------------*/ +/* Not on STM32F1 */ #define ETH_MACDBGR_MMRPEA (1<<0) #define ETH_MACDBGR_MSFRWCS (3<<1) #define ETH_MACDBGR_RFWRA (1<<4) @@ -331,8 +332,9 @@ #define ETH_MMCCR_CSR (1<<1) #define ETH_MMCCR_ROR (1<<2) #define ETH_MMCCR_MCF (1<<3) -#define ETH_MMCCR_MCP (1<<4) -#define ETH_MMCCR_MCFHP (1<<5) +#define ETH_MMCCR_MCP (1<<4) /* Not on STM32F1 */ +#define ETH_MMCCR_MCFHP (1<<5) /* Not on STM32F1 */ + /*---------------------------------------------------------------------------*/ /* MMCRIR -------------------------------------------------------------------*/ @@ -371,6 +373,8 @@ #define ETH_PTPTSCR_TSSTU (1<<3) #define ETH_PTPTSCR_TSITE (1<<4) #define ETH_PTPTSCR_TTSARU (1<<5) + +/* Not on STM32F1 */ #define ETH_PTPTSCR_TSSARFE (1<<8) #define ETH_PTPTSCR_TSSSR (1<<9) #define ETH_PTPTSCR_TSPTPPSV2E (1<<10) @@ -410,29 +414,33 @@ /*---------------------------------------------------------------------------*/ /* PTPTSSR ------------------------------------------------------------------*/ +/* Not on STM32F1 */ #define ETH_PTPTSSR_TSSO (1<<0) #define ETH_PTPTSSR_TSTTR (1<<1) -/*---------------------------------------------------------------------------*/ -/* PTPTSCR ------------------------------------------------------------------*/ -#define ETH_PTPTSCR_PPSFREQ (0x0F<<0) -#define ETH_PTPTSCR_PPSFREQ_1HZ (0x00<<0) -#define ETH_PTPTSCR_PPSFREQ_2HZ (0x01<<0) -#define ETH_PTPTSCR_PPSFREQ_4HZ (0x02<<0) -#define ETH_PTPTSCR_PPSFREQ_8HZ (0x03<<0) -#define ETH_PTPTSCR_PPSFREQ_16HZ (0x04<<0) -#define ETH_PTPTSCR_PPSFREQ_32HZ (0x05<<0) -#define ETH_PTPTSCR_PPSFREQ_64HZ (0x06<<0) -#define ETH_PTPTSCR_PPSFREQ_128HZ (0x07<<0) -#define ETH_PTPTSCR_PPSFREQ_256HZ (0x08<<0) -#define ETH_PTPTSCR_PPSFREQ_512HZ (0x09<<0) -#define ETH_PTPTSCR_PPSFREQ_1024HZ (0x0A<<0) -#define ETH_PTPTSCR_PPSFREQ_2048HZ (0x0B<<0) -#define ETH_PTPTSCR_PPSFREQ_4096HZ (0x0C<<0) -#define ETH_PTPTSCR_PPSFREQ_8192HZ (0x0D<<0) -#define ETH_PTPTSCR_PPSFREQ_16384HZ (0x0E<<0) -#define ETH_PTPTSCR_PPSFREQ_32768HZ (0x0F<<0) +/*---------------------------------------------------------------------------*/ +/* PTPPPSCR -----------------------------------------------------------------*/ + +/* Not on STM32F1 */ +#define ETH_PTPPPSCR_PPSFREQ_MASK (0x0F<<0) +#define ETH_PTPPPSCR_PPSFREQ_1HZ (0x00<<0) +#define ETH_PTPPPSCR_PPSFREQ_2HZ (0x01<<0) +#define ETH_PTPPPSCR_PPSFREQ_4HZ (0x02<<0) +#define ETH_PTPPPSCR_PPSFREQ_8HZ (0x03<<0) +#define ETH_PTPPPSCR_PPSFREQ_16HZ (0x04<<0) +#define ETH_PTPPPSCR_PPSFREQ_32HZ (0x05<<0) +#define ETH_PTPPPSCR_PPSFREQ_64HZ (0x06<<0) +#define ETH_PTPPPSCR_PPSFREQ_128HZ (0x07<<0) +#define ETH_PTPPPSCR_PPSFREQ_256HZ (0x08<<0) +#define ETH_PTPPPSCR_PPSFREQ_512HZ (0x09<<0) +#define ETH_PTPPPSCR_PPSFREQ_1024HZ (0x0A<<0) +#define ETH_PTPPPSCR_PPSFREQ_2048HZ (0x0B<<0) +#define ETH_PTPPPSCR_PPSFREQ_4096HZ (0x0C<<0) +#define ETH_PTPPPSCR_PPSFREQ_8192HZ (0x0D<<0) +#define ETH_PTPPPSCR_PPSFREQ_16384HZ (0x0E<<0) +#define ETH_PTPPPSCR_PPSFREQ_32768HZ (0x0F<<0) + /*---------------------------------------------------------------------------*/ /* DMABMR -------------------------------------------------------------------*/ @@ -463,7 +471,7 @@ #define ETH_DMABMR_USP (1<<23) #define ETH_DMABMR_FPM (1<<24) #define ETH_DMABMR_AAB (1<<25) -#define ETH_DMABMR_MB (1<<26) +#define ETH_DMABMR_MB (1<<26) /* Not on STM32F1 */ /*---------------------------------------------------------------------------*/ /* DMASR --------------------------------------------------------------------*/ @@ -574,6 +582,7 @@ /*---------------------------------------------------------------------------*/ /* DMARSWTR -----------------------------------------------------------------*/ +/* Not on STM32F1 */ #define ETH_DMARSWTR_RSWTC 0xFF /*---------------------------------------------------------------------------*/ From c49b4d35c2b209fc231257e6a6c7efa0cf836fec Mon Sep 17 00:00:00 2001 From: Matthew Lai Date: Wed, 22 Aug 2018 00:42:19 +0100 Subject: [PATCH 023/206] stm32f7: added USB OTG FS/HS Originally tracked at https://github.com/libopencm3/libopencm3/pull/958 While it doesn't work for everyone, this is clearly the basic first steps required for any progress to be made. Reviewed-by: Karl Palsson --- include/libopencm3/usb/dwc/otg_fs.h | 2 +- include/libopencm3/usb/dwc/otg_hs.h | 2 +- lib/stm32/f7/Makefile | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/libopencm3/usb/dwc/otg_fs.h b/include/libopencm3/usb/dwc/otg_fs.h index 4510a849..b947774c 100644 --- a/include/libopencm3/usb/dwc/otg_fs.h +++ b/include/libopencm3/usb/dwc/otg_fs.h @@ -28,7 +28,7 @@ #include /* Memory map is required for USB_OTG_FS_BASE address */ -#if defined(STM32F1) || defined(STM32F2) || defined(STM32F4) || defined(STM32L4) +#if defined(STM32F1) || defined(STM32F2) || defined(STM32F4) || defined(STM32F7) || defined(STM32L4) # include #elif defined(EFM32HG) # include diff --git a/include/libopencm3/usb/dwc/otg_hs.h b/include/libopencm3/usb/dwc/otg_hs.h index 7b5124cd..eee8a7e6 100644 --- a/include/libopencm3/usb/dwc/otg_hs.h +++ b/include/libopencm3/usb/dwc/otg_hs.h @@ -28,7 +28,7 @@ #include /* Memory map is required for USB_OTG_HS_BASE address */ -#if defined(STM32F2) || defined(STM32F4) +#if defined(STM32F2) || defined(STM32F4) || defined(STM32F7) # include #else # error "device family not supported by dwc/otg_hs." diff --git a/lib/stm32/f7/Makefile b/lib/stm32/f7/Makefile index 30c6c44b..30178f9b 100644 --- a/lib/stm32/f7/Makefile +++ b/lib/stm32/f7/Makefile @@ -66,6 +66,9 @@ OBJS += usart_common_all.o usart_common_v2.o # Ethernet OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz80x1.o +OBJS += usb.o usb_standard.o usb_control.o usb_dwc_common.o \ + usb_f107.o usb_f207.o usb_msc.o + VPATH += ../../usb:../:../../cm3:../common VPATH += ../../ethernet From 174d3400dd91876bf964a537a9859a861cb998dc Mon Sep 17 00:00:00 2001 From: Caleb Szalacinski Date: Sun, 31 May 2020 22:41:01 -0500 Subject: [PATCH 024/206] Update checkpatch.pl with changes to the Linux Kernel Coding Style The Linux kernel just deprecated the 80 character line limit. This was always a mild issue of mine because of operations on lengthily-named registers that go just over the 80 character limit. https://www.phoronix.com/scan.php?page=news_item&px=Linux-Kernel-Deprecates-80-Col --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 54026fb9..87bf0560 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -33,7 +33,7 @@ my %ignore_type = (); my @ignore = (); my $help = 0; my $configuration_file = ".checkpatch.conf"; -my $max_line_length = 80; +my $max_line_length = 100; sub help { my ($exitcode) = @_; From b47d7693697754ab6916b578b034761be80eb74a Mon Sep 17 00:00:00 2001 From: tute-avalos Date: Fri, 3 Jul 2020 00:21:48 -0300 Subject: [PATCH 025/206] stm32: uart: Add Trasmission Complete enable/disable interrupt functions --- .../stm32/common/usart_common_all.h | 2 ++ lib/stm32/common/usart_common_all.c | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/libopencm3/stm32/common/usart_common_all.h b/include/libopencm3/stm32/common/usart_common_all.h index a39d6833..5a41684b 100644 --- a/include/libopencm3/stm32/common/usart_common_all.h +++ b/include/libopencm3/stm32/common/usart_common_all.h @@ -120,6 +120,8 @@ void usart_enable_rx_interrupt(uint32_t usart); void usart_disable_rx_interrupt(uint32_t usart); void usart_enable_tx_interrupt(uint32_t usart); void usart_disable_tx_interrupt(uint32_t usart); +void usart_enable_tx_complete_interrupt(uint32_t usart); +void usart_disable_tx_complete_interrupt(uint32_t usart); void usart_enable_error_interrupt(uint32_t usart); void usart_disable_error_interrupt(uint32_t usart); bool usart_get_flag(uint32_t usart, uint32_t flag); diff --git a/lib/stm32/common/usart_common_all.c b/lib/stm32/common/usart_common_all.c index 2c7e9a6d..3565e802 100644 --- a/lib/stm32/common/usart_common_all.c +++ b/lib/stm32/common/usart_common_all.c @@ -350,6 +350,32 @@ void usart_disable_tx_interrupt(uint32_t usart) USART_CR1(usart) &= ~USART_CR1_TXEIE; } +/*---------------------------------------------------------------------------*/ +/** + * @brief USART Transmission Complete Interrupt Enable + * + * @param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base + */ + +void usart_enable_tx_complete_interrupt(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_TCIE; +} + +/*---------------------------------------------------------------------------*/ +/** + * @brief USART Transmission Complete Interrupt Disable + * + * @param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base + */ + +void usart_disable_tx_complete_interrupt(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_TCIE; +} + /*---------------------------------------------------------------------------*/ /** @brief USART Error Interrupt Enable. From 1c54d58c817facf3988055e4d5b89a094f94ba86 Mon Sep 17 00:00:00 2001 From: Matt Walker Date: Thu, 6 Aug 2020 16:28:45 -0400 Subject: [PATCH 026/206] STM32H7: Support the RNG Peripheral The random number generator on the STM32H7 is identical to the v1 RNG already present in the library. So use that, and make sure that the RCC knows about the peripheral. Originally filed at: https://github.com/libopencm3/libopencm3/pull/1244 Reviewed-by: Karl Palsson * whitespace changes from review --- include/libopencm3/stm32/h7/rcc.h | 11 +++++++++++ include/libopencm3/stm32/h7/rng.h | 23 +++++++++++++++++++++++ include/libopencm3/stm32/rng.h | 2 ++ lib/stm32/h7/Makefile | 1 + lib/stm32/h7/rcc.c | 10 ++++++++++ 5 files changed, 47 insertions(+) create mode 100644 include/libopencm3/stm32/h7/rng.h diff --git a/include/libopencm3/stm32/h7/rcc.h b/include/libopencm3/stm32/h7/rcc.h index 0612b3f5..8593d076 100644 --- a/include/libopencm3/stm32/h7/rcc.h +++ b/include/libopencm3/stm32/h7/rcc.h @@ -394,6 +394,7 @@ LGPL License Terms @ref lgpl_license #define RCC_D2CCIP2R_CECSEL_SHIFT 22 #define RCC_D2CCIP2R_USBSEL_SHIFT 20 #define RCC_D2CCIP2R_I2C123SEL_SHIFT 12 +#define RCC_D2CCIP2R_RNGSEL_MASK 0x3 #define RCC_D2CCIP2R_RNGSEL_SHIFT 8 #define RCC_D2CCIP2R_USART16SEL_SHIFT 3 #define RCC_D2CCIP2R_USART234578SEL_SHIFT 0 @@ -402,6 +403,10 @@ LGPL License Terms @ref lgpl_license /** @defgroup rcc_d2ccip2r_values RCC_D2CCIP2R Values * @ingroup rcc_registers * @{*/ +#define RCC_D2CCIP2R_RNGSEL_HSI48 0 +#define RCC_D2CCIP2R_RNGSEL_PLL1Q 1 +#define RCC_D2CCIP2R_RNGSEL_LSE 2 +#define RCC_D2CCIP2R_RNGSEL_LSI 3 #define RCC_D2CCIP2R_USART16SEL_PCLK2 0 #define RCC_D2CCIP2R_USART234578SEL_PCLK1 0 #define RCC_D2CCIP2R_USARTSEL_PLL2Q 1 @@ -774,6 +779,12 @@ void rcc_set_spi123_clksel(uint8_t clksel); */ void rcc_set_spi45_clksel(uint8_t clksel); +/** + * Set the clock select for the RNG device. + * @param[in] clksel Clock source to configure for. @ref rcc_d2ccip2r_values + * @sa rcc_set_peripheral_clk_sel for equivalent generic functionality + */ +void rcc_set_rng_clksel(uint8_t clksel); END_DECLS /**@}*/ diff --git a/include/libopencm3/stm32/h7/rng.h b/include/libopencm3/stm32/h7/rng.h new file mode 100644 index 00000000..09d014d1 --- /dev/null +++ b/include/libopencm3/stm32/h7/rng.h @@ -0,0 +1,23 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RNG_H +#define LIBOPENCM3_RNG_H + +#include + +#endif diff --git a/include/libopencm3/stm32/rng.h b/include/libopencm3/stm32/rng.h index 58878c71..01f1b104 100644 --- a/include/libopencm3/stm32/rng.h +++ b/include/libopencm3/stm32/rng.h @@ -26,6 +26,8 @@ # include #elif defined(STM32F7) # include +#elif defined(STM32H7) +# include #elif defined(STM32L0) # include #elif defined(STM32L4) diff --git a/lib/stm32/h7/Makefile b/lib/stm32/h7/Makefile index 181ec524..737c2fc7 100644 --- a/lib/stm32/h7/Makefile +++ b/lib/stm32/h7/Makefile @@ -44,6 +44,7 @@ OBJS += fmc_common_f47.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += pwr.o rcc.o OBJS += rcc_common_all.o +OBJS += rng_common_v1.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o OBJS += usart_common_v2.o usart_common_fifos.o diff --git a/lib/stm32/h7/rcc.c b/lib/stm32/h7/rcc.c index 4a24f7ec..0977ebdf 100644 --- a/lib/stm32/h7/rcc.c +++ b/lib/stm32/h7/rcc.c @@ -361,6 +361,11 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel) { mask = RCC_D2CCIP1R_FDCANSEL_MASK << RCC_D2CCIP1R_FDCANSEL_SHIFT; val = sel << RCC_D2CCIP1R_FDCANSEL_SHIFT; break; + case RNG_BASE: + reg = &RCC_D2CCIP2R; + mask = RCC_D2CCIP2R_RNGSEL_MASK << RCC_D2CCIP2R_RNGSEL_SHIFT; + val = sel << RCC_D2CCIP2R_RNGSEL_SHIFT; + break; case SPI1_BASE: case SPI2_BASE: case SPI3_BASE: @@ -406,6 +411,11 @@ void rcc_set_fdcan_clksel(uint8_t clksel) { RCC_D2CCIP1R |= clksel << RCC_D2CCIP1R_FDCANSEL_SHIFT; } +void rcc_set_rng_clksel(uint8_t clksel) { + RCC_D2CCIP2R &= ~(RCC_D2CCIP2R_RNGSEL_MASK << RCC_D2CCIP2R_RNGSEL_SHIFT); + RCC_D2CCIP2R |= clksel << RCC_D2CCIP2R_RNGSEL_SHIFT; +} + void rcc_set_spi123_clksel(uint8_t clksel) { RCC_D2CCIP1R &= ~(RCC_D2CCIP1R_SPI123SEL_MASK << RCC_D2CCIP1R_SPI123SEL_SHIFT); RCC_D2CCIP1R |= clksel << RCC_D2CCIP1R_SPI123SEL_SHIFT; From d8d63b3184f38199f8b58f5a7b8c0959a861a94d Mon Sep 17 00:00:00 2001 From: Themroc Date: Tue, 4 Aug 2020 18:48:50 +0200 Subject: [PATCH 027/206] stm32: timer common all: Fix documentation Provide gpio examples for both f1 and "everyone else" gpio blocks Originally filed at: https://github.com/libopencm3/libopencm3/pull/1243 Reviewed-by: Karl Palsson (Merged old and new into two new examples) --- lib/stm32/common/timer_common_all.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/stm32/common/timer_common_all.c b/lib/stm32/common/timer_common_all.c index 64701836..30671ad1 100644 --- a/lib/stm32/common/timer_common_all.c +++ b/lib/stm32/common/timer_common_all.c @@ -44,14 +44,20 @@ Output Compare mode to PWM and enable the output of channel 1. Note that for the advanced timers the break functionality must be enabled before the signal will appear at the output, even though break is not being used. This is in addition to the normal output enable. Enable the alternate function clock (APB2 -only) and port A clock. Set ports A8 and A9 (timer 1 channel 1 compare outputs) -to alternate function push-pull outputs where the PWM output will appear. +only) and port A clock. Set port A8 (timer 1 channel 1 compare output) to +alternate function push-pull output where the PWM output will appear. @code - rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_TIM1); - gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, - GPIO_OSPEED_50MHZ, GPIO8 | GPIO9); + rcc_periph_clock_enable(RCC_GPIOA); + + // for F1.... + gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO8); + // For anyone else + rcc_periph_clock_enable(RCC_AFIO); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8); + // End of family specific + rcc_periph_clock_enable(RCC_TIM1); timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_CENTER_1, TIM_CR1_DIR_UP); From 2a4cf034c75de55fbc5a27d15d3bfc1b45645f14 Mon Sep 17 00:00:00 2001 From: Fabio Pugliese Ornellas Date: Mon, 23 Mar 2020 23:31:29 +0000 Subject: [PATCH 028/206] usb: dwc_otg: Add OTG_DSTS_SUSPSTS Originally filed as: https://github.com/libopencm3/libopencm3/pull/1224 Reviewed-by: Karl Palsson --- include/libopencm3/usb/dwc/otg_common.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/libopencm3/usb/dwc/otg_common.h b/include/libopencm3/usb/dwc/otg_common.h index 8a703713..56483f6e 100644 --- a/include/libopencm3/usb/dwc/otg_common.h +++ b/include/libopencm3/usb/dwc/otg_common.h @@ -253,6 +253,9 @@ #define OTG_DCFG_DAD 0x07F0 #define OTG_DCFG_PFIVL 0x1800 +/* OTG device status register (OTG_DSTS) */ +#define OTG_DSTS_SUSPSTS (1 << 0) + /* OTG Device IN Endpoint Common Interrupt Mask Register (OTG_DIEPMSK) */ /* Bits 31:10 - Reserved */ #define OTG_DIEPMSK_BIM (1 << 9) From 05f07c1051621806df3e224573333c0f9bc60015 Mon Sep 17 00:00:00 2001 From: Ben Brewer Date: Fri, 22 May 2020 11:25:32 +0100 Subject: [PATCH 029/206] stm32f3: Add support for OPAMP --- include/libopencm3/stm32/f3/opamp.h | 193 ++++++++++++++++++++++++++++ include/libopencm3/stm32/opamp.h | 27 ++++ lib/stm32/f3/Makefile | 1 + lib/stm32/f3/opamp.c | 156 ++++++++++++++++++++++ 4 files changed, 377 insertions(+) create mode 100644 include/libopencm3/stm32/f3/opamp.h create mode 100644 include/libopencm3/stm32/opamp.h create mode 100644 lib/stm32/f3/opamp.c diff --git a/include/libopencm3/stm32/f3/opamp.h b/include/libopencm3/stm32/f3/opamp.h new file mode 100644 index 00000000..54f2d422 --- /dev/null +++ b/include/libopencm3/stm32/f3/opamp.h @@ -0,0 +1,193 @@ +/** @defgroup opamp_defines OPAMP Defines + * + * @brief libopencm3 Defined Constants and Types for the STM32F3xx + * Operational Amplifier module + * + * @ingroup STM32F3xx_defines + * + * @version 1.0.0 + * + * @date 22 May 2020 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_OPAMP_H +#define LIBOPENCM3_OPAMP_H +/**@{*/ + +#define OPAMP1 (OPAMP_BASE + 0x38) +#define OPAMP2 (OPAMP_BASE + 0x3C) +#define OPAMP3 (OPAMP_BASE + 0x40) +#define OPAMP4 (OPAMP_BASE + 0x44) + +/* OpAmp registers */ + +/* Control and status register (OPAMPx_CSR) */ +#define OPAMP_CSR(opamp_base) MMIO32((opamp_base) + 0x00) +#define OPAMP1_CSR OPAMP_CSR(OPAMP1) +#define OPAMP2_CSR OPAMP_CSR(OPAMP2) +#define OPAMP3_CSR OPAMP_CSR(OPAMP3) +#define OPAMP4_CSR OPAMP_CSR(OPAMP4) + +/* OPAMPx_CSR values */ + +#define OPAMP_CSR_LOCK (0x1 << 31) + +#define OPAMP_CSR_OUTCAL_MASK (0x1) +#define OPAMP_CSR_OUTCAL_SHIFT (30) +#define OPAMP_CSR_OUTCAL_NON_LO_INV (0x0) +#define OPAMP_CSR_OUTCAL_NON_HI_INV (0x1) + +#define OPAMP_CSR_TSTREF (0x1 << 29) + +#define OPAMP_CSR_TRIMOFFSETN_MASK (0x1f) +#define OPAMP_CSR_TRIMOFFSETN_SHIFT (24) + +#define OPAMP_CSR_TRIMOFFSETP_MASK (0x1f) +#define OPAMP_CSR_TRIMOFFSETP_SHIFT (19) + +#define OPAMP_CSR_USER_TRIM (0x1 << 18) + +#define OPAMP_CSR_PGA_GAIN_MASK (0xf) +#define OPAMP_CSR_PGA_GAIN_SHIFT (14) +#define OPAMP_CSR_PGA_GAIN_2 (0x0) +#define OPAMP_CSR_PGA_GAIN_4 (0x1) +#define OPAMP_CSR_PGA_GAIN_8 (0x2) +#define OPAMP_CSR_PGA_GAIN_16 (0x3) +#define OPAMP_CSR_PGA_GAIN_2_MINUS_VM0 (0x8) +#define OPAMP_CSR_PGA_GAIN_4_MINUS_VM0 (0x9) +#define OPAMP_CSR_PGA_GAIN_8_MINUS_VM0 (0xa) +#define OPAMP_CSR_PGA_GAIN_16_MINUS_VM0 (0xb) +#define OPAMP_CSR_PGA_GAIN_2_MINUS_VM1 (0xc) +#define OPAMP_CSR_PGA_GAIN_4_MINUS_VM1 (0xd) +#define OPAMP_CSR_PGA_GAIN_8_MINUS_VM1 (0xe) +#define OPAMP_CSR_PGA_GAIN_16_MINUS_VM1 (0xf) + +#define OPAMP_CSR_CALSEL_MASK (0x3) +#define OPAMP_CSR_CALSEL_SHIFT (12) +#define OPAMP_CSR_CALSEL_3P3_PERCENT (0x0) +#define OPAMP_CSR_CALSEL_10_PERCENT (0x1) +#define OPAMP_CSR_CALSEL_50_PERCENT (0x2) +#define OPAMP_CSR_CALSEL_90_PERCENT (0x3) + +#define OPAMP_CSR_CALON (0x1 << 11) + +#define OPAMP_CSR_VPS_SEL_MASK (0x3) +#define OPAMP_CSR_VPS_SEL_SHIFT (9) +#define OPAMP1_CSR_VPS_SEL_PA7 (0x0) +#define OPAMP1_CSR_VPS_SEL_PA5 (0x1) +#define OPAMP1_CSR_VPS_SEL_PA3 (0x2) +#define OPAMP1_CSR_VPS_SEL_PA1 (0x3) +#define OPAMP2_CSR_VPS_SEL_PD14 (0x0) +#define OPAMP2_CSR_VPS_SEL_PB14 (0x1) +#define OPAMP2_CSR_VPS_SEL_PB0 (0x2) +#define OPAMP2_CSR_VPS_SEL_PA7 (0x3) +#define OPAMP3_CSR_VPS_SEL_PB13 (0x0) +#define OPAMP3_CSR_VPS_SEL_PA5 (0x1) +#define OPAMP3_CSR_VPS_SEL_PA1 (0x2) +#define OPAMP3_CSR_VPS_SEL_PB0 (0x3) +#define OPAMP4_CSR_VPS_SEL_PD11 (0x0) +#define OPAMP4_CSR_VPS_SEL_PB11 (0x1) +#define OPAMP4_CSR_VPS_SEL_PA4 (0x2) +#define OPAMP4_CSR_VPS_SEL_PB13 (0x3) + +#define OPAMP_CSR_VMS_SEL_MASK (0x1) +#define OPAMP_CSR_VMS_SEL_SHIFT (8) +#define OPAMP1_CSR_VMS_SEL_PC5 (0x0) +#define OPAMP1_CSR_VMS_SEL_PA3 (0x1) +#define OPAMP2_CSR_VMS_SEL_PC5 (0x0) +#define OPAMP2_CSR_VMS_SEL_PA5 (0x1) +#define OPAMP3_CSR_VMS_SEL_PB10 (0x0) +#define OPAMP3_CSR_VMS_SEL_PB2 (0x1) +#define OPAMP4_CSR_VMS_SEL_PB10 (0x0) +#define OPAMP4_CSR_VMS_SEL_PD8 (0x1) + +#define OPAMP_CSR_TCM_EN (0x1 << 7) + +#define OPAMP_CSR_VM_SEL_MASK (0x3) +#define OPAMP_CSR_VM_SEL_SHIFT (5) +#define OPAMP_CSR_VM_SEL_PGA_MODE (0x2) +#define OPAMP_CSR_VM_SEL_FOLLOWER_MODE (0x3) +#define OPAMP1_CSR_VM_SEL_PC5 (0x0) +#define OPAMP1_CSR_VM_SEL_PA3 (0x1) +#define OPAMP2_CSR_VM_SEL_PC5 (0x0) +#define OPAMP2_CSR_VM_SEL_PA5 (0x1) +#define OPAMP3_CSR_VM_SEL_PB10 (0x0) +#define OPAMP3_CSR_VM_SEL_PB2 (0x1) +#define OPAMP4_CSR_VM_SEL_PB10 (0x0) +#define OPAMP4_CSR_VM_SEL_PD8 (0x1) + +#define OPAMP_CSR_VP_SEL_MASK (0x3) +#define OPAMP_CSR_VP_SEL_SHIFT (2) +#define OPAMP1_CSR_VP_SEL_PA7 (0x0) +#define OPAMP1_CSR_VP_SEL_PA5 (0x1) +#define OPAMP1_CSR_VP_SEL_PA3 (0x2) +#define OPAMP1_CSR_VP_SEL_PA1 (0x3) +#define OPAMP2_CSR_VP_SEL_PD14 (0x0) +#define OPAMP2_CSR_VP_SEL_PB14 (0x1) +#define OPAMP2_CSR_VP_SEL_PB0 (0x2) +#define OPAMP2_CSR_VP_SEL_PA7 (0x3) +#define OPAMP3_CSR_VP_SEL_PB13 (0x0) +#define OPAMP3_CSR_VP_SEL_PA5 (0x1) +#define OPAMP3_CSR_VP_SEL_PA1 (0x2) +#define OPAMP3_CSR_VP_SEL_PB0 (0x3) +#define OPAMP4_CSR_VP_SEL_PD11 (0x0) +#define OPAMP4_CSR_VP_SEL_PB11 (0x1) +#define OPAMP4_CSR_VP_SEL_PA4 (0x2) +#define OPAMP4_CSR_VP_SEL_PB13 (0x3) + +#define OPAMP_CSR_FORCE_VP (0x1 << 1) +#define OPAMP_CSR_EN (0x1 << 0) + + +BEGIN_DECLS + +void opamp_enable(uint32_t base); +void opamp_disable(uint32_t base); +void opamp_lock(uint32_t base); + +void opamp_set_calsel(uint32_t base, uint32_t calsel); +bool opamp_read_outcal(uint32_t base); +void opamp_tstref_enable(uint32_t base); +void opamp_tstref_disable(uint32_t base); +void opamp_force_vp_enable(uint32_t base); +void opamp_force_vp_disable(uint32_t base); +void opamp_cal_enable(uint32_t base); +void opamp_cal_disable(uint32_t base); + +void opamp_trimoffsetn_set(uint32_t base, uint32_t trim); +void opamp_trimoffsetp_set(uint32_t base, uint32_t trim); +void opamp_user_trim_enable(uint32_t base); +void opamp_user_trim_disable(uint32_t base); + +void opamp_pga_gain_select(uint32_t base, uint32_t gain); + +void opamp_vp_select(uint32_t base, uint32_t vp); +void opamp_vm_select(uint32_t base, uint32_t vm); + +void opamp_vps_select(uint32_t base, uint32_t vps); +void opamp_vms_select(uint32_t base, uint32_t vms); +void opamp_tcm_enable(uint32_t base); +void opamp_tcm_disable(uint32_t base); + +END_DECLS + +/**@}*/ +#endif diff --git a/include/libopencm3/stm32/opamp.h b/include/libopencm3/stm32/opamp.h new file mode 100644 index 00000000..bde4a3a6 --- /dev/null +++ b/include/libopencm3/stm32/opamp.h @@ -0,0 +1,27 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32F3) +# include +#else +# error "stm32 family not defined." +#endif diff --git a/lib/stm32/f3/Makefile b/lib/stm32/f3/Makefile index 6f768322..f3aa1698 100644 --- a/lib/stm32/f3/Makefile +++ b/lib/stm32/f3/Makefile @@ -46,6 +46,7 @@ OBJS += flash.o flash_common_all.o flash_common_f.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += i2c_common_v2.o OBJS += iwdg_common_all.o +OBJS += opamp.o OBJS += pwr_common_v1.o OBJS += rcc.o rcc_common_all.o OBJS += spi_common_all.o spi_common_v2.o diff --git a/lib/stm32/f3/opamp.c b/lib/stm32/f3/opamp.c new file mode 100644 index 00000000..702e8eb0 --- /dev/null +++ b/lib/stm32/f3/opamp.c @@ -0,0 +1,156 @@ +/** @defgroup opamp_file OPAMP + * + * @ingroup STM32F3xx + * + * @brief libopencm3 STM32F3xx OPAMP + * + * @version 1.0.0 + * + * @date 22 May 2020 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#include + +void opamp_enable(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_EN; +} + +void opamp_disable(uint32_t base) +{ + OPAMP_CSR(base) &= ~OPAMP_CSR_EN; +} + +void opamp_lock(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_LOCK; +} + + +void opamp_set_calsel(uint32_t base, uint32_t calsel) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_CALSEL_MASK << OPAMP_CSR_CALSEL_SHIFT); + OPAMP_CSR(base) |= calsel << OPAMP_CSR_CALSEL_SHIFT; +} + +bool opamp_read_outcal(uint32_t base) +{ + return (OPAMP_CSR(base) >> OPAMP_CSR_OUTCAL_SHIFT) + & OPAMP_CSR_OUTCAL_MASK; +} + +void opamp_tcm_enable(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_TCM_EN; +} + +void opamp_tcm_disable(uint32_t base) +{ + OPAMP_CSR(base) &= ~OPAMP_CSR_TCM_EN; +} + +void opamp_force_vp_enable(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_FORCE_VP; +} + +void opamp_force_vp_disable(uint32_t base) +{ + OPAMP_CSR(base) &= ~OPAMP_CSR_FORCE_VP; +} + +void opamp_cal_enable(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_CALON; +} + +void opamp_cal_disable(uint32_t base) +{ + OPAMP_CSR(base) &= ~OPAMP_CSR_CALON; +} + + +void opamp_trimoffsetn_set(uint32_t base, uint32_t trim) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_TRIMOFFSETN_MASK + << OPAMP_CSR_TRIMOFFSETN_SHIFT); + OPAMP_CSR(base) |= trim << OPAMP_CSR_TRIMOFFSETN_SHIFT; +} + +void opamp_trimoffsetp_set(uint32_t base, uint32_t trim) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_TRIMOFFSETP_MASK + << OPAMP_CSR_TRIMOFFSETP_SHIFT); + OPAMP_CSR(base) |= trim << OPAMP_CSR_TRIMOFFSETP_SHIFT; +} + +void opamp_user_trim_enable(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_USER_TRIM; +} + +void opamp_user_trim_disable(uint32_t base) +{ + OPAMP_CSR(base) &= ~OPAMP_CSR_USER_TRIM; +} + + +void opamp_pga_gain_select(uint32_t base, uint32_t gain) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_PGA_GAIN_MASK + << OPAMP_CSR_PGA_GAIN_SHIFT); + OPAMP_CSR(base) |= gain << OPAMP_CSR_PGA_GAIN_SHIFT; +} + + +void opamp_vp_select(uint32_t base, uint32_t vp) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_VP_SEL_MASK + << OPAMP_CSR_VP_SEL_SHIFT); + OPAMP_CSR(base) |= vp << OPAMP_CSR_VP_SEL_SHIFT; +} + +void opamp_vm_select(uint32_t base, uint32_t vm) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_VM_SEL_MASK + << OPAMP_CSR_VM_SEL_SHIFT); + OPAMP_CSR(base) |= vm << OPAMP_CSR_VM_SEL_SHIFT; +} + + +void opamp_vps_select(uint32_t base, uint32_t vps) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_VPS_SEL_MASK + << OPAMP_CSR_VPS_SEL_SHIFT); + OPAMP_CSR(base) |= vps << OPAMP_CSR_VPS_SEL_SHIFT; +} + +void opamp_vms_select(uint32_t base, uint32_t vms) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_VMS_SEL_MASK + << OPAMP_CSR_VMS_SEL_SHIFT); + OPAMP_CSR(base) |= vms << OPAMP_CSR_VMS_SEL_SHIFT; +} + +/**@}*/ + From d4d4c798a6fed3448420ffe33af262aa46172daf Mon Sep 17 00:00:00 2001 From: Graham Keeth Date: Sat, 23 May 2020 18:17:21 -0400 Subject: [PATCH 030/206] add usb audio, cdc, and midi stub files for doxy - add stub files to relevant makefiles - include in respective headers to fix compilation --- include/libopencm3/usb/audio.h | 2 ++ include/libopencm3/usb/cdc.h | 2 ++ include/libopencm3/usb/midi.h | 2 ++ lib/efm32/ezr32wg/Makefile | 1 + lib/efm32/hg/Makefile | 1 + lib/efm32/lg/Makefile | 1 + lib/efm32/wg/Makefile | 1 + lib/lm4f/Makefile | 1 + lib/stm32/f0/Makefile | 1 + lib/stm32/f1/Makefile | 1 + lib/stm32/f2/Makefile | 1 + lib/stm32/f3/Makefile | 1 + lib/stm32/f4/Makefile | 1 + lib/stm32/l0/Makefile | 1 + lib/stm32/l1/Makefile | 1 + lib/stm32/l4/Makefile | 1 + lib/usb/usb_audio.c | 20 ++++++++++++++++++++ lib/usb/usb_cdc.c | 20 ++++++++++++++++++++ lib/usb/usb_midi.c | 20 ++++++++++++++++++++ 19 files changed, 79 insertions(+) create mode 100644 lib/usb/usb_audio.c create mode 100644 lib/usb/usb_cdc.c create mode 100644 lib/usb/usb_midi.c diff --git a/include/libopencm3/usb/audio.h b/include/libopencm3/usb/audio.h index 02cdeabd..98943829 100644 --- a/include/libopencm3/usb/audio.h +++ b/include/libopencm3/usb/audio.h @@ -40,6 +40,8 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_USB_AUDIO_H #define LIBOPENCM3_USB_AUDIO_H +#include + /* * Definitions from the USB_AUDIO_ or usb_audio_ namespace come from: * "Universal Serial Bus Class Definitions for Audio Devices, Revision 1.0" diff --git a/include/libopencm3/usb/cdc.h b/include/libopencm3/usb/cdc.h index 20b7836f..6e57a565 100644 --- a/include/libopencm3/usb/cdc.h +++ b/include/libopencm3/usb/cdc.h @@ -38,6 +38,8 @@ LGPL License Terms @ref lgpl_license #ifndef __CDC_H #define __CDC_H +#include + /* Definitions of Communications Device Class from * "Universal Serial Bus Class Definitions for Communications Devices * Revision 1.2" diff --git a/include/libopencm3/usb/midi.h b/include/libopencm3/usb/midi.h index 11101415..44278579 100644 --- a/include/libopencm3/usb/midi.h +++ b/include/libopencm3/usb/midi.h @@ -38,6 +38,8 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_USB_MIDI_H #define LIBOPENCM3_USB_MIDI_H +#include + /* * Definitions from the USB_MIDI_ or usb_midi_ namespace come from: * "Universal Serial Bus Class Definitions for MIDI Devices, Revision 1.0" diff --git a/lib/efm32/ezr32wg/Makefile b/lib/efm32/ezr32wg/Makefile index 6e4e75f3..10f8694f 100644 --- a/lib/efm32/ezr32wg/Makefile +++ b/lib/efm32/ezr32wg/Makefile @@ -57,6 +57,7 @@ OBJS += wdog_common.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += usb_efm32.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/efm32/hg/Makefile b/lib/efm32/hg/Makefile index ebad0170..62949335 100644 --- a/lib/efm32/hg/Makefile +++ b/lib/efm32/hg/Makefile @@ -44,6 +44,7 @@ OBJS += timer_common.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += usb_dwc_common.o usb_efm32hg.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/efm32/lg/Makefile b/lib/efm32/lg/Makefile index 1e98e6c4..c60762fd 100644 --- a/lib/efm32/lg/Makefile +++ b/lib/efm32/lg/Makefile @@ -57,6 +57,7 @@ OBJS += wdog_common.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += usb_efm32.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/efm32/wg/Makefile b/lib/efm32/wg/Makefile index 0f359558..3827a05b 100644 --- a/lib/efm32/wg/Makefile +++ b/lib/efm32/wg/Makefile @@ -57,6 +57,7 @@ OBJS += wdog_common.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += usb_efm32.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/lm4f/Makefile b/lib/lm4f/Makefile index 8d2cb21e..66d1af1f 100644 --- a/lib/lm4f/Makefile +++ b/lib/lm4f/Makefile @@ -45,6 +45,7 @@ OBJS += vector.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += usb_lm4f.o VPATH += ../usb:../cm3 diff --git a/lib/stm32/f0/Makefile b/lib/stm32/f0/Makefile index d7af8e69..d50f0232 100644 --- a/lib/stm32/f0/Makefile +++ b/lib/stm32/f0/Makefile @@ -56,6 +56,7 @@ OBJS += usart_common_all.o usart_common_v2.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += st_usbfs_core.o st_usbfs_v2.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index eefb28a7..9371f46e 100755 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -57,6 +57,7 @@ OBJS += phy.o phy_ksz80x1.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += usb_dwc_common.o usb_f107.o OBJS += st_usbfs_core.o st_usbfs_v1.o diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile index 83ab0748..42fb2838 100644 --- a/lib/stm32/f2/Makefile +++ b/lib/stm32/f2/Makefile @@ -54,6 +54,7 @@ OBJS += usart_common_all.o usart_common_f124.o OBJS += usb.o usb_standard.o usb_control.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += usb_dwc_common.o usb_f107.o usb_f207.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/f3/Makefile b/lib/stm32/f3/Makefile index f3aa1698..a88d277d 100644 --- a/lib/stm32/f3/Makefile +++ b/lib/stm32/f3/Makefile @@ -55,6 +55,7 @@ OBJS += usart_common_v2.o usart_common_all.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += st_usbfs_core.o st_usbfs_v1.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index c560f56b..0a30b0d1 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -66,6 +66,7 @@ OBJS += usart_common_all.o usart_common_f124.o OBJS += usb.o usb_standard.o usb_control.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += usb_dwc_common.o usb_f107.o usb_f207.o OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz80x1.o diff --git a/lib/stm32/l0/Makefile b/lib/stm32/l0/Makefile index 68448ac4..1322690d 100644 --- a/lib/stm32/l0/Makefile +++ b/lib/stm32/l0/Makefile @@ -55,6 +55,7 @@ OBJS += usart_common_all.o usart_common_v2.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += st_usbfs_core.o st_usbfs_v2.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile index 6d616342..b2bf7381 100644 --- a/lib/stm32/l1/Makefile +++ b/lib/stm32/l1/Makefile @@ -54,6 +54,7 @@ OBJS += usart_common_all.o usart_common_f124.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += st_usbfs_core.o st_usbfs_v1.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/l4/Makefile b/lib/stm32/l4/Makefile index 2f26dfd0..31822b75 100644 --- a/lib/stm32/l4/Makefile +++ b/lib/stm32/l4/Makefile @@ -57,6 +57,7 @@ OBJS += usart_common_all.o usart_common_v2.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o +OBJS += usb_audio.o usb_cdc.o usb_midi.o OBJS += st_usbfs_core.o st_usbfs_v2.o OBJS += usb_dwc_common.o usb_f107.o diff --git a/lib/usb/usb_audio.c b/lib/usb/usb_audio.c new file mode 100644 index 00000000..0c9425cd --- /dev/null +++ b/lib/usb/usb_audio.c @@ -0,0 +1,20 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/* This stub exists just to trick doxygen. */ diff --git a/lib/usb/usb_cdc.c b/lib/usb/usb_cdc.c new file mode 100644 index 00000000..77b7f805 --- /dev/null +++ b/lib/usb/usb_cdc.c @@ -0,0 +1,20 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/* This stub exists just to trick doxygen. */ diff --git a/lib/usb/usb_midi.c b/lib/usb/usb_midi.c new file mode 100644 index 00000000..045aeb80 --- /dev/null +++ b/lib/usb/usb_midi.c @@ -0,0 +1,20 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/* This stub exists just to trick doxygen. */ From 81d1b2cfb68b48e021f26f04ef6d62bf47738c60 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 27 Nov 2020 21:08:38 +0000 Subject: [PATCH 031/206] gendoxylist: make it not "crash" if you try interactively at least --- scripts/gendoxylist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/gendoxylist b/scripts/gendoxylist index 108e2a90..c8ff210a 100755 --- a/scripts/gendoxylist +++ b/scripts/gendoxylist @@ -2,6 +2,10 @@ # Karl Palsson Sept 2017 # Parse .d files for a given target, and generate a doxygen config file # stub that is to be "@INCLUDE = " into a doxygen template file. +[ $# -eq 2 ] || { + printf "Usage: $0 \n" + exit 1 +} DDIR=$1 ODIR=$2 From 071d4680ec3f9fc38a617cb267c8bd8d71128f83 Mon Sep 17 00:00:00 2001 From: Nikolai Smolyaninov Date: Wed, 22 Apr 2020 16:14:04 +0700 Subject: [PATCH 032/206] stm32f4/7: DCMI: extract common registers And enable for the f7 Originally filed as: https://github.com/libopencm3/libopencm3/pull/1208 Rviewed-by: Karl Palsson --- .../libopencm3/stm32/common/dcmi_common_f47.h | 246 ++++++++++++++++++ include/libopencm3/stm32/dcmi.h | 2 + include/libopencm3/stm32/f4/dcmi.h | 204 +-------------- include/libopencm3/stm32/f7/dcmi.h | 57 ++++ 4 files changed, 313 insertions(+), 196 deletions(-) create mode 100644 include/libopencm3/stm32/common/dcmi_common_f47.h create mode 100644 include/libopencm3/stm32/f7/dcmi.h diff --git a/include/libopencm3/stm32/common/dcmi_common_f47.h b/include/libopencm3/stm32/common/dcmi_common_f47.h new file mode 100644 index 00000000..11e90c75 --- /dev/null +++ b/include/libopencm3/stm32/common/dcmi_common_f47.h @@ -0,0 +1,246 @@ +/** @addtogroup dcmi_defines + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2020 + * Smolyaninov Nikolay + * @author @htmlonly © @endhtmlonly 2017 + * Marek Koza + * + * @date 15 May 2020 + * + * This library supports the Digital camera interface (DCMI) in the STM32F4xx + * and STM32F7xx series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020, Smolyaninov Nikolay + * Copyright (C) 2017, Marek Koza + * + * 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 . + */ + +/**@{*/ +/** @cond */ +#ifndef LIBOPENCM3_STM32_COMMON_DCMI_COMMON_F47_H_ +/** @endcond */ +#define LIBOPENCM3_STM32_COMMON_DCMI_COMMON_F47_H_ + + +#include +#include + +/** + * DCMI control register 1 + */ +#define DCMI_CR MMIO32(DCMI_BASE + 0x0U) +/** + * @defgroup dcmi_cr_values DCMI_CR Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_CR_EN (1 << 14) +#define DCMI_CR_EDM1 (1 << 11) +#define DCMI_CR_EDM0 (1 << 10) +#define DCMI_CR_FCRC1 (1 << 9) +#define DCMI_CR_FCRC0 (1 << 8) +#define DCMI_CR_VSPOL (1 << 7) +#define DCMI_CR_HSPOL (1 << 6) +#define DCMI_CR_PCKPOL (1 << 5) +#define DCMI_CR_ESS (1 << 4) +#define DCMI_CR_JPEG (1 << 3) +#define DCMI_CR_CROP (1 << 2) +#define DCMI_CR_CM (1 << 1) +#define DCMI_CR_CAPTURE (1 << 0) +/**@}*/ + +/** + * DCMI status register + */ +#define DCMI_SR MMIO32(DCMI_BASE + 0x04U) +/** + * @defgroup dcmi_sr_values DCMI_SR Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_SR_FNE (1 << 2) +#define DCMI_SR_VSYNCK (1 << 1) +#define DCMI_SR_HSYNCK (1 << 0) +/**@}*/ + +/** + * DCMI raw interrupt status register + * + * DCMI_RIS gives the raw interrupt status and is accessible in read only. When read, this + * register returns the status of the corresponding interrupt before masking with the DCMI_IER + * register value. + */ +#define DCMI_RIS MMIO32(DCMI_BASE + 0x08U) +/** + * @defgroup dcmi_ris_values DCMI_RIS Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_RIS_LINE (1 << 4) +#define DCMI_RIS_VSYNC (1 << 3) +#define DCMI_RIS_ERR (1 << 2) +#define DCMI_RIS_OVR (1 << 1) +#define DCMI_RIS_FRAME (1 << 0) +/**@}*/ + +/** + * DCMI interrupt enable register + * + * The DCMI_IER register is used to enable interrupts. When one of the DCMI_IER bits is set, + * the corresponding interrupt is enabled. This register is accessible in both read and write. + */ +#define DCMI_IER MMIO32(DCMI_BASE + 0x0CU) +/** + * @defgroup dcmi_ier_values DCMI_IER Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_IER_LINE (1 << 4) +#define DCMI_IER_VSYNC (1 << 3) +#define DCMI_IER_ERR (1 << 2) +#define DCMI_IER_OVR (1 << 1) +#define DCMI_IER_FRAME (1 << 0) +/**@}*/ + +/** + * DCMI masked interrupt status register + * + * This DCMI_MIS register is a read-only register. When read, it returns the current masked + * status value (depending on the value in DCMI_IER) of the corresponding interrupt. A bit in + * this register is set if the corresponding enable bit in DCMI_IER is set and the corresponding + * bit in DCMI_RIS is set. + */ +#define DCMI_MIS MMIO32(DCMI_BASE + 0x10U) +/** + * @defgroup dcmi_mis_values DCMI_MIS Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_MIS_LINE (1 << 4) +#define DCMI_MIS_VSYNC (1 << 3) +#define DCMI_MIS_ERR (1 << 2) +#define DCMI_MIS_OVR (1 << 1) +#define DCMI_MIS_FRAME (1 << 0) +/**@}*/ + +/** + * DCMI interrupt clear register + * + * The DCMI_ICR register is write-only. Writing a ‘1’ into a bit of this register clears the + * corresponding bit in the DCMI_RIS and DCMI_MIS registers. Writing a ‘0’ has no effect. + */ +#define DCMI_ICR MMIO32(DCMI_BASE + 0x14U) +/** + * @defgroup dcmi_icr_values DCMI_ICR Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_ICR_LINE (1 << 4) +#define DCMI_ICR_VSYNC (1 << 3) +#define DCMI_ICR_ERR (1 << 2) +#define DCMI_ICR_OVR (1 << 1) +#define DCMI_ICR_FRAME (1 << 0) +/**@}*/ + +/** + * DCMI embedded synchronization code register + */ +#define DCMI_ESCR MMIO32(DCMI_BASE + 0x18U) +/** + * @defgroup dcmi_escr_values DCMI_ESCR Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_ESCR_FEC_SHIFT 24 +#define DCMI_ESCR_FEC_MASK 0xff +#define DCMI_ESCR_LEC_SHIFT 16 +#define DCMI_ESCR_LEC_MASK 0xff +#define DCMI_ESCR_LSC_SHIFT 8 +#define DCMI_ESCR_LSC_MASK 0xff +#define DCMI_ESCR_FSC_SHIFT 0 +#define DCMI_ESCR_FSC_MASK 0xff +/**@}*/ + + +/** + * DCMI embedded synchronization unmask register + */ +#define DCMI_ESUR MMIO32(DCMI_BASE + 0x1CU) +/** + * @defgroup dcmi_esur_values DCMI_ESUR Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_ESUR_FEU_SHIFT 24 +#define DCMI_ESUR_FEU_MASK 0xff +#define DCMI_ESUR_LEU_SHIFT 16 +#define DCMI_ESUR_LEU_MASK 0xff +#define DCMI_ESUR_LSU_SHIFT 8 +#define DCMI_ESUR_LSU_MASK 0xff +#define DCMI_ESUR_FSU_SHIFT 0 +#define DCMI_ESUR_FSU_MASK 0xff +/**@}*/ + +/** + * DCMI crop window start + */ +#define DCMI_CWSTRT MMIO32(DCMI_BASE + 0x20U) +/** + * @defgroup dcmi_cwstrt_values DCMI_CWSTRT Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_CWSTRT_VST_SHIFT 16 +#define DCMI_CWSTRT_VST_MASK 0x1fff +#define DCMI_CWSTRT_HOFFCNT_SHIFT 0 +#define DCMI_CWSTRT_HOFFCNT_MASK 0x3fff +/**@}*/ + +/** + * DCMI crop window size + */ +#define DCMI_CWSIZE MMIO32(DCMI_BASE + 0x24U) +/** + * @defgroup dcmi_cwsize_values DCMI_CWSIZE Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_CWSIZE_VLINE_SHIFT 16 +#define DCMI_CWSIZE_VLINE_MASK 0x3fff +#define DCMI_CWSIZE_CAPCNT_SHIFT 0 +#define DCMI_CWSIZE_CAPCNT_MASK 0x3fff +/**@}*/ + +/** + * DCMI data register + * + * The digital camera Interface packages all the received data in 32-bit format before + * requesting a DMA transfer. A 4-word deep FIFO is available to leave enough time for DMA + * transfers and avoid DMA overrun conditions. + */ +#define DCMI_DR MMIO32(DCMI_BASE + 0x28U) + +/** @cond */ +#endif /* LIBOPENCM3_STM32_COMMON_DCMI_COMMON_F47_H_ */ +/** @endcond */ +/**@}*/ + diff --git a/include/libopencm3/stm32/dcmi.h b/include/libopencm3/stm32/dcmi.h index ac9cb024..435e48b8 100644 --- a/include/libopencm3/stm32/dcmi.h +++ b/include/libopencm3/stm32/dcmi.h @@ -22,6 +22,8 @@ #if defined(STM32F4) # include +#elif defined(STM32F7) +# include #else # error "stm32 family not defined." #endif diff --git a/include/libopencm3/stm32/f4/dcmi.h b/include/libopencm3/stm32/f4/dcmi.h index ae9639e5..44f77b2d 100644 --- a/include/libopencm3/stm32/f4/dcmi.h +++ b/include/libopencm3/stm32/f4/dcmi.h @@ -6,15 +6,15 @@ * * @version 1.0.0 * - * @date 2017-10-16 + * @date 2020-05-15 * * LGPL License Terms @ref lgpl_license */ + /* - * STM32F4 DCMI Defines - * - * Copyright (C) 2017, Marek Koza + * STM32F7 DCMI Defines + * Copyright (C) 2020, Smolyaninov Nikolay * * This file is part of the libopencm3 project. * @@ -33,197 +33,9 @@ * */ -#include -#include +#ifndef LIBOPENCM3_DCMI_H +#define LIBOPENCM3_DCMI_H -#pragma once +#include -/**@{*/ - -/** - * DCMI control register 1 - */ -#define DCMI_CR MMIO32(DCMI_BASE + 0x0U) -/** - * @defgroup dcmi_cr_values DCMI_CR Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_CR_EN (1 << 14) -#define DCMI_CR_EDM1 (1 << 11) -#define DCMI_CR_EDM0 (1 << 10) -#define DCMI_CR_FCRC1 (1 << 9) -#define DCMI_CR_FCRC0 (1 << 8) -#define DCMI_CR_VSPOL (1 << 7) -#define DCMI_CR_HSPOL (1 << 6) -#define DCMI_CR_PCKPOL (1 << 5) -#define DCMI_CR_ESS (1 << 4) -#define DCMI_CR_JPEG (1 << 3) -#define DCMI_CR_CROP (1 << 2) -#define DCMI_CR_CM (1 << 1) -#define DCMI_CR_CAPTURE (1 << 0) -/**@}*/ - -/** - * DCMI status register - */ -#define DCMI_SR MMIO32(DCMI_BASE + 0x04U) - -/** - * DCMI raw interrupt status register - * - * DCMI_RIS gives the raw interrupt status and is accessible in read only. When read, this - * register returns the status of the corresponding interrupt before masking with the DCMI_IER - * register value. - */ -#define DCMI_RIS MMIO32(DCMI_BASE + 0x08U) -/** - * @defgroup dcmi_ris_values DCMI_RIS Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_RIS_LINE (1 << 4) -#define DCMI_RIS_VSYNC (1 << 3) -#define DCMI_RIS_ERR (1 << 2) -#define DCMI_RIS_OVR (1 << 1) -#define DCMI_RIS_FRAME (1 << 0) -/**@}*/ - -/** - * DCMI interrupt enable register - * - * The DCMI_IER register is used to enable interrupts. When one of the DCMI_IER bits is set, - * the corresponding interrupt is enabled. This register is accessible in both read and write. - */ -#define DCMI_IER MMIO32(DCMI_BASE + 0x0CU) -/** - * @defgroup dcmi_ier_values DCMI_IER Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_IER_LINE (1 << 4) -#define DCMI_IER_VSYNC (1 << 3) -#define DCMI_IER_ERR (1 << 2) -#define DCMI_IER_OVR (1 << 1) -#define DCMI_IER_FRAME (1 << 0) -/**@}*/ - -/** - * DCMI masked interrupt status register - * - * This DCMI_MIS register is a read-only register. When read, it returns the current masked - * status value (depending on the value in DCMI_IER) of the corresponding interrupt. A bit in - * this register is set if the corresponding enable bit in DCMI_IER is set and the corresponding - * bit in DCMI_RIS is set. - */ -#define DCMI_MIS MMIO32(DCMI_BASE + 0x10U) -/** - * @defgroup dcmi_mis_values DCMI_MIS Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_MIS_LINE (1 << 4) -#define DCMI_MIS_VSYNC (1 << 3) -#define DCMI_MIS_ERR (1 << 2) -#define DCMI_MIS_OVR (1 << 1) -#define DCMI_MIS_FRAME (1 << 0) -/**@}*/ - -/** - * DCMI interrupt clear register - * - * The DCMI_ICR register is write-only. Writing a ‘1’ into a bit of this register clears the - * corresponding bit in the DCMI_RIS and DCMI_MIS registers. Writing a ‘0’ has no effect. - */ -#define DCMI_ICR MMIO32(DCMI_BASE + 0x14U) -/** - * @defgroup dcmi_icr_values DCMI_ICR Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_ICR_LINE (1 << 4) -#define DCMI_ICR_VSYNC (1 << 3) -#define DCMI_ICR_ERR (1 << 2) -#define DCMI_ICR_OVR (1 << 1) -#define DCMI_ICR_FRAME (1 << 0) -/**@}*/ - -/** - * DCMI embedded synchronization code register - */ -#define DCMI_ESCR MMIO32(DCMI_BASE + 0x18U) -/** - * @defgroup dcmi_escr_values DCMI_ESCR Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_ESCR_FEC_SHIFT 24 -#define DCMI_ESCR_FEC_MASK 0xff -#define DCMI_ESCR_LEC_SHIFT 16 -#define DCMI_ESCR_LEC_MASK 0xff -#define DCMI_ESCR_LSC_SHIFT 8 -#define DCMI_ESCR_LSC_MASK 0xff -#define DCMI_ESCR_FSC_SHIFT 0 -#define DCMI_ESCR_FSC_MASK 0xff -/**@}*/ - - -/** - * DCMI embedded synchronization unmask register - */ -#define DCMI_ESUR MMIO32(DCMI_BASE + 0x1CU) -/** - * @defgroup dcmi_esur_values DCMI_ESUR Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_ESUR_FEU_SHIFT 24 -#define DCMI_ESUR_FEU_MASK 0xff -#define DCMI_ESUR_LEU_SHIFT 16 -#define DCMI_ESUR_LEU_MASK 0xff -#define DCMI_ESUR_LSU_SHIFT 8 -#define DCMI_ESUR_LSU_MASK 0xff -#define DCMI_ESUR_FSU_SHIFT 0 -#define DCMI_ESUR_FSU_MASK 0xff -/**@}*/ - -/** - * DCMI crop window start - */ -#define DCMI_CWSTRT MMIO32(DCMI_BASE + 0x20U) -/** - * @defgroup dcmi_cwstrt_values DCMI_CWSTRT Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_CWSTRT_VST_SHIFT 16 -#define DCMI_CWSTRT_VST_MASK 0x1fff -#define DCMI_CWSTRT_HOFFCNT_SHIFT 0 -#define DCMI_CWSTRT_HOFFCNT_MASK 0x3fff -/**@}*/ - -/** - * DCMI crop window size - */ -#define DCMI_CWSIZE MMIO32(DCMI_BASE + 0x24U) -/** - * @defgroup dcmi_cwsize_values DCMI_CWSIZE Values - * @ingroup dcmi_defines - * @{ - */ -#define DCMI_CWSIZE_VLINE_SHIFT 16 -#define DCMI_CWSIZE_VLINE_MASK 0x3fff -#define DCMI_CWSIZE_CAPCNT_SHIFT 0 -#define DCMI_CWSIZE_CAPCNT_MASK 0x3fff -/**@}*/ - -/** - * DCMI data register - * - * The digital camera Interface packages all the received data in 32-bit format before - * requesting a DMA transfer. A 4-word deep FIFO is available to leave enough time for DMA - * transfers and avoid DMA overrun conditions. - */ -#define DCMI_DR MMIO32(DCMI_BASE + 0x28U) - -/**@}*/ +#endif diff --git a/include/libopencm3/stm32/f7/dcmi.h b/include/libopencm3/stm32/f7/dcmi.h new file mode 100644 index 00000000..b417e6ea --- /dev/null +++ b/include/libopencm3/stm32/f7/dcmi.h @@ -0,0 +1,57 @@ +/** @defgroup dcmi_defines DCMI Defines + * + * @ingroup STM32F7xx_defines + * + * @brief Defined Constants and Macros for the STM32F7xx DCMI Peripheral + * + * @version 1.0.0 + * + * @date 2020-05-15 + * + * LGPL License Terms @ref lgpl_license + */ + + +/* + * STM32F7 DCMI Defines + * Copyright (C) 2020, Smolyaninov Nikolay + * + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + */ + +#ifndef LIBOPENCM3_DCMI_H +#define LIBOPENCM3_DCMI_H + +#include + +/**@{*/ + +/** + * @defgroup dcmi_cr_values DCMI_CR Values + * @ingroup dcmi_defines + * @{ + */ +#define DCMI_CR_OELS (1 << 20) +#define DCMI_CR_LSM (1 << 19) +#define DCMI_CR_OEBS (1 << 18) +#define DCMI_CR_BSM1 (1 << 17) +#define DCMI_CR_BSM0 (1 << 16) + + +/**@}*/ + +#endif From daf99b9b76bfbcd0b823c5d8b993a7e11adfd47e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 27 Nov 2020 22:16:35 +0000 Subject: [PATCH 033/206] stm32: dcmi: hook up doxygen again We still need stub .c files as we're using shared common files, so .d tracking doesn't work. It lets us setup basic introductory text anyway, and there will be .c files eventually, so acceptable. --- .../libopencm3/stm32/common/dcmi_common_f47.h | 13 +++---------- include/libopencm3/stm32/f4/dcmi.h | 1 - include/libopencm3/stm32/f7/dcmi.h | 3 --- lib/stm32/common/dcmi_common_f47.c | 18 ++++++++++++++++++ lib/stm32/f4/Makefile | 1 + lib/stm32/f7/Makefile | 1 + 6 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 lib/stm32/common/dcmi_common_f47.c diff --git a/include/libopencm3/stm32/common/dcmi_common_f47.h b/include/libopencm3/stm32/common/dcmi_common_f47.h index 11e90c75..3af734a4 100644 --- a/include/libopencm3/stm32/common/dcmi_common_f47.h +++ b/include/libopencm3/stm32/common/dcmi_common_f47.h @@ -34,16 +34,13 @@ * along with this library. If not, see . */ -/**@{*/ -/** @cond */ -#ifndef LIBOPENCM3_STM32_COMMON_DCMI_COMMON_F47_H_ -/** @endcond */ -#define LIBOPENCM3_STM32_COMMON_DCMI_COMMON_F47_H_ - +#pragma once #include #include +/**@{*/ + /** * DCMI control register 1 */ @@ -239,8 +236,4 @@ */ #define DCMI_DR MMIO32(DCMI_BASE + 0x28U) -/** @cond */ -#endif /* LIBOPENCM3_STM32_COMMON_DCMI_COMMON_F47_H_ */ -/** @endcond */ /**@}*/ - diff --git a/include/libopencm3/stm32/f4/dcmi.h b/include/libopencm3/stm32/f4/dcmi.h index 44f77b2d..89065ab9 100644 --- a/include/libopencm3/stm32/f4/dcmi.h +++ b/include/libopencm3/stm32/f4/dcmi.h @@ -13,7 +13,6 @@ /* - * STM32F7 DCMI Defines * Copyright (C) 2020, Smolyaninov Nikolay * * This file is part of the libopencm3 project. diff --git a/include/libopencm3/stm32/f7/dcmi.h b/include/libopencm3/stm32/f7/dcmi.h index b417e6ea..bc118724 100644 --- a/include/libopencm3/stm32/f7/dcmi.h +++ b/include/libopencm3/stm32/f7/dcmi.h @@ -13,7 +13,6 @@ /* - * STM32F7 DCMI Defines * Copyright (C) 2020, Smolyaninov Nikolay * * This file is part of the libopencm3 project. @@ -38,8 +37,6 @@ #include -/**@{*/ - /** * @defgroup dcmi_cr_values DCMI_CR Values * @ingroup dcmi_defines diff --git a/lib/stm32/common/dcmi_common_f47.c b/lib/stm32/common/dcmi_common_f47.c new file mode 100644 index 00000000..949ef705 --- /dev/null +++ b/lib/stm32/common/dcmi_common_f47.c @@ -0,0 +1,18 @@ +/** @addtogroup dcmi_file DCMI peripheral API + * @ingroup peripheral_apis + * @brief Digital camera interface. + * + * The digital camera is a synchronous parallel interface able to + * receive a high-speed data flow from an external 8-, 10-, 12- or 14-bit + * CMOS camera module. + * + * If the APIs here are insufficient or incomplete, see @ref dcmi_defines + * + * LGPL License Terms @ref lgpl_license + */ + +/**@{*/ + +#include + +/**@}*/ \ No newline at end of file diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 0a30b0d1..80c88572 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -42,6 +42,7 @@ OBJS += can.o OBJS += crc_common_all.o OBJS += crypto_common_f24.o crypto.o OBJS += dac_common_all.o +OBJS += dcmi_common_f47.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_f24.o OBJS += dma2d_common_f47.o diff --git a/lib/stm32/f7/Makefile b/lib/stm32/f7/Makefile index 30178f9b..fc7c092e 100644 --- a/lib/stm32/f7/Makefile +++ b/lib/stm32/f7/Makefile @@ -44,6 +44,7 @@ OBJS += adc_common_v1.o adc_common_v1_multi.o adc_common_f47.o OBJS += can.o OBJS += crc_common_all.o crc_v2.o OBJS += dac_common_all.o +OBJS += dcmi_common_f47.o OBJS += desig_common_all.o desig.o OBJS += dma_common_f24.o OBJS += dma2d_common_f47.o From cb83273416b1e8cf9971fea9ace3a1c9066d1405 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 27 Nov 2020 22:28:44 +0000 Subject: [PATCH 034/206] stm32: dcmi: drop redundant @ingroups @ingroup is only needed if you want to assign a doxygen group to something other than the naturally containing outer group. --- include/libopencm3/stm32/common/dcmi_common_f47.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/libopencm3/stm32/common/dcmi_common_f47.h b/include/libopencm3/stm32/common/dcmi_common_f47.h index 3af734a4..ae78fd02 100644 --- a/include/libopencm3/stm32/common/dcmi_common_f47.h +++ b/include/libopencm3/stm32/common/dcmi_common_f47.h @@ -47,7 +47,6 @@ #define DCMI_CR MMIO32(DCMI_BASE + 0x0U) /** * @defgroup dcmi_cr_values DCMI_CR Values - * @ingroup dcmi_defines * @{ */ #define DCMI_CR_EN (1 << 14) @@ -71,7 +70,6 @@ #define DCMI_SR MMIO32(DCMI_BASE + 0x04U) /** * @defgroup dcmi_sr_values DCMI_SR Values - * @ingroup dcmi_defines * @{ */ #define DCMI_SR_FNE (1 << 2) @@ -89,7 +87,6 @@ #define DCMI_RIS MMIO32(DCMI_BASE + 0x08U) /** * @defgroup dcmi_ris_values DCMI_RIS Values - * @ingroup dcmi_defines * @{ */ #define DCMI_RIS_LINE (1 << 4) @@ -108,7 +105,6 @@ #define DCMI_IER MMIO32(DCMI_BASE + 0x0CU) /** * @defgroup dcmi_ier_values DCMI_IER Values - * @ingroup dcmi_defines * @{ */ #define DCMI_IER_LINE (1 << 4) @@ -129,7 +125,6 @@ #define DCMI_MIS MMIO32(DCMI_BASE + 0x10U) /** * @defgroup dcmi_mis_values DCMI_MIS Values - * @ingroup dcmi_defines * @{ */ #define DCMI_MIS_LINE (1 << 4) @@ -148,7 +143,6 @@ #define DCMI_ICR MMIO32(DCMI_BASE + 0x14U) /** * @defgroup dcmi_icr_values DCMI_ICR Values - * @ingroup dcmi_defines * @{ */ #define DCMI_ICR_LINE (1 << 4) @@ -164,7 +158,6 @@ #define DCMI_ESCR MMIO32(DCMI_BASE + 0x18U) /** * @defgroup dcmi_escr_values DCMI_ESCR Values - * @ingroup dcmi_defines * @{ */ #define DCMI_ESCR_FEC_SHIFT 24 @@ -184,7 +177,6 @@ #define DCMI_ESUR MMIO32(DCMI_BASE + 0x1CU) /** * @defgroup dcmi_esur_values DCMI_ESUR Values - * @ingroup dcmi_defines * @{ */ #define DCMI_ESUR_FEU_SHIFT 24 @@ -203,7 +195,6 @@ #define DCMI_CWSTRT MMIO32(DCMI_BASE + 0x20U) /** * @defgroup dcmi_cwstrt_values DCMI_CWSTRT Values - * @ingroup dcmi_defines * @{ */ #define DCMI_CWSTRT_VST_SHIFT 16 @@ -218,7 +209,6 @@ #define DCMI_CWSIZE MMIO32(DCMI_BASE + 0x24U) /** * @defgroup dcmi_cwsize_values DCMI_CWSIZE Values - * @ingroup dcmi_defines * @{ */ #define DCMI_CWSIZE_VLINE_SHIFT 16 From 245761f894bb0495fa50f73e18828d1249017881 Mon Sep 17 00:00:00 2001 From: Kevin Stefanik Date: Thu, 13 Feb 2020 18:39:54 -0500 Subject: [PATCH 035/206] pac55xx: implemented CAN module interface for qorvo pac55xx. --- include/libopencm3/pac55xx/can.h | 307 +++++++++++++++++++++ lib/pac55xx/Makefile | 1 + lib/pac55xx/can.c | 460 +++++++++++++++++++++++++++++++ 3 files changed, 768 insertions(+) create mode 100644 include/libopencm3/pac55xx/can.h create mode 100644 lib/pac55xx/can.c diff --git a/include/libopencm3/pac55xx/can.h b/include/libopencm3/pac55xx/can.h new file mode 100644 index 00000000..2ef38d7d --- /dev/null +++ b/include/libopencm3/pac55xx/can.h @@ -0,0 +1,307 @@ +/** + * @brief CAN definitions for the Qorvo PAC55xx series of microcontrollers. + * + * @addtogroup PAC55xx_can CAN + * @ingroup PAC55xx_defines + * @author Kevin Stefanik + * LGPL License Terms @ref lgpl_license + * @date February 13, 2020 + * + * Definitions in this file come from the PAC55XX Family User Guide Rev 1.23 + * by Active-Semi dated November 19, 2019. + * + * Note: all memory-mapped writes must be performed using 32-bit registers. + * Any 8-bit memory-mapped registers below may only be used to read. + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Kevin Stefanik + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#ifndef LIBOPENCM3_PAC55XX_CAN_H_ +#define LIBOPENCM3_PAC55XX_CAN_H_ + +#include +#include + +/**@{*/ + +/** + * @defgroup can_isr_sr_cmr_mr CAN ISR/SR/CMR/MR Registers + * @{*/ +/** This is the 32-bit memory mapped read/write accessor for: + * - ISR - bits 31:24 - Interrupt Status/ACK Register RW, default 00h + * - SR - bits 23:16 - Status Register RO, default 00h + * - CMR - bits 15:8 - Command RW, default 00h + * - MR - bits 7:0 - Mode RW, default 04h + * When writing, be sure to use CAN_ISR_SR_CMR_MR_SET and CAN_ISR_SR_CMR_MR_CLEAR + * so as to avoid inadvertently Acknowledging an ISR bit. Writing '1' to one + * of the ISR bits when it is triggered/set will ACK/clear the bit. + */ +#define CAN_ISR_SR_CMR_MR(can_base) MMIO32((can_base) + 0x0000) +#define CAN_ISR_SR_CMR_MR_SET(can_base, bits) (CAN_ISR_SR_CMR_MR(can_base) = \ + (CAN_ISR_SR_CMR_MR(can_base) & 0x00FFFFFF) | (bits)) +#define CAN_ISR_SR_CMR_MR_CLEAR(can_base, bits) (CAN_ISR_SR_CMR_MR(can_base) = \ + (CAN_ISR_SR_CMR_MR(can_base) & 0x00FFFFFF) & ~(bits)) +/**@}*/ + +/** + * @defgroup can_btr01_rmc_imr CAN BTR1/BTR0/RMC/IMR Registers + * @{*/ +/** This is the 32-bit memory mapped read/write accessor for: + * - BTR1 - bits 31:24 - Bus Timing 1 Register RW, default 00h + * - BTR0 - bits 23:16 - Bus Timing 0 Register RW, default 00h + * - RMC - bits 15:8 - Receive Message Counter RO, default 00h + * - IMR - bits 7:0 - Interrupt Mask Register RW, default 00h + */ +#define CAN_BTR1_BTR0_RMC_IMR(can_base) MMIO32((can_base) + 0x0004) +/**@}*/ + +/** CAN Transmit Buffer Register RW, default 00000000h */ +#define CAN_TXBUF(can_base) MMIO32((can_base) + 0x0008) +/** CAN Receive Buffer Register RO, default 00000000h */ +#define CAN_RXBUF(can_base) MMIO32((can_base) + 0x000C) +/** CAN Acceptance Code Register RW, default 00000000h */ +#define CAN_ACR(can_base) MMIO32((can_base) + 0x0010) +/** CAN Acceptance Mask Register RW, default 00000000h */ +#define CAN_AMR(can_base) MMIO32((can_base) + 0x0014) + +/** + * @defgroup can_alc_txrxerr_ecc CAN ALC/TXERR/RXERR/ECC Registers + * @{*/ +#define CAN_ALC_TXERR_RXERR_ECC(can_base) MMIO32((can_base) + 0x0018) +/** CAN Error Code Capture Register RO, default 00h */ +#define CAN_ECC(can_base) (CAN_ALC_TXERR_RXERR_ECC(can_base) & 0xFF) +/** CAN RX Error Counter Register RO, default 00h */ +#define CAN_RXERR(can_base) ((CAN_ALC_TXERR_RXERR_ECC(can_base) >> 8) & 0xFF) +/** CAN TX Error Counter Register RO, default 00h */ +#define CAN_TXERR(can_base) ((CAN_ALC_TXERR_RXERR_ECC(can_base) >> 16) & 0xFF) +/** CAN Arbitration Lost Code Capture Register RO, default 00h */ +#define CAN_ALC(can_base) ((CAN_ALC_TXERR_RXERR_ECC(can_base) >> 24) & 0xFF) +/**@}*/ + +/** CAN Mode Register bit definitions. This register controls high level modes of the CAN peripheral. + * @defgroup can_mr_bits CAN Mode Register + * @{*/ +/** AFM: Acceptance Filter Mode */ +#define CAN_MR_AFM BIT0 +/** LOM: Listen only mode */ +#define CAN_MR_LOM BIT1 +/** RM: Reset Mode */ +#define CAN_MR_RM BIT2 +/**@}*/ + +/** CAN Command Register. This register commands the CAN peripheral to either transmit or abort. + * @defgroup can_cmr_bits CAN Command Register + * @{*/ +/** AT: Abort transmission */ +#define CAN_CMR_AT BIT9 +/** TR: Transmit Request */ +#define CAN_CMR_TR BIT10 +/**@}*/ + +/** CAN Status Register. This register provides read-only status of the CAN peripheral. + * @defgroup can_sr_bits CAN Status Register + * @{*/ +/** BS: Bus Off Status */ +#define CAN_SR_BS BIT16 +/** ES: Error Status */ +#define CAN_SR_ES BIT17 +/** TS: Transmit Status */ +#define CAN_SR_TS BIT18 +/** RS: Receive Status */ +#define CAN_SR_RS BIT19 +/** TBS: Transmit Buffer Status */ +#define CAN_SR_TBS BIT21 +/** DSO: Data Overrun Status */ +#define CAN_SR_DSO BIT22 +/** RBS: Receive Buffer Status */ +#define CAN_SR_RBS BIT23 +/**@}*/ + +/** CAN Interrupt Status Register bit definitions. + * - 1: interrupt triggered + * - 0: no interrupt + * - Writing a 1 to a triggered interrupt clears the bit. + * @defgroup can_isr_bits CAN Interrupt Status Register + * @{*/ +/** DOI: Data Overflow Interrupt */ +#define CAN_ISR_DOI BIT24 +/** BEI: Bus Error Interrupt */ +#define CAN_ISR_BEI BIT25 +/** TI: Transmit Interrupt */ +#define CAN_ISR_TI BIT26 +/** RI: Receive Interrupt */ +#define CAN_ISR_RI BIT27 +/** EPI: Error Passive Interrupt */ +#define CAN_ISR_EPI BIT28 +/** EWI: Error Warning Interrupt */ +#define CAN_ISR_EWI BIT29 +/** ALI: Arbitration Lost Interrupt */ +#define CAN_ISR_ALI BIT30 +/** This is a helper to acknowledge an ISR */ +#define CAN_ISR_ACKNOWLEDGE(can_base, isr) CAN_ISR_SR_CMR_MR_SET(can_base, ((isr) & 0x7F000000)) +/**@}*/ + +/** CAN Interrupt Mask Register bit definitions. + * 0: disables/masks interrupt + * 1: enables interrupt + * @defgroup can_imr_bits CAN Mask Register + * @{*/ +/** DOIM: DOI Interrupt Mask */ +#define CAN_IMR_DOIM BIT0 +/** BEIM: BEI Interrupt Mask */ +#define CAN_IMR_BEIM BIT1 +/** TIM: TI Interrupt Mask */ +#define CAN_IMR_TIM BIT2 +/** RIM: RI Interrupt Mask */ +#define CAN_IMR_RIM BIT3 +/** EPIM: EPI Interrupt Mask */ +#define CAN_IMR_EPIM BIT4 +/** EWIM: EWI Interrupt Mask */ +#define CAN_IMR_EWIM BIT5 +/** ALIM: ALI Interrupt Mask */ +#define CAN_IMR_ALIM BIT6 +/**@}*/ + +/** CAN Receive Message Counter Register bit definitions. + * @defgroup can_rmc_bits CAN Receive Message Counter Register. + * @{*/ +#define CAN_RMC(can_base) ((CAN_BTR1_BTR0_RMC_IMR(can_base) >> 8) & 0x1F) +/**@}*/ + +/** CAN Bus Timing 0 Register bit definitions. + * @defgroup can_btr0_bits CAN Bus Timing 0 Register. + * @{*/ +#define CAN_BTR0_BRP_MASK (0x3F) +#define CAN_BTR0_BRP_SHIFT 16 +#define CAN_BTR0_BRP(val) (((val) & CAN_BTR0_BRP_MASK) << CAN_BTR0_BRP_SHIFT) +#define CAN_BTR0_SJW_MASK (0x03) +#define CAN_BTR0_SJW_SHIFT 22 +#define CAN_BTR0_SJW(val) (((val) & CAN_BTR0_SJW_MASK) << CAN_BTR0_SJW_SHIFT) +/**@}*/ + +/** CAN Bus Timing 1 Register bit definitions. + * @defgroup can_btr1_bits CAN Bus Timing 1 Register + * @{*/ +#define CAN_BTR1_TSEG1_MASK (0x0F) +#define CAN_BTR1_TSEG1_SHIFT 24 +#define CAN_BTR1_TSEG1(val) (((val) & CAN_BTR1_TSEG1_MASK) << CAN_BTR1_TSEG1_SHIFT) + +#define CAN_BTR1_TSEG2_MASK (0x07) +#define CAN_BTR1_TSEG2_SHIFT 28 +#define CAN_BTR1_TSEG2(val) (((val) & CAN_BTR1_TSEG2_MASK) << CAN_BTR1_TSEG2_SHIFT) +#define CAN_BTR1_SAM BIT31 +/**@}*/ + +/** CAN Error Code Capture Register bit definitions. + * @defgroup can_ecc_bits CAN Error Code Capture Register + * @{*/ +/** BER: Bit error ocurred */ +#define CAN_ECC_BER BIT0 +/** STFER: Stuff error occurred */ +#define CAN_ECC_STFER BIT1 +/** CRCER: CRC error occurred */ +#define CAN_ECC_CRCER BIT2 +/** FRMER: Form error occurred */ +#define CAN_ECC_FRMER BIT3 +/** ACKER: ACK error occurred */ +#define CAN_ECC_ACKER BIT4 +/** EDIR: Direction of transfer 0:TX, 1:RX */ +#define CAN_ECC_EDIR BIT5 +/** TXWRN: set when CAN_TXERR >= 96 */ +#define CAN_ECC_TXWRN BIT6 +/** RXWRN: set when CAN_RXERR >= 96 */ +#define CAN_ECC_RXWRN BIT7 +/**@}*/ + +/** CAN Acceptance Code/Mask Register. This is used for filtering messages. + * Mask value of 1 ignores the bit. Mask value of 0 checks the bit. + * @defgroup can_acr_bits CAN Acceptance Code Register + * @{*/ +#define CAN_ACR_DUAL_DB_UPPER 0x000F0000U /* 19:16 */ +#define CAN_ACR_DUAL_DB_LOWER 0x0000000FU /* 3:0 */ +#define CAN_ACR_DUAL_ID1 0xFFE00000U /* 31:21 */ +#define CAN_ACR_DUAL_ID2 0x0000FFE0U /* 15:5 */ +#define CAN_ACR_DUAL_RTR1 0x00100000U /* 20 */ +#define CAN_ACR_DUAL_RTR2 0x00000010U /* 4 */ + +#define CAN_ACR_SINGLE_STD_ID 0xFFE00000U /* 31:21 */ +#define CAN_ACR_SINGLE_STD_RTR 0x00100000U /* 20 */ +#define CAN_ACR_SINGLE_STD_DB1 0x0000FF00U /* 15:8 */ +#define CAN_ACR_SINGLE_STD_DB2 0x000000FFU /* 7:0 */ + +#define CAN_ACR_SINGLE_EXT_ID 0xFFFFFFF8U /* 31:3 */ +#define CAN_ACR_SINGLE_EXT_RTR 0x00000004U /* 2 */ +/**@}*/ + +/** + * @defgroup can_bit_masks CAN Miscellaneous Bit Masks + * @{*/ +#define CAN_BITS_2_0 (0x07) +#define CAN_BITS_3_0 (0x0F) +#define CAN_BITS_4_0 (0x1F) +#define CAN_BITS_7_3 (0xF8) +#define CAN_BITS_10_3 (0x07F8) +#define CAN_BITS_12_5 (0x00001FE0U) +#define CAN_BITS_20_13 (0x001FE000U) +#define CAN_BITS_28_21 (0x1FE00000U) +#define CAN_BITS_15_8 (0x0000FF00U) +#define CAN_BITS_23_16 (0x00FF0000U) +#define CAN_BITS_31_24 (0xFF000000U) +#define CAN_BITS_23_21 (0x00E00000U) +/**@}*/ + +/**@}*/ + +BEGIN_DECLS +/** CAN Application Programming Interface. + * @addtogroup can_api CAN Peripheral API + * @ingroup peripheral_apis + @{*/ +void can_enable(uint32_t canport); +void can_disable(uint32_t canport); +void can_init(uint32_t canport, bool listen_only, uint32_t sjw, + uint32_t tseg1, uint32_t tseg2, + bool sam3, uint32_t brp); +void can_filter_clear(uint32_t canport); +void can_filter_dual(uint32_t canport, uint32_t id1, uint32_t id1_mask, + uint32_t id2, uint32_t id2_mask, + uint8_t db, uint8_t db_mask); +void can_filter_single_std(uint32_t canport, uint32_t id, uint32_t id_mask, + uint8_t db1, uint8_t db1_mask, + uint8_t db2, uint8_t db2_mask); +void can_filter_single_std_rtr(uint32_t canport, uint32_t id, uint32_t id_mask, + uint8_t db1, uint8_t db1_mask, + uint8_t db2, uint8_t db2_mask); +void can_filter_single_ext(uint32_t canport, uint32_t id, uint32_t id_mask); +void can_filter_single_ext_rtr(uint32_t canport, uint32_t id, uint32_t id_mask); +void can_enable_irq(uint32_t canport, uint8_t imr); +void can_disable_irq(uint32_t canport, uint8_t imr); + +bool can_transmit_std(uint32_t canport, uint32_t id, bool rtr, uint8_t length, + const uint8_t *data); +bool can_transmit_ext(uint32_t canport, uint32_t id, bool rtr, uint8_t length, + const uint8_t *data); +void can_abort_transmit(uint32_t canport); + +void can_receive(uint32_t canport, uint32_t *id, bool *ext, bool *rtr, uint8_t *length, + uint8_t *data); +/**@}*/ + +END_DECLS + +#endif /* LIBOPENCM3_PAC55XX_CAN_H_ */ diff --git a/lib/pac55xx/Makefile b/lib/pac55xx/Makefile index 36e2fdb2..463340ba 100644 --- a/lib/pac55xx/Makefile +++ b/lib/pac55xx/Makefile @@ -35,6 +35,7 @@ TGT_CFLAGS += $(DEBUG_FLAGS) TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs +OBJS += can.o OBJS += gpio.o VPATH += ../cm3 diff --git a/lib/pac55xx/can.c b/lib/pac55xx/can.c new file mode 100644 index 00000000..467e8192 --- /dev/null +++ b/lib/pac55xx/can.c @@ -0,0 +1,460 @@ +/** + * @addtogroup can_api CAN Peripheral API + * @ingroup peripheral_apis + * @brief PAC55xxxx CAN Driver + * @author @htmlonly © @endhtmlonly 2020 Kevin Stefanik + * @date February 13, 2020 + * + * This library supports the CAN module in the PAC55xx SoC from Qorvo. + * + * Note: Acceptance Code Mask Register values of 1 indicate the filter is to + * ignore the bit. However, standard CAN driver APIs use a positive logic for the + * mask. The implementations in this file inverts masks as appropriate to + * the mask to make this more portable/intuitive. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#include +#include + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Enable +Enable the CAN peripheral and its associated FIFOs/counters/interrupts. +@param[in] canport Unsigned int32. CAN block register base address. +*/ +void can_enable(uint32_t canport) { + CAN_ISR_SR_CMR_MR_CLEAR(canport, CAN_MR_RM); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Disable +Disable the CAN peripheral and all associated FIFOs/counters/interrupts. +@param[in] canport Unsigned int32. CAN block register base address. +*/ +void can_disable(uint32_t canport) { + CAN_ISR_SR_CMR_MR_SET(canport, CAN_MR_RM); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Init +Initialize the selected CAN peripheral block. +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] listen_only bool. Enable listen only mode. +@param[in] sjw Unsigned int32. Resynchronization time quanta jump width. +@param[in] tseg1 Unsigned int32. Time segment 1 time quanta width. +@param[in] tseg2 Unsigned int32. Time segment 2 time quanta width. +@param[in] sam3 bool. Use best 2 out of 3 samples. +@param[in] brp Unsigned int32. Baud rate prescaler. +*/ +void can_init(uint32_t canport, bool listen_only, uint32_t sjw, + uint32_t tseg1, uint32_t tseg2, + bool sam3, uint32_t brp) { + /* Put CAN module in reset and clear out ISR/SR/CMR/MR */ + CAN_ISR_SR_CMR_MR(canport) = CAN_MR_RM; + /* Setup single filter scheme */ + CAN_ISR_SR_CMR_MR_SET(canport, CAN_MR_AFM); + /* enable listen-only mode */ + if (listen_only) { + CAN_ISR_SR_CMR_MR_SET(canport, CAN_MR_LOM); + } + + /* Set Baud Rate Prescaler, sync jump width, tseg1/2 */ + CAN_BTR1_BTR0_RMC_IMR(canport) = CAN_BTR0_BRP(brp) | CAN_BTR0_SJW(sjw) + | CAN_BTR1_TSEG1(tseg1) | CAN_BTR1_TSEG2(tseg2); + if (sam3) { + /* enable sample bus 3 times */ + CAN_BTR1_BTR0_RMC_IMR(canport) |= CAN_BTR1_SAM; + } + + /* Filter: Accept incoming messages with any identifier */ + CAN_ACR(canport) = 0; + /* Note: when mask bits are 1, the bits are ignored */ + CAN_AMR(canport) = 0xFFFFFFFFu; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Filter Clear +Clear the message filters to receive all messages. +@param[in] canport Unsigned int32. CAN block register base address. +*/ +void can_filter_clear(uint32_t canport) { + /* Filter: Accept incoming messages with any identifier */ + CAN_ACR(canport) = 0; + /* Note: when mask bits are 1, the bits are ignored */ + CAN_AMR(canport) = 0xFFFFFFFFu; + /* Setup single filter scheme */ + CAN_ISR_SR_CMR_MR_SET(canport, CAN_MR_AFM); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Dual Filter Standard Frame +Notes: + - Acceptance Code Mask Register values of 1 indicate the filter is to ignore + the bit. However standard CAN driver APIs use a positive logic for the mask. + So this function inverts the mask to make this more portable/intuitive. + - Register definition byte order is opposite what is shown in Rev 1.23 of + the PAC55XX Family User Guide. Since both data and ID values cross byte + boundaries, the bswap32 function is used to correct for the discrepancy. + +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] id1 Unsigned int32. CAN ID 1. Only bits 10:0 are used. +@param[in] id1_mask Unsigned int32. CAN ID 1 mask. Only bits 10:0 are used. +@param[in] id2 Unsigned int32. CAN ID 2. Only bits 10:0 are used. +@param[in] id2_mask Unsigned int32. CAN ID 2 mask. Only bits 10:0 are used. +@param[in] db bool. CAN first data byte value. +@param[in] db_mask bool. CAN first data byte mask. +*/ +void can_filter_dual(uint32_t canport, uint32_t id1, uint32_t id1_mask, + uint32_t id2, uint32_t id2_mask, + uint8_t db, uint8_t db_mask) { + /* set value */ + uint32_t word = ((id1 << 21) & CAN_ACR_DUAL_ID1) + | ((id2 << 5) & CAN_ACR_DUAL_ID2) + | ((db << 12) & CAN_ACR_DUAL_DB_UPPER) | (db & CAN_ACR_DUAL_DB_LOWER); + CAN_ACR(canport) = __builtin_bswap32(word); + /* set mask */ + word = ((~id1_mask << 21) & CAN_ACR_DUAL_ID1) + | ((~id2_mask << 5) & CAN_ACR_DUAL_ID2) + | ((~db_mask << 12) & CAN_ACR_DUAL_DB_UPPER) + | ((~db_mask) & CAN_ACR_DUAL_DB_LOWER) + | CAN_ACR_DUAL_RTR1 | CAN_ACR_DUAL_RTR2; + CAN_AMR(canport) = __builtin_bswap32(word); + /* 0: dual filter */ + CAN_ISR_SR_CMR_MR_CLEAR(canport, CAN_MR_AFM); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Filter Single Standard Frame +Notes: + - Acceptance Code Mask Register values of 1 indicate the filter is to ignore + the bit. However standard CAN driver APIs use a positive logic for the mask. + So this function inverts the mask to make this more portable/intuitive. + - Register definition byte order is opposite what is shown in Rev 1.23 of + the PAC55XX Family User Guide. Since both data and ID values cross byte + boundaries, the bswap32 function is used to correct for the discrepancy. + +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] id Unsigned int32. CAN ID. Only bits 10:0 are used. +@param[in] id_mask Unsigned int32. CAN ID mask. Only bits 10:0 are used. +@param[in] db1 bool. CAN first data byte value. +@param[in] db1_mask bool. CAN first data byte mask. +@param[in] db2 bool. CAN second data byte value. +@param[in] db2_mask bool. CAN second data byte mask. +*/ +void can_filter_single_std(uint32_t canport, uint32_t id, uint32_t id_mask, + uint8_t db1, uint8_t db1_mask, + uint8_t db2, uint8_t db2_mask) { + /* set value */ + uint32_t word = ((id << 21) & CAN_ACR_SINGLE_STD_ID) + | ((db1 << 8) & CAN_ACR_SINGLE_STD_DB1) + | ((db2 << 0) & CAN_ACR_SINGLE_STD_DB2); + CAN_ACR(canport) = __builtin_bswap32(word); + /* set mask */ + word = ((~id_mask << 21) & CAN_ACR_SINGLE_STD_ID) + | CAN_ACR_SINGLE_STD_RTR | CAN_ACR_DUAL_DB_UPPER + | ((~db1_mask << 8) & CAN_ACR_SINGLE_STD_DB1) + | ((~db2_mask << 0) & CAN_ACR_SINGLE_STD_DB2); + CAN_AMR(canport) = __builtin_bswap32(word); + /* 1: single filter */ + CAN_ISR_SR_CMR_MR_SET(canport, CAN_MR_AFM); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Filter Single Standard Frame w/RTR set +Notes: + - Acceptance Code Mask Register values of 1 indicate the filter is to ignore + the bit. However standard CAN driver APIs use a positive logic for the mask. + So this function inverts the mask to make this more portable/intuitive. + - Register definition byte order is opposite what is shown in Rev 1.23 of + the PAC55XX Family User Guide. Since both data and ID values cross byte + boundaries, the bswap32 function is used to correct for the discrepancy. + +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] id Unsigned int32. CAN ID. Only bits 10:0 are used. +@param[in] id_mask Unsigned int32. CAN ID mask. Only bits 10:0 are used. +@param[in] db1 bool. CAN first data byte value. +@param[in] db1_mask bool. CAN first data byte mask. +@param[in] db2 bool. CAN second data byte value. +@param[in] db2_mask bool. CAN second data byte mask. +*/ +void can_filter_single_std_rtr(uint32_t canport, uint32_t id, uint32_t id_mask, + uint8_t db1, uint8_t db1_mask, + uint8_t db2, uint8_t db2_mask) { + /* set value */ + uint32_t word = ((id << 21) & CAN_ACR_SINGLE_STD_ID) + | CAN_ACR_SINGLE_STD_RTR | ((db1 << 8) & CAN_ACR_SINGLE_STD_DB1) + | ((db2 << 0) & CAN_ACR_SINGLE_STD_DB2); + CAN_ACR(canport) = __builtin_bswap32(word); + /* set mask */ + word = ((~id_mask << 21) & CAN_ACR_SINGLE_STD_ID) + | ((~db1_mask << 8) & CAN_ACR_SINGLE_STD_DB1) + | ((~db2_mask << 0) & CAN_ACR_SINGLE_STD_DB2); + CAN_AMR(canport) = __builtin_bswap32(word); + /* 1: single filter */ + CAN_ISR_SR_CMR_MR_SET(canport, CAN_MR_AFM); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Filter Single Extended Frame +Notes: + - Acceptance Code Mask Register values of 1 indicate the filter is to ignore + the bit. However standard CAN driver APIs use a positive logic for the mask. + So this function inverts the mask to make this more portable/intuitive. + - Register definition byte order is opposite what is shown in Rev 1.23 of + the PAC55XX Family User Guide. Since both data and ID values cross byte + boundaries, the bswap32 function is used to correct for the discrepancy. + +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] id Unsigned int32. CAN ID. Only bits 28:0 are used. +@param[in] id_mask Unsigned int32. CAN ID mask. Only bits 28:0 are used. +*/ +void can_filter_single_ext(uint32_t canport, uint32_t id, uint32_t id_mask) { + /* set value */ + uint32_t word = ((id << 3) & CAN_ACR_SINGLE_EXT_ID); + CAN_ACR(canport) = __builtin_bswap32(word); + /* set mask */ + word = ((~id_mask << 3) & CAN_ACR_SINGLE_EXT_ID) | CAN_ACR_SINGLE_EXT_RTR; + CAN_AMR(canport) = __builtin_bswap32(word); + /* 1: single filter */ + CAN_ISR_SR_CMR_MR_SET(canport, CAN_MR_AFM); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Filter Single Extended Frame w/RTR set +Notes: + - Acceptance Code Mask Register values of 1 indicate the filter is to ignore + the bit. However standard CAN driver APIs use a positive logic for the mask. + So this function inverts the mask to make this more portable/intuitive. + - Register definition byte order is opposite what is shown in Rev 1.23 of + the PAC55XX Family User Guide. Since both data and ID values cross byte + boundaries, the bswap32 function is used to correct for the discrepancy. + +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] id Unsigned int32. CAN ID. Only bits 28:0 are used. +@param[in] id_mask Unsigned int32. CAN ID mask. Only bits 28:0 are used. +*/ +void can_filter_single_ext_rtr(uint32_t canport, uint32_t id, uint32_t id_mask) { + /* set value */ + uint32_t word = ((id << 3) & CAN_ACR_SINGLE_EXT_ID) | CAN_ACR_SINGLE_EXT_RTR; + CAN_ACR(canport) = __builtin_bswap32(word); + /* set mask */ + word = ((~id_mask << 3) & CAN_ACR_SINGLE_EXT_ID); + CAN_AMR(canport) = __builtin_bswap32(word); + /* 1: single filter */ + CAN_ISR_SR_CMR_MR_SET(canport, CAN_MR_AFM); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Enable IRQ +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] irq Unsigned int8. IRQ bit(s). +*/ +void can_enable_irq(uint32_t canport, uint8_t irq) { + /* set to 1 (not masked) to enable */ + CAN_BTR1_BTR0_RMC_IMR(canport) |= (uint32_t)irq; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Disable IRQ +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] irq Unsigned int8. IRQ bit(s). +*/ +void can_disable_irq(uint32_t canport, uint8_t irq) { + /* set to 0 (masked) to disable */ + CAN_BTR1_BTR0_RMC_IMR(canport) &= ~(uint32_t)irq; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Transmit Standard Frame +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] id Unsigned int32. Message ID bits 10:0 used. +@param[in] rtr bool. Remote Request bit value. +@param[in] length Unsigned int8. Message payload length. +@param[in] data Unsigned int8[]. Message payload data. +@returns true if able to transmit, false otherwise. +*/ +bool can_transmit_std(uint32_t canport, uint32_t id, bool rtr, uint8_t length, + const uint8_t *data) { + /* if TBS is 0, then not ready to transmit */ + if ((CAN_ISR_SR_CMR_MR(canport) & CAN_SR_TBS) == 0) { + return false; + } + uint32_t word = (length & CAN_BITS_3_0) + | (rtr ? BIT6 : 0) /* DLC/RTR/FF ==> 7:0 */ + | ((id & CAN_BITS_10_3) << 5) /* ID 10:3 ==> 15:8 */ + | ((id & CAN_BITS_2_0) << 21) /* ID 2:0 ==> 23:21 */ + | (((length > 0) ? data[0] : 0) << 24); + CAN_TXBUF(canport) = word; + + if (length > 1) { + word = (data[1] << 0) | (data[2] << 8) + | (data[3] << 16) | (data[4] << 24); + CAN_TXBUF(canport) = word; + } + + if (length > 5) { + word = (data[5] << 0) | (data[6] << 8) | (data[7] << 16); + CAN_TXBUF(canport) = word; + } + + /* Request transmit */ + CAN_ISR_SR_CMR_MR_SET(canport, CAN_CMR_TR); + return true; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Transmit Extended Frame +@param[in] canport Unsigned int32. CAN block register base address. +@param[in] id Unsigned int32. Message ID bits 28:0 used. +@param[in] rtr bool. Remote Request bit value. +@param[in] length Unsigned int8. Message payload length, 0-8. +@param[in] data Unsigned int8[]. Message payload data. +@returns true if able to transmit, false otherwise. +*/ +bool can_transmit_ext(uint32_t canport, uint32_t id, bool rtr, uint8_t length, + const uint8_t *data) { + /* if TBS is 0, then not ready to transmit */ + if ((CAN_ISR_SR_CMR_MR(canport) & CAN_SR_TBS) == 0) { + return false; + } + uint32_t word = (length & CAN_BITS_3_0) + | (rtr ? BIT6 : 0) | BIT7 /* DLC/RTR/FF ==> 7:0 */ + | ((id & CAN_BITS_28_21) >> 13) /* ID 28:21 ==> 15:8 */ + | ((id & CAN_BITS_20_13) << 3) /* ID 20:13 ==> 23:16 */ + | ((id & CAN_BITS_12_5) << 19); /* ID 12:5 ==> 31:24 */ + CAN_TXBUF(canport) = word; /* write first 32-bit word to FIFO */ + + word = ((id & CAN_BITS_4_0) << 3); /* ID 4:0 ==> 7:3 */ + if (length > 0) { + word |= (data[0] << 8) | (data[1] << 16) | (data[2] << 24); + } + /* for extended frame, always write second 32-bit word to FIFO */ + CAN_TXBUF(canport) = word; + if (length > 3) { + word = (data[3] << 0) | (data[4] << 8) + | (data[5] << 16) | (data[6] << 24); + CAN_TXBUF(canport) = word; + } + if (length > 7) { + word = data[7]; + CAN_TXBUF(canport) = word; + } + /* Request transmit */ + CAN_ISR_SR_CMR_MR_SET(canport, CAN_CMR_TR); + return true; +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Abort Transmit +Aborts the current transmission. + +@param[in] canport Unsigned int32. CAN block register base address. +*/ +void can_abort_transmit(uint32_t canport) { + CAN_ISR_SR_CMR_MR_SET(canport, CAN_CMR_AT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief CAN Receive Message +If no data is in the RX buffer, id and length are set to 0. + +@param[in] canport Unsigned int32. CAN block register base address. +@param[out] id Unsigned int32 pointer. Message ID. +@param[out] ext bool pointer. The message ID is extended. +@param[out] rtr bool pointer. Remote Request bit value. +@param[out] length Unsigned int8 pointer. Length of message payload. +@param[out] data Unsigned int8[]. Message payload data, min length 8. +*/ +void can_receive(uint32_t canport, uint32_t *id, bool *ext, bool *rtr, uint8_t *length, + uint8_t *data) { + if ((CAN_ISR_SR_CMR_MR(canport) & CAN_ISR_RI) == 0 || CAN_RMC(canport) == 0) { + *id = 0; + *length = 0; + return; /* empty RX FIFO */ + } + uint32_t can_buffer = CAN_RXBUF(canport); /* read 32-bit word */ + uint8_t rx_length = can_buffer & CAN_BITS_3_0; + bool is_extended = can_buffer & BIT7; + if (ext) { + *ext = is_extended; + } + if (rtr) { + *rtr = can_buffer & BIT6; + } + if (length) { + *length = rx_length; + } + uint32_t _id; + if (is_extended) { + /* Parse extended message ID from RXBUF */ + _id = ((can_buffer & CAN_BITS_15_8) << 13) /* ID 28:21 <== 15:8 */ + | ((can_buffer & CAN_BITS_23_16) >> 3) /* ID 20:13 <== 23:16 */ + | ((can_buffer & CAN_BITS_31_24) >> 19); /* ID 12:5 <== 31:24 */ + can_buffer = CAN_RXBUF(canport); + _id |= ((can_buffer & CAN_BITS_7_3) >> 3); /* ID 4:0 <== 7:3 */ + + /* Parse extended message data from RXBUF */ + data[0] = can_buffer >> 8; + data[1] = can_buffer >> 16; + data[2] = can_buffer >> 24; + if (rx_length > 3) { + can_buffer = CAN_RXBUF(canport); + data[3] = can_buffer; + data[4] = can_buffer >> 8; + data[5] = can_buffer >> 16; + data[6] = can_buffer >> 24; + } + if (rx_length > 7) { + can_buffer = CAN_RXBUF(canport); + data[7] = can_buffer; + } + } else { + /* Parse standard message ID from RXBUF */ + _id = ((can_buffer & CAN_BITS_15_8) >> 5) /* ID 10:3 <== 15:8 */ + | ((can_buffer & CAN_BITS_23_21) >> 21); /* ID 2:0 <== 23:21 */ + /* Parse standard message data from RXBUF */ + data[0] = can_buffer >> 24; + if (rx_length > 1) { + can_buffer = CAN_RXBUF(canport); + data[1] = can_buffer; + data[2] = can_buffer >> 8; + data[3] = can_buffer >> 16; + data[4] = can_buffer >> 24; + if (rx_length > 5) { + /* buffer contains data5,data6,data7 */ + can_buffer = CAN_RXBUF(canport); + data[5] = can_buffer; + data[6] = can_buffer >> 8; + data[7] = can_buffer >> 16; + } + } + } + if (id) { + *id = _id; + } + + /* + * Write 1 to acknowledge/clear the interrupt + * Note: ensure not to let the other interrupt masks be written as 1, so as + * to avoid acknowledging them. + * Note: CAN_ISR_RI is already high, but we still write '1' to it to clear it. + */ + CAN_ISR_ACKNOWLEDGE(canport, CAN_ISR_RI); + return; +} From 253a09193623460374591b3fee3ba08aeba7df7e Mon Sep 17 00:00:00 2001 From: Kevin Stefanik Date: Mon, 30 Mar 2020 15:41:48 -0400 Subject: [PATCH 036/206] pac55xx: adding memctl for flash/sram access, and clock/pll configuration functions. Merge-conflict: took _prior_ verision of CCS_MUXSELR_MASK_PIN as bracketing of (pin) seemed more correct! --- include/libopencm3/pac55xx/ccs.h | 246 +++++++++++++++++++++++++- include/libopencm3/pac55xx/memctl.h | 163 +++++++++++++++++ lib/pac55xx/Makefile | 2 + lib/pac55xx/ccs.c | 261 ++++++++++++++++++++++++++++ lib/pac55xx/memctl.c | 78 +++++++++ 5 files changed, 744 insertions(+), 6 deletions(-) create mode 100644 include/libopencm3/pac55xx/memctl.h create mode 100644 lib/pac55xx/ccs.c create mode 100644 lib/pac55xx/memctl.c diff --git a/include/libopencm3/pac55xx/ccs.h b/include/libopencm3/pac55xx/ccs.h index b3054f1d..b18f2f1c 100644 --- a/include/libopencm3/pac55xx/ccs.h +++ b/include/libopencm3/pac55xx/ccs.h @@ -4,6 +4,7 @@ * @defgroup system_defines Clock Config and System Defines * @ingroup PAC55xx_defines * @author Brian Viele + * @author Kevin Stefanik * LGPL License Terms @ref lgpl_license * @date 1 Dec 2019 * @@ -26,18 +27,95 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ -#ifndef INCLUDE_LIBOPENCM3_PAC55XX_CCS_H_ -#define INCLUDE_LIBOPENCM3_PAC55XX_CCS_H_ +#ifndef LIBOPENCM3_PAC55XX_CCS_H_ +#define LIBOPENCM3_PAC55XX_CCS_H_ #include +#include +#include +#include /**@{*/ -/** Clock Control Registers - * @defgroup clock_config_regs Clock Config Registers. - * @{*/ +/** @defgroup ccs_frequencies CCS Frequencies +@{*/ +/** Ring Oscillator Frequency */ +#define CCS_ROSC_FREQ (16000000U) +/** Internally generated and trimmed 4MHz clock */ +#define CCS_CLKREF_FREQ ( 4000000U) +/** Maximum external clock frequency */ +#define CCS_EXTCLK_MAX_FREQ (20000000U) +/**@}*/ + +/** @defgroup ccs_ctl_reg Clock Control Register +@{*/ #define CCSCTL MMIO32(SCC_BASE) +#define CCS_CTL_FRCLKMUXSEL_MASK (0x03) +#define CCS_CTL_FRCLKMUXSEL(sel) ((sel) & CCS_CTL_FRCLKMUXSEL_MASK) +#define CCS_CTL_FRCLKMUXSEL_ROSC (0) +#define CCS_CTL_FRCLKMUXSEL_CLKREF (1) +#define CCS_CTL_FRCLKMUXSEL_EXTCLK (3) +#define CCS_CTL_ROSCEN BIT2 +#define CCS_CTL_SCLKMUXSEL BIT4 +#define CCS_CTL_SCLKMUXSEL_FRCLK (0) +#define CCS_CTL_SCLKMUXSEL_PLLCLK (1) +#define CCS_CTL_CLKFAILEN BIT5 +#define CCS_CTL_CLKFAILMUXSEL BIT6 +#define CCS_CTL_CLKFAILIF BIT7 +#define CCS_CTL_LDOEN BIT8 +#define CCS_CTL_SWRESET BIT11 +#define CCS_CTL_PCLKEN BIT12 +#define CCS_CTL_ACLKEN BIT13 +#define CCS_CTL_ADCCLKEN BIT14 +#define CCS_CTL_STCLKSLPEN BIT15 +#define CCS_CTL_PCLKDIV_MASK (0x07) +#define CCS_CTL_PCLKDIV_SHIFT (16) +/* Supported PCLK divisors: 1-8 */ +#define CCS_CTL_PCLKDIV(div) (((div-1) & CCS_CTL_PCLKDIV_MASK) << CCS_CTL_PCLKDIV_SHIFT) +#define CCS_CTL_ACLKDIV_MASK (0x07) +#define CCS_CTL_ACLKDIV_SHIFT (20) +/* Supported ACLK divisors: 1-8 */ +#define CCS_CTL_ACLKDIV(div) (((div-1) & CCS_CTL_ACLKDIV_MASK) << CCS_CTL_ACLKDIV_SHIFT) +#define CCS_CTL_HCLKDIV_MASK (0x07) +#define CCS_CTL_HCLKDIV_SHIFT (24) +/* Supported HCLK divisors: 1-8 */ +#define CCS_CTL_HCLKDIV(div) (((div-1) & CCS_CTL_HCLKDIV_MASK) << CCS_CTL_HCLKDIV_SHIFT) +#define CCS_CTL_USAMODE BIT28 +#define CCS_CTL_USBMODE BIT29 +#define CCS_CTL_USCMODE BIT30 +#define CCS_CTL_USDMODE BIT31 +/**@}*/ + +/** @defgroup ccs_pllctl_reg CCS PLL Control Register +@{*/ #define CCSPLLCTL MMIO32(SCC_BASE + 0x04) +/** PLL Enable */ +#define CCS_PLLCTL_PLLEN BIT0 +/** PLL Bypass */ +#define CCS_PLLCTL_PLLBP BIT1 +#define CCS_PLLCTL_PLLOUTDIV_MASK (0x03) +#define CCS_PLLCTL_PLLOUTDIV_SHIFT (2) +/** PLL Output Divisor */ +#define CCS_PLLCTL_PLLOUTDIV(div) (((div) & CCS_PLLCTL_PLLOUTDIV_MASK) << CCS_PLLCTL_PLLOUTDIV_SHIFT) +#define CCS_PLLCTL_PLLOUTDIV1 (0) +#define CCS_PLLCTL_PLLOUTDIV2 (1) +#define CCS_PLLCTL_PLLOUTDIV4 (2) +#define CCS_PLLCTL_PLLOUTDIV8 (3) +#define CCS_PLLCTL_PLLINDIV_MASK (0x0F) +#define CCS_PLLCTL_PLLINDIV_SHIFT (4) +/** PLL Input Divisor */ +#define CCS_PLLCTL_PLLINDIV(div) (((div) & CCS_PLLCTL_PLLINDIV_MASK) << CCS_PLLCTL_PLLINDIV_SHIFT) +#define CCS_PLLCTL_PLLFBDIV_MASK (0x3FFF) +#define CCS_PLLCTL_PLLFBDIV_SHIFT (8) +/** PLL Feedback Divisor */ +#define CCS_PLLCTL_PLLFBDIV(div) (((div) & CCS_PLLCTL_PLLFBDIV_MASK) << CCS_PLLCTL_PLLFBDIV_SHIFT) +/** PLL Lock */ +#define CCS_PLLCTL_PLLLOCK BIT24 +/**@}*/ + +/** @defgroup ccs_rosctrim Ring Oscillator Trim Control Register +@{*/ +#define CCSROSCTRIM_MASK (0x7F) #define CCSROSCTRIM MMIO32(SCC_BASE + 0x08) /**@}*/ @@ -136,6 +214,162 @@ typedef enum { CCS_DSR_DS_25MA = 0x07, } ccs_drive_strength_t; /**@}*/ + /**@}*/ -#endif /* INCLUDE_LIBOPENCM3_PAC55XX_CCS_H_ */ +BEGIN_DECLS + +/** + * @defgroup ccs_api Clock Control System API + * @ingroup peripheral_apis + * @brief PAC5xx CCS Driver + * @author @htmlonly © @endhtmlonly 2020 Kevin Stefanik + * @date March 7, 2020 + * + * This library supports the CCS module in the PAC55xx SoC from Qorvo. + * + * LGPL License Terms @ref lgpl_license + */ + +/**@{*/ + +/** + * Select the source for FRCLK. + * @param[in] sel one of: + * - /ref CCS_CTL_FRCLKMUXSEL_ROSC - 16MHz ring oscillator + * - /ref CCS_CTL_FRCLKMUXSEL_CLKREF - trimmed 4MHz clock + * - /ref CCS_CTL_FRCLKMUXSEL_EXTCLK + */ +void ccs_frclkmux_select(uint32_t sel); +/** Enable the 16MHz Ring oscillator */ +void ccs_rosc_enable(void); +/** Disable the 16MHz Ring oscillator */ +void ccs_rosc_disable(void); +/** Select FRCLK for SCLK */ +void ccs_sclkmux_select_frclk(void); +/** Select PLLCLK for SCLK */ +void ccs_sclkmux_select_pllclk(void); +/** Enable Clock Fail Detection */ +void ccs_clkfail_enable(void); +/** Disable Clock Fail Detection */ +void ccs_clkfail_disable(void); +/** Select FRCLK for Clock Fail Detection */ +void ccs_clkfailmux_select_frclk(void); +/** Select PLLCLK for Clock Fail Detection */ +void ccs_clkfailmux_select_pllclk(void); +/** Enable the LDO */ +void ccs_ldo_enable(void); +/** Disable the LDO */ +void ccs_ldo_disable(void); +/** Enable the Peripheral Clock */ +void ccs_pclk_enable(void); +/** Disable the Peripheral Clock */ +void ccs_pclk_disable(void); +/** Enable the Auxiliary Clock */ +void ccs_aclk_enable(void); +/** Disable the Auxiliary Clock */ +void ccs_aclk_disable(void); +/** Enable the ADC Clock */ +void ccs_adcclk_enable(void); +/** Disable the ADC Clock */ +void ccs_adcclk_disable(void); +/** Enable SysTick clock gating in deep sleep mode */ +void ccs_stclk_sleep_enable(void); +/** Disable SysTick clock gating in deep sleep mode */ +void ccs_stclk_sleep_disable(void); +/** + * Set the divisor for the Peripheral Clock. + * @param[in] div PCLK Divisor: 1-8. + */ +void ccs_set_pclkdiv(uint32_t div); +/** + * Set the divisor for the Auxiliary Clock. + * @param[in] div ACLK Divisor: 1-8. + */ +void ccs_set_aclkdiv(uint32_t div); +/** + * Set the divisor for the AHB Clock. + * @param[in] div HCLK Divisor: 1-8. + */ +void ccs_set_hclkdiv(uint32_t div); +/** Enable the PLL */ +void ccs_pll_enable(void); +/** Disable the PLL */ +void ccs_pll_disable(void); +/** Check if the PLL is locked. + * @return true if locked. + */ +bool ccs_pll_locked(void); +/** Enable the PLL bypass */ +void ccs_pll_bypass_enable(void); +/** Disable the PLL bypass */ +void ccs_pll_bypass_disable(void); +/** + * Set the output divisor. + * @param[in] div Output divisor, one of: + * - /ref CCS_PLLCTL_PLLOUTDIV1 + * - /ref CCS_PLLCTL_PLLOUTDIV2 + * - /ref CCS_PLLCTL_PLLOUTDIV4 + * - /ref CCS_PLLCTL_PLLOUTDIV8 + */ +void ccs_pll_set_outdiv(uint32_t div); +/** + * Set the PLL input divisor. + * @param[in] div Input divisor, 1-15. + */ +void ccs_pll_set_indiv(uint32_t div); +/** + * Set the PLL feedback divisor. + * @param[in] div Feedback divisor, 4-16383. + */ +void ccs_pll_set_fbdiv(uint32_t div); +/** + * Configure the CCS PLL, enable it, and wait for lock. + * @param[in] indiv Input divisor, 1-15. + * @param[in] fbdiv Feedback divisor, 4-16383. + * @param[in] outdiv Output divisor, one of: + * - /ref CCS_PLLCTL_PLLOUTDIV1 + * - /ref CCS_PLLCTL_PLLOUTDIV2 + * - /ref CCS_PLLCTL_PLLOUTDIV4 + * - /ref CCS_PLLCTL_PLLOUTDIV8 + */ +void css_pll_config_enable(uint32_t indiv, uint32_t fbdiv, uint32_t outdiv); +/** + * Get the clock rate (in Hz) of the specified peripheral. This will pull the + * proper sources out of the clock tree and calculate the clock for the + * peripheral for return to the user, based on current settings. + * @param[in] periph Peripheral base address to get the clock rate for. + * @param[in] select Peripheral-controlled clock select value. Set to 0 when not applicable. + * @return Clock rate in Hz for the specified peripheral. 0 if undefined or error. + */ +uint32_t ccs_get_peripheral_clk_freq(uint32_t periph, uint32_t select); +/** Restores CCSCTL and CCSPLLCTL registers to default/safe values */ +void ccs_reset_clocks(void); + +/** CCS Clock Configuration structure. */ +struct ccs_clk_config { + uint32_t frclk_source; /**< FRCLK source input selection */ + uint32_t extclk_frequency; /**< EXTCLK frequency, 0 if none. */ + uint32_t sclk_source; /**< SCLK source selection */ + uint32_t pll_indiv; /**< PLL Input Divider 1-15 */ + uint32_t pll_fbdiv; /**< PLL Feedback Divider 4-16383 */ + uint32_t pll_outdiv; /**< PLL Output Divider */ + uint32_t hclkdiv; /**< Divisor from SCLK to HCLK */ + uint32_t aclkdiv; /**< Divisor from SCLK to ACLK */ + uint32_t pclkdiv; /**< Divisor from HCLK to PCLK */ + uint32_t mem_wstate; /**< Number of Flash Read wait states */ + uint32_t mem_mclkdiv; /**< Divisor from HCLK to MCLK */ + bool mem_mclksel; /**< false: ROSCLK, true: HCLK/MCLK */ + bool mem_enable_cache; /**< false: disable cache, true: enable cache */ +}; +/** + * Setup the PAC55xx clocks with the given struct. + * @param[in] config CCS Clock configuration struct /ref ccs_clk_config + */ +void ccs_configure_clocks(const struct ccs_clk_config *config); + +/**@}*/ + +END_DECLS + +#endif /* LIBOPENCM3_PAC55XX_CCS_H_ */ diff --git a/include/libopencm3/pac55xx/memctl.h b/include/libopencm3/pac55xx/memctl.h new file mode 100644 index 00000000..1a70e45d --- /dev/null +++ b/include/libopencm3/pac55xx/memctl.h @@ -0,0 +1,163 @@ +/** + * @brief Memory Controller definitions for the Qorvo PAC55xx series of microcontrollers + * + * @addtogroup PAC55xx_memctl Memory Controller Defines + * @ingroup PAC55xx_defines + * @author Kevin Stefanik + * LGPL License Terms @ref lgpl_license + * @date 17 Mar 2020 + * + * Definitions in this file come from the PAC55XX Family User Guide Rev 1.23 + * by Active-Semi dated November 19, 2019. + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Kevin Stefanik + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#ifndef LIBOPENCM3_PAC55XX_MEMCTL_H_ +#define LIBOPENCM3_PAC55XX_MEMCTL_H_ + +#include +#include +/**@{*/ + +/** @defgroup memctl_reg Memory Controller Configuration Register +@{*/ +/** Memory Controller Configuration Register */ +#define MEMCTL_MEMCTLR MMIO32(MEMCTL_BASE) +#define MEMCTL_MEMCTLR_WSTATE_MASK (0xF) +#define MEMCTL_MEMCTLR_WSTATE(ws) ((ws) & MEMCTL_MEMCTLR_WSTATE_MASK) +#define MEMCTL_MEMCTLR_MCLKDIV_MASK (0xF) +#define MEMCTL_MEMCTLR_MCLKDIV_SHIFT 4 +/* Supported MCLK divisors: 1-16 */ +#define MEMCTL_MEMCTLR_MCLKDIV(div) (((div-1) & MEMCTL_MEMCTLR_MCLKDIV_MASK) << MEMCTL_MEMCTLR_MCLKDIV_SHIFT) +#define MEMCTL_MEMCTLR_WRITEWORDCNT_MASK (0x3) +#define MEMCTL_MEMCTLR_WRITEWORDCNT_SHIFT 8 +#define MEMCTL_MEMCTLR_WRITEWORDCNT(cnt) (((cnt) & MEMCTL_MEMCTLR_WRITEWORDCNT_MASK) << MEMCTL_MEMCTLR_WRITEWORDCNT_SHIFT) +#define MEMCTL_MEMCTLR_SEIE BIT16 +#define MEMCTL_MEMCTLR_DEIE BIT17 +#define MEMCTL_MEMCTLR_INVADDRIE BIT18 +#define MEMCTL_MEMCTLR_STBY BIT19 +#define MEMCTL_MEMCTLR_ECCDIS BIT20 +#define MEMCTL_MEMCTLR_CACHEDIS BIT21 +#define MEMCTL_MEMCTLR_MCLKSEL BIT22 +/**@}*/ + +/** @defgroup memstatus_reg Memory Controller Status Register +@{*/ +/** Memory Controller Status Register */ +#define MEMCTL_MEMSTATUS MMIO32(MEMCTL_BASE + 0x0004) +#define MEMCTL_MEMSTATUS_WBUSY BIT0 +#define MEMCTL_MEMSTATUS_EBUSY BIT1 +#define MEMCTL_MEMSTATUS_WRITEWORDCNT_MASK (0x3) +#define MEMCTL_MEMSTATUS_WRITEWORDCNT_SHIFT 8 +#define MEMCTL_MEMSTATUS_WRITEWORDCNT ((MEMCTL_MEMSTATUS >> MEMCTL_MEMSTATUS_WRITEWORDCNT_SHIFT) & MEMCTL_MEMSTATUS_WRITEWORDCNT_MASK) +#define MEMCTL_MEMSTATUS_WRITEWORDCNT_4BYTES (0) +#define MEMCTL_MEMSTATUS_WRITEWORDCNT_8BYTES (1) +#define MEMCTL_MEMSTATUS_WRITEWORDCNT_12BYTES (2) +#define MEMCTL_MEMSTATUS_WRITEWORDCNT_16BYTES (3) +#define MEMCTL_MEMSTATUS_SE BIT16 +#define MEMCTL_MEMSTATUS_DE BIT17 +#define MEMCTL_MEMSTATUS_INVADDR BIT18 +/**@}*/ + +/** @defgroup flashlock_vals Flash Lock/Write Enable Register values +@{*/ +/** Flash Lock Access Register */ +#define MEMCTL_FLASHLOCK MMIO32(MEMCTL_BASE + 0x0008) +#define MEMCTL_FLASHLOCK_CLEAR (0) +#define MEMCTL_FLASHLOCK_ALLOW_FLASH_WRITE (0x43DF140A) +#define MEMCTL_FLASHLOCK_ALLOW_MEMCTL_WRITE (0xD513B490) +#define MEMCTL_FLASHLOCK_ALLOW_INFO2_SWDFUSE (0x79B4F762) +/**@}*/ + +/** Flash Page Address Register */ +#define MEMCTL_FLASHPAGE MMIO32(MEMCTL_BASE + 0x000C) +/** SWD Unlock Register */ +#define MEMCTL_SWDUNLOCK MMIO32(MEMCTL_BASE + 0x0010) + +/** @defgroup flasherase_vals Flash Erase Enable Register values +@{*/ +/** Flash Erase Enable Register */ +#define MEMCTL_FLASHERASE MMIO32(MEMCTL_BASE + 0x0020) +#define MEMCTL_FLASHERASE_PAGE_ERASE (0x8C799CA7) +#define MEMCTL_FLASHERASE_MASS_PAGE_ERASE (0x09EE76C9) +#define MEMCTL_FLASHERASE_INFO3_ERASE (0x1266FF45) +/**@}*/ + +/**@}*/ + +BEGIN_DECLS + +/** + * @defgroup memctl_api Memory Controller API + * @ingroup peripheral_apis + * @brief PAC5xx MEMCTL Driver + * @author @htmlonly © @endhtmlonly 2020 Kevin Stefanik + * @date March 7, 2020 + * + * This library supports the MEMCTL module in the PAC55xx SoC from Qorvo. + * + * LGPL License Terms @ref lgpl_license + */ + +/*@{*/ + +/** Set the number of wait states for Flash reads. + * @param[in] wstate Wait states: 0-15 + */ +void memctl_flash_set_wstate(uint32_t wstate); +/** Set the MCLK divisor. + * @param[in] div HCLK to MCLK divisor: 1-16 + */ +void memctl_flash_set_mclkdiv(uint32_t div); +/** Set WRITEWORDCOUNT to 0 to reset the Flash write data buffer */ +void memctl_flash_reset_write_buffer(void); +/** Enable Flash Standby Mode */ +void memctl_flash_standby_mode_enable(void); +/** Disable Flash Standby Mode */ +void memctl_flash_standby_mode_disable(void); +/** Enable Flash cache */ +void memctl_flash_cache_enable(void); +/** Disable Flash cache */ +void memctl_flash_cache_disable(void); +/** Select ROSCCLK as input to Flash Memory Controller */ +void memctl_flash_select_roscclk(void); +/** Select MCLK as input to Flash Memory Controller */ +void memctl_flash_select_mclk(void); +/** Enable SRAM ECC */ +void memctl_sram_ecc_enable(void); +/** Disable SRAM ECC */ +void memctl_sram_ecc_disable(void); +/** Enable SRAM ECC Single Bit Detection Interrupt */ +void memctl_sram_ecc_single_bit_interrupt_enable(void); +/** Disable SRAM ECC Single Bit Detection Interrupt */ +void memctl_sram_ecc_single_bit_interrupt_disable(void); +/** Enable SRAM ECC Dual Bit Detection Interrupt */ +void memctl_sram_ecc_dual_bit_interrupt_enable(void); +/** Disable SRAM ECC Dual Bit Detection Interrupt */ +void memctl_sram_ecc_dual_bit_interrupt_disable(void); +/** Enable Invalid Memory Access Interrupt */ +void memctl_invaddr_interrupt_enable(void); +/** Disable Invalid Memory Access Interrupt */ +void memctl_invaddr_interrupt_disable(void); + +/**@}*/ + +END_DECLS + +#endif /* LIBOPENCM3_PAC55XX_MEMCTL_H_ */ diff --git a/lib/pac55xx/Makefile b/lib/pac55xx/Makefile index 463340ba..eee1dfdd 100644 --- a/lib/pac55xx/Makefile +++ b/lib/pac55xx/Makefile @@ -36,7 +36,9 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs OBJS += can.o +OBJS += ccs.o OBJS += gpio.o +OBJS += memctl.o VPATH += ../cm3 diff --git a/lib/pac55xx/ccs.c b/lib/pac55xx/ccs.c new file mode 100644 index 00000000..0d817bbc --- /dev/null +++ b/lib/pac55xx/ccs.c @@ -0,0 +1,261 @@ +/** + * @brief PAC55xxxx CCS Driver + * @author @htmlonly © @endhtmlonly 2020 Kevin Stefanik + * @date March 7, 2020 + * + * This library supports the CCS module in the PAC55xx SoC from Qorvo. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#include +#include +#include +#include + +static volatile uint32_t ccs_extclk_frequency = 0; +static volatile uint32_t ccs_frclk_frequency = CCS_ROSC_FREQ; +static volatile uint32_t ccs_sclk_frequency = CCS_ROSC_FREQ; +static volatile uint32_t ccs_pll_clk_frequency = 0; +static volatile uint32_t ccs_hclk_frequency = CCS_ROSC_FREQ; +static volatile uint32_t ccs_aclk_frequency = CCS_ROSC_FREQ; +static volatile uint32_t ccs_pclk_frequency = CCS_ROSC_FREQ; + +void ccs_frclkmux_select(uint32_t sel) { + CCSCTL = (CCSCTL & ~CCS_CTL_FRCLKMUXSEL(CCS_CTL_FRCLKMUXSEL_MASK)) | CCS_CTL_FRCLKMUXSEL(sel); +} +void ccs_rosc_enable(void) { + CCSCTL |= CCS_CTL_ROSCEN; +} +void ccs_rosc_disable(void) { + CCSCTL &= ~CCS_CTL_ROSCEN; +} +void ccs_sclkmux_select_frclk(void) { + CCSCTL &= ~CCS_CTL_SCLKMUXSEL; +} +void ccs_sclkmux_select_pllclk(void) { + CCSCTL |= CCS_CTL_SCLKMUXSEL; +} +void ccs_clkfail_enable(void) { + CCSCTL |= CCS_CTL_CLKFAILEN; +} +void ccs_clkfail_disable(void) { + CCSCTL &= ~CCS_CTL_CLKFAILEN; +} +void ccs_clkfailmux_select_frclk(void) { + CCSCTL &= ~CCS_CTL_CLKFAILMUXSEL; +} +void ccs_clkfailmux_select_pllclk(void) { + CCSCTL |= CCS_CTL_CLKFAILMUXSEL; +} +void ccs_ldo_enable(void) { + CCSCTL |= CCS_CTL_LDOEN; +} +void ccs_ldo_disable(void) { + CCSCTL &= ~CCS_CTL_LDOEN; +} +void ccs_pclk_enable(void) { + CCSCTL |= CCS_CTL_PCLKEN; +} +void ccs_pclk_disable(void) { + CCSCTL &= ~CCS_CTL_PCLKEN; +} +void ccs_aclk_enable(void) { + CCSCTL |= CCS_CTL_ACLKEN; +} +void ccs_aclk_disable(void) { + CCSCTL &= ~CCS_CTL_ACLKEN; +} +void ccs_adcclk_enable(void) { + CCSCTL |= CCS_CTL_ADCCLKEN; +} +void ccs_adcclk_disable(void) { + CCSCTL &= ~CCS_CTL_ADCCLKEN; +} +void ccs_stclk_sleep_enable(void) { + CCSCTL |= CCS_CTL_STCLKSLPEN; +} +void ccs_stclk_sleep_disable(void) { + CCSCTL &= ~CCS_CTL_STCLKSLPEN; +} +void ccs_set_pclkdiv(uint32_t div) { + CCSCTL = (CCSCTL & ~CCS_CTL_PCLKDIV(8)) | CCS_CTL_PCLKDIV(div); +} +void ccs_set_aclkdiv(uint32_t div) { + CCSCTL = (CCSCTL & ~CCS_CTL_ACLKDIV(8)) | CCS_CTL_ACLKDIV(div); +} +void ccs_set_hclkdiv(uint32_t div) { + CCSCTL = (CCSCTL & ~CCS_CTL_HCLKDIV(8)) | CCS_CTL_HCLKDIV(div); +} +void ccs_pll_enable(void) { + CCSPLLCTL |= CCS_PLLCTL_PLLEN; +} +void ccs_pll_disable(void) { + CCSPLLCTL &= ~CCS_PLLCTL_PLLEN; +} +bool ccs_pll_locked(void) { + return (CCSPLLCTL & CCS_PLLCTL_PLLLOCK) == CCS_PLLCTL_PLLLOCK; +} +void ccs_pll_bypass_enable(void) { + CCSPLLCTL |= CCS_PLLCTL_PLLBP; +} +void ccs_pll_bypass_disable(void) { + CCSPLLCTL &= ~CCS_PLLCTL_PLLBP; +} +void ccs_pll_set_outdiv(uint32_t div) { + CCSPLLCTL = (CCSPLLCTL & ~CCS_PLLCTL_PLLOUTDIV(CCS_PLLCTL_PLLOUTDIV_MASK)) | CCS_PLLCTL_PLLOUTDIV(div); +} +void ccs_pll_set_indiv(uint32_t div) { + if (div <= 15 && div >= 1) { + CCSPLLCTL = (CCSPLLCTL & ~CCS_PLLCTL_PLLINDIV(CCS_PLLCTL_PLLINDIV_MASK)) | CCS_PLLCTL_PLLINDIV(div); + } else { + cm3_assert_not_reached(); + } +} +void ccs_pll_set_fbdiv(uint32_t div) { + if (div <= 16383 && div >= 4) { + CCSPLLCTL = (CCSPLLCTL & ~CCS_PLLCTL_PLLFBDIV(CCS_PLLCTL_PLLFBDIV_MASK)) | CCS_PLLCTL_PLLFBDIV(div); + } else { + cm3_assert_not_reached(); + } +} +void css_pll_config_enable(uint32_t indiv, uint32_t fbdiv, uint32_t outdiv) { + ccs_pll_disable(); + ccs_pll_set_fbdiv(fbdiv); + ccs_pll_set_outdiv(outdiv); + ccs_pll_set_indiv(indiv); + ccs_pll_enable(); + while (!ccs_pll_locked()) ; /* Wait for PLL lock ~500us */ +} +uint32_t ccs_get_peripheral_clk_freq(uint32_t periph, uint32_t select) { + switch (periph) { + case ADC_BASE: + return ccs_sclk_frequency; + case I2C_BASE: /* fall through */ + case USARTA_BASE: /* fall through */ + case USARTB_BASE: /* fall through */ + case USARTC_BASE: /* fall through */ + case USARTD_BASE: /* fall through */ + case CAN_BASE: /* fall through */ + case GPTIMERA_BASE: /* fall through */ + case GPTIMERB_BASE: + return ccs_pclk_frequency; + case TIMERA_BASE: /* fall through */ + case TIMERB_BASE: /* fall through */ + case TIMERC_BASE: /* fall through */ + case TIMERD_BASE: + return (select == 0) ? ccs_pclk_frequency : ccs_aclk_frequency; + case MEMCTL_BASE: + return (select == 0) ? CCS_ROSC_FREQ : ccs_hclk_frequency; + case WWDT_BASE: + return (select == 0) ? ccs_frclk_frequency : CCS_ROSC_FREQ; + case RTC_BASE: + return ccs_frclk_frequency; + case CRC_BASE: /* fall through */ + case SYS_TICK_BASE: + return ccs_hclk_frequency; + default: + cm3_assert_not_reached(); + } +} + +void ccs_reset_clocks(void) { + CCSCTL = CCS_CTL_LDOEN | CCS_CTL_ROSCEN | + CCS_CTL_PCLKEN | CCS_CTL_ACLKEN | + CCS_CTL_ADCCLKEN | CCS_CTL_STCLKSLPEN; + CCSPLLCTL = 0; +} + +void ccs_configure_clocks(const struct ccs_clk_config *config) { + MEMCTL_FLASHLOCK = MEMCTL_FLASHLOCK_ALLOW_MEMCTL_WRITE; + + ccs_reset_clocks(); /* set safe defaults */ + ccs_frclkmux_select(CCS_CTL_FRCLKMUXSEL_ROSC); + ccs_sclkmux_select_frclk(); + memctl_flash_select_roscclk(); + + if (config->mem_enable_cache) { + memctl_flash_cache_enable(); + } else { + memctl_flash_cache_disable(); + } + + ccs_frclkmux_select(CCS_CTL_FRCLKMUXSEL_CLKREF); /* switch frclk to 4MHz CLKREF */ + + switch (config->frclk_source) { + case CCS_CTL_FRCLKMUXSEL_ROSC: + ccs_frclkmux_select(CCS_CTL_FRCLKMUXSEL_ROSC); + ccs_frclk_frequency = CCS_ROSC_FREQ; + break; + case CCS_CTL_FRCLKMUXSEL_CLKREF: + ccs_frclkmux_select(CCS_CTL_FRCLKMUXSEL_CLKREF); + ccs_frclk_frequency = CCS_CLKREF_FREQ; + break; + case CCS_CTL_FRCLKMUXSEL_EXTCLK: + if (config->extclk_frequency > CCS_EXTCLK_MAX_FREQ + || config->extclk_frequency == 0) { + cm3_assert_not_reached(); + } + ccs_frclkmux_select(CCS_CTL_FRCLKMUXSEL_EXTCLK); + ccs_frclk_frequency = ccs_extclk_frequency = config->extclk_frequency; + break; + default: + cm3_assert_not_reached(); + } + + if (config->sclk_source == CCS_CTL_SCLKMUXSEL_FRCLK) { + ccs_set_hclkdiv(config->hclkdiv); + ccs_set_aclkdiv(config->aclkdiv); + memctl_flash_set_wstate(config->mem_wstate); + ccs_sclkmux_select_frclk(); + memctl_flash_set_mclkdiv(config->mem_mclkdiv); + if (config->mem_mclksel == false) { + memctl_flash_select_roscclk(); + } else { + memctl_flash_select_mclk(); + } + ccs_sclk_frequency = ccs_frclk_frequency; + } else if (config->sclk_source == CCS_CTL_SCLKMUXSEL_PLLCLK) { + css_pll_config_enable(config->pll_indiv, config->pll_fbdiv, config->pll_outdiv); + ccs_set_hclkdiv(config->hclkdiv); + ccs_set_aclkdiv(config->aclkdiv); + memctl_flash_set_wstate(config->mem_wstate); + ccs_sclkmux_select_pllclk(); + memctl_flash_set_mclkdiv(config->mem_mclkdiv); + if (config->mem_mclksel == false) { + memctl_flash_select_roscclk(); + } else { + memctl_flash_select_mclk(); + } + ccs_pll_clk_frequency = ((ccs_frclk_frequency * config->pll_fbdiv) / config->pll_indiv) >> config->pll_outdiv; + ccs_sclk_frequency = ccs_pll_clk_frequency; + } else { + cm3_assert_not_reached(); + } + ccs_set_pclkdiv(config->pclkdiv); + ccs_pclk_enable(); + ccs_aclk_enable(); + ccs_adcclk_enable(); + ccs_stclk_sleep_disable(); + + ccs_hclk_frequency = ccs_sclk_frequency / config->hclkdiv; + ccs_aclk_frequency = ccs_sclk_frequency / config->aclkdiv; + ccs_pclk_frequency = ccs_hclk_frequency / config->pclkdiv; + + MEMCTL_FLASHLOCK = MEMCTL_FLASHLOCK_CLEAR; +} diff --git a/lib/pac55xx/memctl.c b/lib/pac55xx/memctl.c new file mode 100644 index 00000000..86a66f29 --- /dev/null +++ b/lib/pac55xx/memctl.c @@ -0,0 +1,78 @@ +/** + * @brief PAC55xxxx Memory Controller Driver + * @author @htmlonly © @endhtmlonly 2020 Kevin Stefanik + * @date April 1, 2020 + * + * This library supports the Memory Controller in the PAC55xx SoC from Qorvo. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#include + +void memctl_flash_set_wstate(uint32_t wstate) { + MEMCTL_MEMCTLR = (MEMCTL_MEMCTLR & ~MEMCTL_MEMCTLR_WSTATE(MEMCTL_MEMCTLR_WSTATE_MASK)) | MEMCTL_MEMCTLR_WSTATE(wstate); +} +void memctl_flash_set_mclkdiv(uint32_t div) { + MEMCTL_MEMCTLR = (MEMCTL_MEMCTLR & ~MEMCTL_MEMCTLR_MCLKDIV(16)) | MEMCTL_MEMCTLR_MCLKDIV(div); +} +void memctl_flash_reset_write_buffer(void) { + MEMCTL_MEMCTLR = (MEMCTL_MEMCTLR & ~MEMCTL_MEMCTLR_WRITEWORDCNT(MEMCTL_MEMCTLR_WRITEWORDCNT_MASK)); +} +void memctl_flash_standby_mode_enable(void) { + MEMCTL_MEMCTLR |= MEMCTL_MEMCTLR_STBY; +} +void memctl_flash_standby_mode_disable(void) { + MEMCTL_MEMCTLR &= ~MEMCTL_MEMCTLR_STBY; +} +void memctl_flash_cache_enable(void) { + MEMCTL_MEMCTLR &= ~MEMCTL_MEMCTLR_CACHEDIS; +} +void memctl_flash_cache_disable(void) { + MEMCTL_MEMCTLR |= MEMCTL_MEMCTLR_CACHEDIS; +} +void memctl_flash_select_roscclk(void) { + MEMCTL_MEMCTLR &= ~MEMCTL_MEMCTLR_MCLKSEL; +} +void memctl_flash_select_mclk(void) { + MEMCTL_MEMCTLR |= MEMCTL_MEMCTLR_MCLKSEL; +} +void memctl_sram_ecc_enable(void) { + MEMCTL_MEMCTLR &= ~MEMCTL_MEMCTLR_ECCDIS; +} +void memctl_sram_ecc_disable(void) { + MEMCTL_MEMCTLR |= MEMCTL_MEMCTLR_ECCDIS; +} +void memctl_sram_ecc_single_bit_interrupt_enable(void) { + MEMCTL_MEMCTLR |= MEMCTL_MEMCTLR_SEIE; +} +void memctl_sram_ecc_single_bit_interrupt_disable(void) { + MEMCTL_MEMCTLR &= ~MEMCTL_MEMCTLR_SEIE; +} +void memctl_sram_ecc_dual_bit_interrupt_enable(void) { + MEMCTL_MEMCTLR |= MEMCTL_MEMCTLR_DEIE; +} +void memctl_sram_ecc_dual_bit_interrupt_disable(void) { + MEMCTL_MEMCTLR &= ~MEMCTL_MEMCTLR_DEIE; +} +void memctl_invaddr_interrupt_enable(void) { + MEMCTL_MEMCTLR |= MEMCTL_MEMCTLR_INVADDRIE; +} +void memctl_invaddr_interrupt_disable(void) { + MEMCTL_MEMCTLR &= ~MEMCTL_MEMCTLR_INVADDRIE; +} From df55d45cc19558b142ef6de42054b6e28dd7b91d Mon Sep 17 00:00:00 2001 From: Kevin Stefanik Date: Thu, 2 Apr 2020 12:34:44 -0400 Subject: [PATCH 037/206] pac55xx: add usart definitions and basic support code. --- include/libopencm3/pac55xx/usart.h | 214 +++++++++++++++++++++++++++++ lib/pac55xx/Makefile | 1 + lib/pac55xx/usart.c | 200 +++++++++++++++++++++++++++ 3 files changed, 415 insertions(+) create mode 100644 include/libopencm3/pac55xx/usart.h create mode 100644 lib/pac55xx/usart.c diff --git a/include/libopencm3/pac55xx/usart.h b/include/libopencm3/pac55xx/usart.h new file mode 100644 index 00000000..d7ce72ef --- /dev/null +++ b/include/libopencm3/pac55xx/usart.h @@ -0,0 +1,214 @@ +/** + * @brief USART definitions for the Qorvo PAC55xx series of microcontrollers + * + * @addtogroup PAC55xx_usart USART + * @ingroup PAC55xx_defines + * @author Kevin Stefanik + * LGPL License Terms @ref lgpl_license + * @date 25 Feb 2020 + * + * Definitions in this file come from the PAC55XX Family User Guide Rev 1.23 + * by Active-Semi dated November 19, 2019. TX and RX hardware buffer sizes + * are both 16 bytes. + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Kevin Stefanik + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#ifndef LIBOPENCM3_PAC55XX_USART_H_ +#define LIBOPENCM3_PAC55XX_USART_H_ + +#include +#include + +/**@{*/ + +/** @defgroup usart_registers Registers +@{*/ +/** Receive Buffer Register RO, only bits 7:0 used */ +#define USART_RBR(usart_base) MMIO32((usart_base) + 0x0000) +/** Transmit Holding Register WO, only bits 7:0 used */ +#define USART_THR(usart_base) MMIO32((usart_base) + 0x0004) +/** Divisor Latch Register RW, default 0000 0001h, only bits 15:0 used.*/ +#define USART_DLR(usart_base) MMIO32((usart_base) + 0x0008) +/** Interrupt Enable Register RW, default 0000 0000h */ +#define USART_IER(usart_base) MMIO32((usart_base) + 0x000C) +/** Interrupt Identification Register RO, default 0000 0001h */ +#define USART_IIR(usart_base) MMIO32((usart_base) + 0x0010) +/** FIFO Control Register RW, default 0000 0000h */ +#define USART_FCR(usart_base) MMIO32((usart_base) + 0x0014) +/** Line control Register RW, default 0000 0000h */ +#define USART_LCR(usart_base) MMIO32((usart_base) + 0x0018) +/** Line Status Register RO, default 0000 0060h */ +#define USART_LSR(usart_base) MMIO32((usart_base) + 0x0020) +/** Scratch Pad Register RW, only bits 7:0 used */ +#define USART_SCR(usart_base) MMIO32((usart_base) + 0x0028) +/** Enhanced Mode Register RW, default 0000 000h */ +#define USART_EFR(usart_base) MMIO32((usart_base) + 0x002C) +/**@}*/ + +/** @defgroup usart_ier_bits Interrupt Enable Register bits +@{*/ +/** Enable RX line status interrupt */ +#define USART_IER_RLSIE BIT2 +/** Enable the TX Holding Empty interrupt */ +#define USART_IER_THRIE BIT1 +/** Enable the RX Buffer Register Interrupt */ +#define USART_IER_RBRIE BIT0 +/**@}*/ + +/** @defgroup usart_iir_bits Interrupt ID Register bits +@{*/ +/** This bit is active low to indicate an interrupt is pending */ +#define USART_IIR_INTSTATUS BIT0 +/** TX Holding Register Empty */ +#define USART_IIR_TXEMPTY (0x02) +/** Receive Data Available */ +#define USART_IIR_RXAVAIL (0x04) +/** Receive Line Status */ +#define USART_IIR_RXLINESTAT (0x06) +/** Receive FIFO Character Time-out */ +#define USART_IIR_RXTIMEOUT (0x0C) +/**@}*/ + +/** @defgroup usart_fcr_bits FIFO Control Register bits +@{*/ +/** Enable both UART RX and TX FIFOs, must be set before writing rest of FCR */ +#define USART_FCR_FIFOEN BIT0 +/** RX FIFO Reset. Write 1 to clear. This bit is self-clearing. */ +#define USART_FCR_RXFIFORST BIT1 +/** TX FIFO Reset. Write 1 to clear. This bit is self-clearing. */ +#define USART_FCR_TXFIFORST BIT2 +#define USART_FCR_TXTL_MASK (3) +#define USART_FCR_TXTL_SHIFT 4 +/** TX Trigger Level */ +#define USART_FCR_TXTL(txtl) (((txtl) & USART_FCR_TXTL_MASK) << USART_FCR_TXTL_SHIFT) +#define USART_FCR_RXTL_MASK (3) +#define USART_FCR_RXTL_SHIFT 6 +/** RX Trigger Level */ +#define USART_FCR_RXTL(rxtl) (((rxtl) & USART_FCR_RXTL_MASK) << USART_FCR_RXTL_SHIFT) +#define USART_FIFO_TRIG_1CHAR (0) +#define USART_FIFO_TRIG_4CHAR (1) +#define USART_FIFO_TRIG_8CHAR (2) +#define USART_FIFO_TRIG_14CHAR (3) +/**@}*/ + +/** @defgroup usart_lcr_bits Line Control Register bits +@{*/ +/** LCR:WLS 5-bit character length */ +#define USART_DATABITS_5 (0) +/** LCR:WLS 6-bit character length */ +#define USART_DATABITS_6 (0x01) +/** LCR:WLS 7-bit character length */ +#define USART_DATABITS_7 (0x02) +/** LCR:WLS 8-bit character length */ +#define USART_DATABITS_8 (0x03) +/** LCR:PSEL & LCR:PEN Odd parity */ +#define USART_PSELPEN_ODD (0x01) +/** LCR:PSEL & LCR:PEN Even parity */ +#define USART_PSELPEN_EVEN (0x03) +/** LCR:PSEL & LCR:PEN Force 1 stick parity */ +#define USART_PSELPEN_FORCE1 (0x05) +/** LCR:PSEL & LCR:PEN Force 0 stick parity */ +#define USART_PSELPEN_FORCE0 (0x07) +/** LCR:PSEL & LCR:PEN Disable parity */ +#define USART_PARITY_DISABLE (0) +/** LCR:PSEL & LCR:PEN Odd parity */ +#define USART_PARITY_ODD USART_PSELPEN_ODD +/** LCR:PSEL & LCR:PEN Even parity */ +#define USART_PARITY_EVEN USART_PSELPEN_EVEN +/** LCR:PSEL & LCR:PEN Force 1 stick parity */ +#define USART_PARITY_FORCE1 USART_PSELPEN_FORCE1 +/** LCR:PSEL & LCR:PEN Force 0 stick parity */ +#define USART_PARITY_FORCE0 USART_PSELPEN_FORCE0 +/** LCR:SBS Use 1 stop bit */ +#define USART_STOPBITS_1 (0) +/** LCR:SBS Use 1.5 stop bit when databits is 5 */ +#define USART_STOPBITS_1P5 USART_LCR_SBS +/** LCR:SBS Use 2 stop bits */ +#define USART_STOPBITS_2 USART_LCR_SBS +#define USART_LCR_WLS_MASK (3) +/** Word length select: 5-8 databits */ +#define USART_LCR_WLS(wls) ((wls) & USART_LCR_WLS_MASK) +/** Set LCR:SBS for 1.5 or 2 stop bits, Clear for 1 stop bit */ +#define USART_LCR_SBS BIT2 +/** Enable parity checking */ +#define USART_LCR_PEN BIT3 +#define USART_LCR_PSELPEN_MASK (7) +#define USART_LCR_PSELPEN_SHIFT 3 +/** LCR:PSEL and LCR:PEN control parity */ +#define USART_LCR_PSELPEN(psel) (((psel) & USART_LCR_PSELPEN_MASK) << USART_LCR_PSELPEN_SHIFT) +/** Break Control: Enabling this bit forces TX to logic 0 */ +#define USART_LCR_BCON BIT6 +/**@}*/ + +/** @defgroup usart_lsr_bits Line Status Register bits +@{*/ +/** Receiver Data Ready */ +#define USART_LSR_RDR BIT0 +/** Overrun Error */ +#define USART_LSR_OE BIT1 +/** Parity Error */ +#define USART_LSR_PE BIT2 +/** Framing Error */ +#define USART_LSR_FE BIT3 +/** Break Interrupt */ +#define USART_LSR_BI BIT4 +/** Transmitter Holding Register Empty */ +#define USART_LSR_THRE BIT5 +/** Transmitter Empty */ +#define USART_LSR_TEMT BIT6 +/** Error in RX FIFO */ +#define USART_LSR_RXFE BIT7 +/**@}*/ + +/** TX FIFO depth */ +#define USART_TX_FIFO_DEPTH (16) +/** RX FIFO depth */ +#define USART_RX_FIFO_DETPH (16) + +/** Enable Enhanced Mode to use TX and RX FIFO trigger level interrupts */ +#define USART_EFR_ENMODE BIT4 + +/**@}*/ + +BEGIN_DECLS + +uint32_t usart_set_baudrate(uint32_t usart, uint32_t baud); +void usart_configure_lcr(uint32_t usart, uint8_t data_bits, uint8_t stop_bits, + uint8_t parity); +void usart_break_enable(uint32_t usart); +void usart_break_disable(uint32_t usart); +void usart_enhanced_enable(uint32_t usart); +void usart_enhanced_disable(uint32_t usart); +void usart_set_fifo_depth(uint32_t usart, uint8_t tx_depth, uint8_t rx_depth); +void usart_send(uint32_t usart, uint8_t data); +uint8_t usart_recv(uint32_t usart); +void usart_enable_rx_interrupt(uint32_t usart); +void usart_disable_rx_interrupt(uint32_t usart); +void usart_enable_tx_interrupt(uint32_t usart); +void usart_disable_tx_interrupt(uint32_t usart); +void usart_enable_rls_interrupt(uint32_t usart); +void usart_disable_rls_interrupt(uint32_t usart); +void usart_fifo_enable(uint32_t usart); +void usart_fifo_disable(uint32_t usart); +void usart_clear_tx_fifo(uint32_t usart); +void usart_clear_rx_fifo(uint32_t usart); + +END_DECLS + +#endif /* LIBOPENCM3_PAC55XX_USART_H_ */ diff --git a/lib/pac55xx/Makefile b/lib/pac55xx/Makefile index eee1dfdd..eac14dab 100644 --- a/lib/pac55xx/Makefile +++ b/lib/pac55xx/Makefile @@ -39,6 +39,7 @@ OBJS += can.o OBJS += ccs.o OBJS += gpio.o OBJS += memctl.o +OBJS += usart.o VPATH += ../cm3 diff --git a/lib/pac55xx/usart.c b/lib/pac55xx/usart.c new file mode 100644 index 00000000..61794fac --- /dev/null +++ b/lib/pac55xx/usart.c @@ -0,0 +1,200 @@ +/** + * @defgroup usart_api USART peripheral API + * @ingroup peripheral_apis + * @brief PAC55xxxx USART Driver + * @author @htmlonly © @endhtmlonly 2020 Kevin Stefanik + * @date February 25, 2020 + * + * This library supports the USART module in the PAC55xx SoC from Qorvo. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +#include +#include + +/**@{*/ + +/** @brief USART Set Baudrate +The baud rate is computed assuming a peripheral clock of 150MHz. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +@param[in] baud unsigned 32 bit. Baud rate specified in Hz. +@return Actual baud rate. +*/ +uint32_t usart_set_baudrate(uint32_t usart, uint32_t baud) { + /* TODO Assumes 150MHz PCLK. Update this to ccs_get_peripheral_freq() like on other platforms */ + const uint32_t pclk = 150000000; + uint32_t denom = (baud << 4); /* denominator is baud * 16. */ + uint32_t dlr = 0xFFFFu & ((pclk + denom / 2) / denom); + USART_DLR(usart) = dlr; + return pclk / (dlr << 4); /* Baud Rate = PCLK / (16 * UARTADLR) */ +} + +/** @brief USART Configure Line Control Register +This register sets the data bits, stop bits, and parity +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +@param[in] data_bits unsigned 8 bit. One of USART_DATABITS_5/6/7/8. +@param[in] stop_bits unsigned 8 bit. One of USART_STOPBITS_1/1P5/2. +@param[in] parity unsigned 8 bit. One of USART_PARITY_DISABLE/ODD/EVEN/FORCE1/FORCE0 +*/ +void usart_configure_lcr(uint32_t usart, uint8_t data_bits, uint8_t stop_bits, + uint8_t parity) { + USART_LCR(usart) = USART_LCR_WLS(data_bits) + | ((stop_bits==USART_STOPBITS_2) ? USART_LCR_SBS : 0) + | USART_LCR_PSELPEN(parity); +} + +/** @brief Enable Break Control +Enables break control bit that forces TX pin to logic low. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_break_enable(uint32_t usart) { + USART_LCR(usart) |= USART_LCR_BCON; +} + +/** @brief Disable Break Control +Disables break control bit that forces TX pin to logic low. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_break_disable(uint32_t usart) { + USART_LCR(usart) &= ~USART_LCR_BCON; +} + +/** @brief Enable Enhanced Mode +Enable enhanced mode to generate interrupts when FIFO thresholds in FCR are reached. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_enhanced_enable(uint32_t usart) { + USART_EFR(usart) = USART_EFR_ENMODE; +} + +/** @brief Disable Enhanced Mode +Disable enhanced mode to generate interrupts when FIFO thresholds in FCR are reached. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_enhanced_disable(uint32_t usart) { + USART_EFR(usart) &= ~USART_EFR_ENMODE; +} + +/** @brief Enable FIFOs +Enable both TX and RX FIFOs. This must be set before setting the trigger levels. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_fifo_enable(uint32_t usart) { + USART_FCR(usart) |= USART_FCR_FIFOEN; +} + +/** @brief Disable FIFOs +Disable both TX and RX FIFOs. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_fifo_disable(uint32_t usart) { + USART_FCR(usart) &= ~USART_FCR_FIFOEN; +} + +/** Set the TX and RX FIFO depth. This function also enables the FIFOs if not already. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +@param[in] tx_depth unsigned 8 bit. One of USART_FIFO_TRIG_1/2/4/14CHAR. +@param[in] rx_depth unsigned 8 bit. One of USART_FIFO_TRIG_1/2/4/14CHAR. +*/ +void usart_set_fifo_depth(uint32_t usart, uint8_t tx_depth, uint8_t rx_depth) { + USART_FCR(usart) |= USART_FCR_FIFOEN; + USART_FCR(usart) = USART_FCR_TXTL(tx_depth) | USART_FCR_RXTL(rx_depth) | USART_FCR_FIFOEN; +} + +/** @brief Write byte to TX FIFO +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +@param[in] data unsigned 8 bit. Data to write to the TX FIFO. +*/ +void usart_send(uint32_t usart, uint8_t data) { + USART_THR(usart) = (uint32_t)data; +} + +/** @brief Read byte from the RX FIFO +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +@return Data read from the RX FIFO. +*/ +uint8_t usart_recv(uint32_t usart) { + return (uint8_t)USART_RBR(usart); +} + +/** @brief Enable RX Interrupts +Enable both the Receive Data Available and Character Timeout interrupts. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_enable_rx_interrupt(uint32_t usart) { + USART_IER(usart) |= USART_IER_RBRIE; +} + +/** @brief Disable RX Interrupts +Disable both the Receive Data Available and Character Timeout interrupts. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_disable_rx_interrupt(uint32_t usart) { + USART_IER(usart) &= ~USART_IER_RBRIE; +} + +/** @brief Enable TX Interrupt +Enable the TX Holding Register Empty interrupt. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_enable_tx_interrupt(uint32_t usart) { + USART_IER(usart) |= USART_IER_THRIE; +} + +/** @brief Disable TX Interrupt +Disable the TX Holding Register Empty interrupt. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_disable_tx_interrupt(uint32_t usart) { + USART_IER(usart) &= ~USART_IER_THRIE; +} + +/** @brief Enable RX Line Status Interrupt +Enable the RX Line Status interrupt. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_enable_rls_interrupt(uint32_t usart) { + USART_IER(usart) |= USART_IER_RLSIE; +} + +/** @brief Disable RX Line Status Interrupt +Disable the RX Line Status interrupt. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_disable_rls_interrupt(uint32_t usart) { + USART_IER(usart) &= ~USART_IER_RLSIE; +} + +/** @brief Clear the TX FIFO +Clears the TX FIFO. The bit is self-clearing. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_clear_tx_fifo(uint32_t usart) { + USART_FCR(usart) |= USART_FCR_TXFIFORST; +} + +/** @brief Clear the RX FIFO +Clears the RX FIFO. The bit is self-clearing. +@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base +*/ +void usart_clear_rx_fifo(uint32_t usart) { + USART_FCR(usart) |= USART_FCR_RXFIFORST; +} + +/**@}*/ From e41ac6ea711c86f3b029d3728c665a3712c3dca9 Mon Sep 17 00:00:00 2001 From: Brian Viele Date: Fri, 6 Mar 2020 00:57:21 -0500 Subject: [PATCH 038/206] stm32: added peripheral clock get helpers for all stm32 platforms. Allows for abstraction for code that's dependent on knowing the source clock for a peripheral. Implemented a few core peripherals that tend to have clock tree differences between platforms (USART, timers, I2C, SPI). --- .../libopencm3/stm32/common/rcc_common_all.h | 7 + include/libopencm3/stm32/f0/rcc.h | 14 ++ include/libopencm3/stm32/f1/rcc.h | 5 +- include/libopencm3/stm32/f2/rcc.h | 4 + include/libopencm3/stm32/f3/rcc.h | 7 + include/libopencm3/stm32/f4/rcc.h | 6 +- include/libopencm3/stm32/f7/rcc.h | 9 + include/libopencm3/stm32/g0/rcc.h | 10 +- include/libopencm3/stm32/h7/rcc.h | 34 +++- include/libopencm3/stm32/l0/rcc.h | 5 +- include/libopencm3/stm32/l1/rcc.h | 4 + include/libopencm3/stm32/l4/rcc.h | 4 + lib/stm32/common/rcc_common_all.c | 12 ++ lib/stm32/f0/rcc.c | 68 +++++++ lib/stm32/f1/rcc.c | 40 ++++ lib/stm32/f2/rcc.c | 52 ++++++ lib/stm32/f3/rcc.c | 82 ++++++++ lib/stm32/f4/rcc.c | 52 ++++++ lib/stm32/f7/rcc.c | 87 +++++++++ lib/stm32/g0/rcc.c | 65 ++++++- lib/stm32/h7/rcc.c | 176 ++++++++++-------- lib/stm32/l0/rcc.c | 77 ++++++++ lib/stm32/l1/rcc.c | 52 ++++++ lib/stm32/l4/rcc.c | 82 ++++++++ 24 files changed, 860 insertions(+), 94 deletions(-) diff --git a/include/libopencm3/stm32/common/rcc_common_all.h b/include/libopencm3/stm32/common/rcc_common_all.h index 49837137..2db980ff 100644 --- a/include/libopencm3/stm32/common/rcc_common_all.h +++ b/include/libopencm3/stm32/common/rcc_common_all.h @@ -67,6 +67,13 @@ bool rcc_is_osc_ready(enum rcc_osc osc); */ void rcc_wait_for_osc_ready(enum rcc_osc osc); +/** + * This will return the divisor 1/2/4/8/16/64/128/256/512 which is set as a + * 4-bit value, typically used for hpre and other prescalers. + * @param div_val Masked and shifted divider value from register (e.g. RCC_CFGR) + */ +uint16_t rcc_get_div_from_hpre(uint8_t div_val); + END_DECLS /**@}*/ diff --git a/include/libopencm3/stm32/f0/rcc.h b/include/libopencm3/stm32/f0/rcc.h index 3bd4f58f..e0663eb5 100644 --- a/include/libopencm3/stm32/f0/rcc.h +++ b/include/libopencm3/stm32/f0/rcc.h @@ -149,6 +149,7 @@ Control #define RCC_CFGR_PPRE_SHIFT 8 #define RCC_CFGR_PPRE (7 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_MASK 0x7 /** @defgroup rcc_cfgr_apb1pre RCC_CFGR APB prescale Factors @{*/ #define RCC_CFGR_PPRE_NODIV (0 << RCC_CFGR_PPRE_SHIFT) @@ -160,6 +161,7 @@ Control #define RCC_CFGR_HPRE_SHIFT 4 #define RCC_CFGR_HPRE (0xf << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_MASK 0xf /** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale Factors @{*/ #define RCC_CFGR_HPRE_NODIV (0x0 << RCC_CFGR_HPRE_SHIFT) @@ -383,6 +385,12 @@ Control /**@}*/ /* --- RCC_CFGR3 values ---------------------------------------------------- */ +#define RCC_CFGR3_USART3SW_SHIFT 18 +#define RCC_CFGR3_USART3SW (3 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART3SW_PCLK (0 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART3SW_SYSCLK (1 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART3SW_LSE (2 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART3SW_HSI (3 << RCC_CFGR3_USART2SW_SHIFT) #define RCC_CFGR3_USART2SW_SHIFT 16 #define RCC_CFGR3_USART2SW (3 << RCC_CFGR3_USART2SW_SHIFT) @@ -403,6 +411,8 @@ Control #define RCC_CFGR3_USART1SW_LSE (2 << RCC_CFGR3_USART1SW_SHIFT) #define RCC_CFGR3_USART1SW_HSI (3 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USARTxSW_MASK 3 + /* --- RCC_CFGR3 values ---------------------------------------------------- */ #define RCC_CR2_HSI48CAL_SHIFT 24 @@ -579,6 +589,10 @@ enum rcc_osc rcc_usb_clock_source(void); void rcc_clock_setup_in_hse_8mhz_out_48mhz(void); void rcc_clock_setup_in_hsi_out_48mhz(void); void rcc_clock_setup_in_hsi48_out_48mhz(void); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index f497d110..55cd54b0 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -790,7 +790,10 @@ void rcc_clock_setup_in_hse_25mhz_out_72mhz(void) LIBOPENCM3_DEPRECATED("use rcc */ void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); void rcc_backupdomain_reset(void); - +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS #endif diff --git a/include/libopencm3/stm32/f2/rcc.h b/include/libopencm3/stm32/f2/rcc.h index 1831feb0..d758d318 100644 --- a/include/libopencm3/stm32/f2/rcc.h +++ b/include/libopencm3/stm32/f2/rcc.h @@ -850,6 +850,10 @@ void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t rcc_system_clock_source(void); void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock); void rcc_backupdomain_reset(void); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS diff --git a/include/libopencm3/stm32/f3/rcc.h b/include/libopencm3/stm32/f3/rcc.h index fd6fe286..f77df32e 100644 --- a/include/libopencm3/stm32/f3/rcc.h +++ b/include/libopencm3/stm32/f3/rcc.h @@ -436,6 +436,9 @@ #define RCC_CFGR3_UART1SW_LSE 0x2 #define RCC_CFGR3_UART1SW_HSI 0x3 +/* Shared mask for UART clock source. */ +#define RCC_CFGR3_UARTxSW_MASK 0x3 + /* --- Variable definitions ------------------------------------------------ */ extern uint32_t rcc_ahb_frequency; @@ -655,6 +658,10 @@ uint32_t rcc_get_i2c_clocks(void); void rcc_usb_prescale_1_5(void); void rcc_usb_prescale_1(void); void rcc_adc_prescale(uint32_t prescale1, uint32_t prescale2); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS diff --git a/include/libopencm3/stm32/f4/rcc.h b/include/libopencm3/stm32/f4/rcc.h index e957b06c..31cce195 100644 --- a/include/libopencm3/stm32/f4/rcc.h +++ b/include/libopencm3/stm32/f4/rcc.h @@ -1127,8 +1127,12 @@ void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t rcc_system_clock_source(void); void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); void __attribute__((deprecated("Use rcc_clock_setup_pll as direct replacement"))) rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS #endif -/**@}*/ \ No newline at end of file +/**@}*/ diff --git a/include/libopencm3/stm32/f7/rcc.h b/include/libopencm3/stm32/f7/rcc.h index bace1c3a..2f3bcc73 100644 --- a/include/libopencm3/stm32/f7/rcc.h +++ b/include/libopencm3/stm32/f7/rcc.h @@ -646,6 +646,10 @@ #define RCC_DCKCFGR2_UART2SEL_SHIFT 2 #define RCC_DCKCFGR2_UART1SEL_MASK 0x3 #define RCC_DCKCFGR2_UART1SEL_SHIFT 0 +#define RCC_DCKCFGR2_UARTxSEL_PCLK 0 +#define RCC_DCKCFGR2_UARTxSEL_SYSCLK 1 +#define RCC_DCKCFGR2_UARTxSEL_HSI 2 + extern uint32_t rcc_ahb_frequency; extern uint32_t rcc_apb1_frequency; @@ -986,6 +990,11 @@ void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t rcc_system_clock_source(void); void rcc_clock_setup_hse(const struct rcc_clock_scale *clock, uint32_t hse_mhz); void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); + END_DECLS /**@}*/ diff --git a/include/libopencm3/stm32/g0/rcc.h b/include/libopencm3/stm32/g0/rcc.h index 77409f7f..dd3d4acf 100644 --- a/include/libopencm3/stm32/g0/rcc.h +++ b/include/libopencm3/stm32/g0/rcc.h @@ -251,7 +251,7 @@ #define RCC_PLLCFGR_PLLM_SHIFT 0x4 #define RCC_PLLCFGR_PLLM_MASK 0x7 /** @defgroup rcc_pllcfgr_pllm PLLM - * @brief Division factor M [1..8] for PLL input clock. Input frequency must be between 4mhz and 16mhz. + * @brief Division factor M [1..8] for PLL input clock. Input frequency must be between 4mhz and 16mhz. @{*/ #define RCC_PLLCFGR_PLLM_DIV(x) ((x)-1) /**@}*/ @@ -629,7 +629,7 @@ extern uint32_t rcc_apb1_frequency; #define rcc_apb2_frequency rcc_apb1_frequency /* --- Function prototypes ------------------------------------------------- */ - + #define _REG_BIT(offset, bit) (((offset) << 5) + (bit)) enum rcc_osc { @@ -778,7 +778,7 @@ enum rcc_periph_rst { struct rcc_clock_scale { enum rcc_osc sysclock_source; - + /* PLL as sysclock source cfg */ uint8_t pll_source; uint8_t pll_div; @@ -841,6 +841,10 @@ void rcc_clock_setup(const struct rcc_clock_scale *clock); void rcc_set_rng_clk_div(uint32_t rng_div); void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS diff --git a/include/libopencm3/stm32/h7/rcc.h b/include/libopencm3/stm32/h7/rcc.h index 8593d076..ebef3935 100644 --- a/include/libopencm3/stm32/h7/rcc.h +++ b/include/libopencm3/stm32/h7/rcc.h @@ -409,6 +409,7 @@ LGPL License Terms @ref lgpl_license #define RCC_D2CCIP2R_RNGSEL_LSI 3 #define RCC_D2CCIP2R_USART16SEL_PCLK2 0 #define RCC_D2CCIP2R_USART234578SEL_PCLK1 0 +#define RCC_D2CCIP2R_USARTSEL_PCLK 0 #define RCC_D2CCIP2R_USARTSEL_PLL2Q 1 #define RCC_D2CCIP2R_USARTSEL_PLL3Q 2 #define RCC_D2CCIP2R_USARTSEL_HSI 3 @@ -732,13 +733,34 @@ void rcc_clock_setup_pll(const struct rcc_pll_config *config); uint32_t rcc_get_bus_clk_freq(enum rcc_clock_source source); /** - * Get the clock rate (in Hz) of the specified peripheral. This will pull the - * proper sources out of the clock tree and calculate the clock for the - * peripheral for return to the user, based on current settings. - * @param[in] periph Peripheral base address to get the clock rate for. - * @return Clock rate in Hz for the specified peripheral. 0 if undefined or error. + * Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for (e.g. USART1_BASE). */ -uint32_t rcc_get_peripheral_clk_freq(uint32_t periph); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); + +/** + * Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIMER to get clock frequency for (e.g. TIM1_BASE). + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer); + +/** + * Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for (e.g. I2C1_BASE). + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); + +/** + * Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi); + +/** + * Get the peripheral clock speed for the FDCAN device at base specified. + * @param fdcan Base address of FDCAN to get clock frequency for (e.g. FDCAN1_BASE). + */ +uint32_t rcc_get_fdcan_clk_freq(uint32_t fdcan); /** * Set the clksel value for the specified peripheral. This code will determine diff --git a/include/libopencm3/stm32/l0/rcc.h b/include/libopencm3/stm32/l0/rcc.h index 287f6b99..6aa9d4b4 100644 --- a/include/libopencm3/stm32/l0/rcc.h +++ b/include/libopencm3/stm32/l0/rcc.h @@ -709,11 +709,14 @@ void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); void rcc_set_msi_range(uint32_t msi_range); void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel); - void rcc_set_lptim1_sel(uint32_t lptim1_sel); void rcc_set_lpuart1_sel(uint32_t lpupart1_sel); void rcc_set_usart1_sel(uint32_t usart1_sel); void rcc_set_usart2_sel(uint32_t usart2_sel); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h index cf8a7197..220d1f88 100644 --- a/include/libopencm3/stm32/l1/rcc.h +++ b/include/libopencm3/stm32/l1/rcc.h @@ -660,6 +660,10 @@ void rcc_clock_setup_msi(const struct rcc_clock_scale *clock); void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock); void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); void rcc_backupdomain_reset(void); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS diff --git a/include/libopencm3/stm32/l4/rcc.h b/include/libopencm3/stm32/l4/rcc.h index 09b9d9bf..24f9b391 100644 --- a/include/libopencm3/stm32/l4/rcc.h +++ b/include/libopencm3/stm32/l4/rcc.h @@ -987,6 +987,10 @@ void rcc_set_clock48_source(uint32_t clksel); void rcc_enable_rtc_clock(void); void rcc_disable_rtc_clock(void); void rcc_set_rtc_clock_source(enum rcc_osc clk); +uint32_t rcc_get_usart_clk_freq(uint32_t usart); +uint32_t rcc_get_timer_clk_freq(uint32_t timer); +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); +uint32_t rcc_get_spi_clk_freq(uint32_t spi); END_DECLS diff --git a/lib/stm32/common/rcc_common_all.c b/lib/stm32/common/rcc_common_all.c index e5068114..4cbe0a81 100644 --- a/lib/stm32/common/rcc_common_all.c +++ b/lib/stm32/common/rcc_common_all.c @@ -270,6 +270,18 @@ void rcc_osc_bypass_disable(enum rcc_osc osc) } } +/* This is a helper to calculate dividers that go 2/4/8/16/64/128/256/512. + * These dividers also use the top bit as an "enable". This is tyipcally + * used for AHB and other system clock prescaler. */ +uint16_t rcc_get_div_from_hpre(uint8_t div_val) { + if (div_val < 0x8) { + return 1; + } else if (div_val <= 0x0b /* DIV16 */) { + return (1U << (div_val - 7)); + } else { + return (1U << (div_val - 6)); + } +} /**@}*/ #undef _RCC_REG diff --git a/lib/stm32/f0/rcc.c b/lib/stm32/f0/rcc.c index 182bdd28..5a679124 100644 --- a/lib/stm32/f0/rcc.c +++ b/lib/stm32/f0/rcc.c @@ -625,5 +625,73 @@ void rcc_clock_setup_in_hsi48_out_48mhz(void) rcc_apb1_frequency = 48000000; rcc_ahb_frequency = 48000000; } + +static uint32_t rcc_get_usart_clksel_freq(uint8_t shift) { + uint8_t clksel = (RCC_CFGR3 >> shift) & RCC_CFGR3_USARTxSW_MASK; + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + switch (clksel) { + case RCC_CFGR3_USART1SW_PCLK: + return rcc_apb1_frequency; + case RCC_CFGR3_USART1SW_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CFGR3_USART1SW_HSI: + return 8000000U; + } + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + if (usart == USART1_BASE) { + return rcc_get_usart_clksel_freq(RCC_CFGR3_USART1SW_SHIFT); + } else if (usart == USART2_BASE) { + return rcc_get_usart_clksel_freq(RCC_CFGR3_USART2SW_SHIFT); + } else if (usart == USART3_BASE) { + return rcc_get_usart_clksel_freq(RCC_CFGR3_USART3SW_SHIFT); + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer __attribute__((unused))) +{ + uint8_t ppre = (RCC_CFGR >> RCC_CFGR_PPRE_SHIFT) & RCC_CFGR_PPRE_MASK; + return (ppre == RCC_CFGR_PPRE_NODIV) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c) +{ + if (i2c == I2C1_BASE) { + if (RCC_CFGR3 & RCC_CFGR3_I2C1SW) { + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + } else { + return 8000000U; + } + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi __attribute__((unused))) { + return rcc_apb1_frequency; +} /**@}*/ diff --git a/lib/stm32/f1/rcc.c b/lib/stm32/f1/rcc.c index 78c4f840..ba64d604 100644 --- a/lib/stm32/f1/rcc.c +++ b/lib/stm32/f1/rcc.c @@ -1289,5 +1289,45 @@ void rcc_backupdomain_reset(void) RCC_BDCR &= ~RCC_BDCR_BDRST; } +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + if (usart == USART1_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer) +{ + /* Handle APB1 timer clocks. */ + if (timer >= TIM2_BASE && timer <= TIM14_BASE) { + uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; + return (ppre1 == RCC_CFGR_PPRE1_HCLK_NODIV) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; + } else { + uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; + return (ppre2 == RCC_CFGR_PPRE2_HCLK_NODIV) ? rcc_apb2_frequency + : 2 * rcc_apb2_frequency; + } + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused))) +{ + return rcc_apb1_frequency; +} /**@}*/ diff --git a/lib/stm32/f2/rcc.c b/lib/stm32/f2/rcc.c index 80db1935..12567874 100644 --- a/lib/stm32/f2/rcc.c +++ b/lib/stm32/f2/rcc.c @@ -389,4 +389,56 @@ void rcc_backupdomain_reset(void) RCC_BDCR &= ~RCC_BDCR_BDRST; } + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + if (usart == USART1_BASE || usart == USART6_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer) +{ + /* Handle APB1 timer clocks. */ + if (timer >= TIM2_BASE && timer <= TIM14_BASE) { + uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; + return (ppre1 == RCC_CFGR_PPRE_DIV_NONE) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; + } else { + uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; + return (ppre2 == RCC_CFGR_PPRE_DIV_NONE) ? rcc_apb2_frequency + : 2 * rcc_apb2_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused))) +{ + return rcc_apb1_frequency; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi) { + if (spi == SPI1_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} /**@}*/ diff --git a/lib/stm32/f3/rcc.c b/lib/stm32/f3/rcc.c index 9d5fc6d5..831ce263 100644 --- a/lib/stm32/f3/rcc.c +++ b/lib/stm32/f3/rcc.c @@ -493,5 +493,87 @@ void rcc_adc_prescale(uint32_t prescale1, uint32_t prescale2) RCC_CFGR2 &= ~(clear_mask); RCC_CFGR2 |= (set); } + +static uint32_t rcc_get_usart_clksel_freq(uint32_t apb_clk, uint8_t shift) { + uint8_t clksel = (RCC_CFGR3 >> shift) & RCC_CFGR3_UARTxSW_MASK; + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + switch (clksel) { + case RCC_CFGR3_UART1SW_PCLK: + return apb_clk; + case RCC_CFGR3_UART1SW_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CFGR3_UART1SW_HSI: + return 8000000U; + } + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + /* Handle values with selectable clocks. */ + if (usart == USART1_BASE) { + return rcc_get_usart_clksel_freq(rcc_apb2_frequency, RCC_CFGR3_UART1SW_SHIFT); + } else if (usart == USART2_BASE) { + return rcc_get_usart_clksel_freq(rcc_apb1_frequency, RCC_CFGR3_UART2SW_SHIFT); + } else if (usart == USART3_BASE) { + return rcc_get_usart_clksel_freq(rcc_apb1_frequency, RCC_CFGR3_UART3SW_SHIFT); + } else if (usart == UART4_BASE) { + return rcc_get_usart_clksel_freq(rcc_apb1_frequency, RCC_CFGR3_UART4SW_SHIFT); + } else { /* UART5 */ + return rcc_get_usart_clksel_freq(rcc_apb1_frequency, RCC_CFGR3_UART5SW_SHIFT); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer) +{ + /* Handle APB1 timer clocks. */ + if (timer >= TIM2_BASE && timer <= TIM7_BASE) { + uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; + return (ppre1 == RCC_CFGR_PPRE1_DIV_NONE) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; + } else { + uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; + return (ppre2 == RCC_CFGR_PPRE2_DIV_NONE) ? rcc_apb2_frequency + : 2 * rcc_apb2_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c) +{ + if (i2c == I2C1_BASE) { + if (RCC_CFGR3 & RCC_CFGR3_I2C1SW) { + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + } else { + return 8000000U; + } + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi) { + if (spi == SPI1_BASE || spi == SPI4_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} /**@}*/ diff --git a/lib/stm32/f4/rcc.c b/lib/stm32/f4/rcc.c index ba3f2469..6b4da4ac 100644 --- a/lib/stm32/f4/rcc.c +++ b/lib/stm32/f4/rcc.c @@ -791,4 +791,56 @@ void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock) rcc_clock_setup_pll(clock); } +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + /* Handle values with selectable clocks. */ + if (usart == USART1_BASE || usart == USART6_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer) +{ + /* Handle APB1 timer clocks. */ + if (timer >= TIM2_BASE && timer <= TIM14_BASE) { + uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; + return (ppre1 == RCC_CFGR_PPRE_DIV_NONE) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; + } else { + uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; + return (ppre2 == RCC_CFGR_PPRE_DIV_NONE) ? rcc_apb2_frequency + : 2 * rcc_apb2_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused))) +{ + return rcc_apb1_frequency; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi) { + if (spi == SPI2_BASE || spi == SPI3_BASE) { + return rcc_apb1_frequency; + } else { + return rcc_apb2_frequency; + } +} /**@}*/ diff --git a/lib/stm32/f7/rcc.c b/lib/stm32/f7/rcc.c index 4246036a..99a697d4 100644 --- a/lib/stm32/f7/rcc.c +++ b/lib/stm32/f7/rcc.c @@ -484,4 +484,91 @@ void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock) rcc_apb2_frequency = clock->apb2_frequency; } +static uint32_t rcc_usart_i2c_clksel_freq(uint32_t apb_clk, uint8_t shift) { + uint8_t clksel = (RCC_DCKCFGR2 >> shift) & RCC_DCKCFGR2_UART1SEL_MASK; + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + switch (clksel) { + case RCC_DCKCFGR2_UARTxSEL_PCLK: + return apb_clk; + case RCC_DCKCFGR2_UARTxSEL_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_DCKCFGR2_UARTxSEL_HSI: + return 16000000U; + default: + cm3_assert_not_reached(); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + /* F7 is highly configurable, every USART can be configured in DCKCFGR2. */ + if (usart == USART1_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb2_frequency, RCC_DCKCFGR2_UART1SEL_SHIFT); + } else if (usart == USART2_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_UART2SEL_SHIFT); + } else if (usart == USART3_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_UART3SEL_SHIFT); + } else if (usart == UART4_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_UART4SEL_SHIFT); + } else if (usart == UART5_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_UART5SEL_SHIFT); + } else if (usart == USART6_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb2_frequency, RCC_DCKCFGR2_USART6SEL_SHIFT); + } else if (usart == UART7_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_UART7SEL_SHIFT); + } else { /* UART8 */ + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_UART8SEL_SHIFT); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer) +{ + /* Handle APB1 timer clocks. */ + if (timer >= TIM2_BASE && timer <= TIM14_BASE) { + uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; + return (ppre1 == RCC_CFGR_PPRE_DIV_NONE) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; + } else { + uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; + return (ppre2 == RCC_CFGR_PPRE_DIV_NONE) ? rcc_apb2_frequency + : 2 * rcc_apb2_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused))) +{ + if (i2c == I2C1_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_I2C1SEL_SHIFT); + } else if (i2c == I2C2_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_I2C2SEL_SHIFT); + } else if (i2c == I2C3_BASE) { + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_I2C3SEL_SHIFT); + } else { /* I2C4 */ + return rcc_usart_i2c_clksel_freq(rcc_apb1_frequency, RCC_DCKCFGR2_I2C4SEL_SHIFT); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi) { + if (spi == SPI2_BASE || spi == SPI3_BASE) { + return rcc_apb1_frequency; + } else { + return rcc_apb2_frequency; + } +} /**@}*/ diff --git a/lib/stm32/g0/rcc.c b/lib/stm32/g0/rcc.c index c3f157ab..9e05bb93 100644 --- a/lib/stm32/g0/rcc.c +++ b/lib/stm32/g0/rcc.c @@ -437,7 +437,7 @@ void rcc_set_mcopre(uint32_t mcopre) * @param clock rcc_clock_scale with desired parameters */ void rcc_clock_setup(const struct rcc_clock_scale *clock) -{ +{ if (clock->sysclock_source == RCC_PLL) { enum rcc_osc pll_source; @@ -547,4 +547,67 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel) RCC_CCIPR = reg32 | (sel << shift); } +static uint32_t rcc_get_clksel_freq(uint8_t shift) { + uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_USART1SEL_MASK; + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + switch (clksel) { + case RCC_CCIPR_USART1SEL_PCLK: + return rcc_apb1_frequency; + case RCC_CCIPR_USART1SEL_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CCIPR_USART1SEL_HSI16: + return 16000000U; + } + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + if (usart == USART1_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_USART1SEL_SHIFT); + } else if (usart == USART2_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_USART2SEL_SHIFT); + } else if (usart == LPUART1_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_LPUART1SEL_SHIFT); + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer __attribute__((unused))) +{ + uint8_t ppre = (RCC_CFGR >> RCC_CFGR_PPRE_SHIFT) & RCC_CFGR_PPRE_MASK; + return (ppre == RCC_CFGR_PPRE_NODIV) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused))) +{ + if (i2c == I2C1_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_I2C1SEL_SHIFT); + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi __attribute__((unused))) { + return rcc_apb1_frequency; +} + /**@}*/ diff --git a/lib/stm32/h7/rcc.c b/lib/stm32/h7/rcc.c index 0977ebdf..71f7fae9 100644 --- a/lib/stm32/h7/rcc.c +++ b/lib/stm32/h7/rcc.c @@ -265,87 +265,101 @@ uint32_t rcc_get_bus_clk_freq(enum rcc_clock_source source) { } } -uint32_t rcc_get_peripheral_clk_freq(uint32_t periph) { - uint32_t clksel; - switch (periph) { - case FDCAN1_BASE: - case FDCAN2_BASE: - clksel = (RCC_D2CCIP1R >> RCC_D2CCIP1R_FDCANSEL_SHIFT) & RCC_D2CCIP1R_FDCANSEL_MASK; - if (clksel == RCC_D2CCIP1R_FDCANSEL_HSE) { - return rcc_clock_tree.hse_khz * HZ_PER_KHZ; - } else if (clksel == RCC_D2CCIP1R_FDCANSEL_PLL1Q) { - return rcc_clock_tree.pll1.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP1R_FDCANSEL_PLL2Q) { - return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ; - } else { - return 0U; - } - case SPI1_BASE: - case SPI2_BASE: - case SPI3_BASE: - clksel = (RCC_D2CCIP1R >> RCC_D2CCIP1R_SPI123SEL_SHIFT) & RCC_D2CCIP1R_SPI123SEL_MASK; - if (clksel == RCC_D2CCIP1R_SPI123SEL_PLL1Q) { - return rcc_clock_tree.pll1.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP1R_SPI123SEL_PLL2P) { - return rcc_clock_tree.pll2.p_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP1R_SPI123SEL_PLL3P) { - return rcc_clock_tree.pll3.p_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP1R_SPI123SEL_PERCK) { - return rcc_get_bus_clk_freq(RCC_PERCLK); - } else { - return 0U; - } - case SPI4_BASE: - case SPI5_BASE: - clksel = (RCC_D2CCIP1R >> RCC_D2CCIP1R_SPI45SEL_SHIFT) & RCC_D2CCIP1R_SPI45SEL_MASK; - if (clksel == RCC_D2CCIP1R_SPI45SEL_APB4){ - return rcc_get_bus_clk_freq(RCC_APB1CLK); - } else if (clksel == RCC_D2CCIP1R_SPI45SEL_PLL2Q){ - return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP1R_SPI45SEL_PLL3Q){ - return rcc_clock_tree.pll3.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP1R_SPI45SEL_HSI){ - return RCC_HSI_BASE_FREQUENCY; - } else if (clksel == RCC_D2CCIP1R_SPI45SEL_HSE) { - return rcc_clock_tree.hse_khz * HZ_PER_KHZ; - } else { - return 0U; - } - case USART1_BASE: - case USART6_BASE: - clksel = (RCC_D2CCIP2R >> RCC_D2CCIP2R_USART16SEL_SHIFT) & RCC_D2CCIP2R_USARTSEL_MASK; - if (clksel == RCC_D2CCIP2R_USART16SEL_PCLK2) { - return rcc_get_bus_clk_freq(RCC_APB2CLK); - } else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL2Q) { - return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL3Q) { - return rcc_clock_tree.pll3.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP2R_USARTSEL_HSI) { - return RCC_HSI_BASE_FREQUENCY; - } else { - return 0U; - } - case USART2_BASE: - case USART3_BASE: - case UART4_BASE: - case UART5_BASE: - case UART7_BASE: - case UART8_BASE: - clksel = (RCC_D2CCIP2R >> RCC_D2CCIP2R_USART234578SEL_SHIFT) & RCC_D2CCIP2R_USARTSEL_MASK; - if (clksel == RCC_D2CCIP2R_USART234578SEL_PCLK1) { - return rcc_get_bus_clk_freq(RCC_APB1CLK); - } else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL2Q) { - return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL3Q) { - return rcc_clock_tree.pll3.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP2R_USARTSEL_HSI) { - return RCC_HSI_BASE_FREQUENCY; - } else { - return 0U; - } - default: - cm3_assert_not_reached(); - return 0; +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + uint32_t clksel, pclk; + if (usart == USART1_BASE || usart == USART6_BASE) { + pclk = rcc_clock_tree.per.pclk2_mhz * HZ_PER_MHZ;; + clksel = (RCC_D2CCIP2R >> RCC_D2CCIP2R_USART16SEL_SHIFT) & RCC_D2CCIP2R_USARTSEL_MASK; + } else { + pclk = rcc_clock_tree.per.pclk1_mhz * HZ_PER_MHZ; + clksel = (RCC_D2CCIP2R >> RCC_D2CCIP2R_USART234578SEL_SHIFT) & RCC_D2CCIP2R_USARTSEL_MASK; + } + + /* Based on extracted clksel value, return the clock. */ + if (clksel == RCC_D2CCIP2R_USARTSEL_PCLK) { + return pclk; + } else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL2Q) { + return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL3Q) { + return rcc_clock_tree.pll3.q_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP2R_USARTSEL_HSI) { + return RCC_HSI_BASE_FREQUENCY; + } else { + return 0U; + } +} + +uint32_t rcc_get_timer_clk_freq(uint32_t timer __attribute__((unused))) +{ + if (timer >= LPTIM2_BASE && timer <= LPTIM5_BASE) { + /* TODO: Read LPTIMxSEL values from D3CCIPR to determine clock source. */ + return rcc_clock_tree.per.pclk4_mhz * HZ_PER_MHZ; + } else if (timer >= TIM1_BASE && timer <= HRTIM_BASE) { + return rcc_clock_tree.per.pclk2_mhz * HZ_PER_MHZ; + } else { + return rcc_clock_tree.per.pclk1_mhz * HZ_PER_MHZ; + } +} + +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c) +{ + if (i2c == I2C4_BASE) { + /* TODO: Read I2C4SEL from D3CCIPR to determine clock source. */ + return rcc_clock_tree.per.pclk3_mhz * HZ_PER_MHZ; + } else { + /* TODO: Read I2C123SEL from D2CCIP2R to determine clock source. */ + return rcc_clock_tree.per.pclk1_mhz * HZ_PER_MHZ; + } +} + +uint32_t rcc_get_spi_clk_freq(uint32_t spi) +{ + if (spi == SPI4_BASE || spi == SPI5_BASE) { + uint32_t clksel = + (RCC_D2CCIP1R >> RCC_D2CCIP1R_SPI45SEL_SHIFT) & RCC_D2CCIP1R_SPI45SEL_MASK; + if (clksel == RCC_D2CCIP1R_SPI45SEL_APB4){ + return rcc_clock_tree.per.pclk2_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP1R_SPI45SEL_PLL2Q){ + return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP1R_SPI45SEL_PLL3Q){ + return rcc_clock_tree.pll3.q_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP1R_SPI45SEL_HSI){ + return RCC_HSI_BASE_FREQUENCY; + } else if (clksel == RCC_D2CCIP1R_SPI45SEL_HSE) { + return rcc_clock_tree.hse_khz * HZ_PER_KHZ; + } else { + return 0U; + } + } else { + uint32_t clksel = + (RCC_D2CCIP1R >> RCC_D2CCIP1R_SPI123SEL_SHIFT) & RCC_D2CCIP1R_SPI123SEL_MASK; + if (clksel == RCC_D2CCIP1R_SPI123SEL_PLL1Q) { + return rcc_clock_tree.pll1.q_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP1R_SPI123SEL_PLL2P) { + return rcc_clock_tree.pll2.p_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP1R_SPI123SEL_PLL3P) { + return rcc_clock_tree.pll3.p_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP1R_SPI123SEL_PERCK) { + return rcc_get_bus_clk_freq(RCC_PERCLK); + } else { + return 0U; + } + } +} + +uint32_t rcc_get_fdcan_clk_freq(uint32_t fdcan __attribute__((unused))) +{ + uint32_t clksel = + (RCC_D2CCIP1R >> RCC_D2CCIP1R_FDCANSEL_SHIFT) & RCC_D2CCIP1R_FDCANSEL_MASK; + if (clksel == RCC_D2CCIP1R_FDCANSEL_HSE) { + return rcc_clock_tree.hse_khz * HZ_PER_KHZ; + } else if (clksel == RCC_D2CCIP1R_FDCANSEL_PLL1Q) { + return rcc_clock_tree.pll1.q_mhz * HZ_PER_MHZ; + } else if (clksel == RCC_D2CCIP1R_FDCANSEL_PLL2Q) { + return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ; + } else { + return 0U; } } diff --git a/lib/stm32/l0/rcc.c b/lib/stm32/l0/rcc.c index 39bdaff7..01e84ac0 100644 --- a/lib/stm32/l0/rcc.c +++ b/lib/stm32/l0/rcc.c @@ -495,6 +495,83 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel) RCC_CCIPR = reg32 | (sel << shift); } + +/* Helper to calculate the frequency of a clksel based clock. */ +static uint32_t rcc_uart_i2c_clksel_freq_hz(uint32_t apb_clk, uint8_t shift) { + uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_I2C1SEL_MASK; + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + switch (clksel) { + case RCC_CCIPR_USART1SEL_APB: + return apb_clk; + case RCC_CCIPR_USART1SEL_SYS: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CCIPR_USART1SEL_HSI16: + return 16000000U; + } + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + if (usart == LPUART1_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_LPUART1SEL_SHIFT); + } else if (usart == USART1_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb2_frequency, RCC_CCIPR_USART1SEL_SHIFT); + } else { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART2SEL_SHIFT); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer) +{ + /* Handle APB1 timers, and apply multiplier if necessary. */ + if (timer >= TIM2_BASE && timer <= TIM7_BASE) { + uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; + return (ppre1 == RCC_CFGR_PPRE1_NODIV) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; + } else { + uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; + return (ppre2 == RCC_CFGR_PPRE2_NODIV) ? rcc_apb2_frequency + : 2 * rcc_apb2_frequency; + } + +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c) +{ + if (i2c == I2C1_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C1SEL_SHIFT); + } else if (i2c == I2C3_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C3SEL_SHIFT); + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi) { + if (spi == SPI1_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} + /** @brief RCC Setup PLL and use it as Sysclk source. * * @param[in] clock full struct with desired parameters diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c index 06898d00..ddef69b6 100644 --- a/lib/stm32/l1/rcc.c +++ b/lib/stm32/l1/rcc.c @@ -39,6 +39,7 @@ system clock. Not all possible configurations are included. */ /**@{*/ +#include #include #include #include @@ -555,4 +556,55 @@ void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) rcc_apb2_frequency = clock->apb2_frequency; } +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + if (usart == USART1_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer) +{ + /* Handle APB1 timers, and apply multiplier if necessary. */ + if (timer >= TIM2_BASE && timer <= TIM7_BASE) { + uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; + return (ppre1 == RCC_CFGR_PPRE1_HCLK_NODIV) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; + } else { + uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; + return (ppre2 == RCC_CFGR_PPRE2_HCLK_NODIV) ? rcc_apb2_frequency + : 2 * rcc_apb2_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused))) +{ + return rcc_apb1_frequency; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi) { + if (spi == SPI1_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} /**@}*/ diff --git a/lib/stm32/l4/rcc.c b/lib/stm32/l4/rcc.c index 1d3e3472..c8429184 100644 --- a/lib/stm32/l4/rcc.c +++ b/lib/stm32/l4/rcc.c @@ -36,6 +36,7 @@ */ /**@{*/ +#include #include /* Set the default clock frequencies after reset. */ @@ -434,4 +435,85 @@ void rcc_set_rtc_clock_source(enum rcc_osc clk) } } +/* Helper to calculate the frequency of a UART/I2C based on the apb and clksel value. */ +static uint32_t rcc_uart_i2c_clksel_freq_hz(uint32_t apb_clk, uint8_t shift) { + uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_USARTxSEL_MASK; + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + switch (clksel) { + case RCC_CCIPR_USARTxSEL_APB: + return apb_clk; + case RCC_CCIPR_USARTxSEL_SYS: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CCIPR_USARTxSEL_HSI16: + return 16000000U; + } + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the USART at base specified. + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + /* Handle values with selectable clocks. */ + if (usart == LPUART1_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb2_frequency, RCC_CCIPR_LPUART1SEL_SHIFT); + } else if (usart == USART1_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART1SEL_SHIFT); + } else if (usart == USART2_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART2SEL_SHIFT); + } else if (usart == USART3_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART3SEL_SHIFT); + } else if (usart == UART4_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_UART4SEL_SHIFT); + } else { /* USART5 */ + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_UART5SEL_SHIFT); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the Timer at base specified. + * @param timer Base address of TIM to get clock frequency for. + */ +uint32_t rcc_get_timer_clk_freq(uint32_t timer) +{ + /* Handle APB1 timers, and apply multiplier if necessary. */ + if (timer >= TIM2_BASE && timer <= TIM7_BASE) { + uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; + return (ppre1 == RCC_CFGR_PPRE1_NODIV) ? rcc_apb1_frequency + : 2 * rcc_apb1_frequency; + } else { + uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; + return (ppre2 == RCC_CFGR_PPRE2_NODIV) ? rcc_apb2_frequency + : 2 * rcc_apb2_frequency; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the I2C device at base specified. + * @param i2c Base address of I2C to get clock frequency for. + */ +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c) +{ + if (i2c == I2C1_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C1SEL_SHIFT); + } else if (i2c == I2C2_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C2SEL_SHIFT); + } else { /* I2C3 */ + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C3SEL_SHIFT); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get the peripheral clock speed for the SPI device at base specified. + * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). + */ +uint32_t rcc_get_spi_clk_freq(uint32_t spi) { + if (spi == SPI1_BASE) { + return rcc_apb2_frequency; + } else { + return rcc_apb1_frequency; + } +} /**@}*/ From f5192dbcb5dacb8f28322e01195a1a73804cff67 Mon Sep 17 00:00:00 2001 From: Denis Feklushkin Date: Thu, 1 Oct 2020 08:32:26 +0700 Subject: [PATCH 039/206] mk: genlink: simplify variable usage --- mk/genlink-rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/genlink-rules.mk b/mk/genlink-rules.mk index ebbcd741..d44fe0ca 100644 --- a/mk/genlink-rules.mk +++ b/mk/genlink-rules.mk @@ -17,6 +17,6 @@ ## along with this library. If not, see . ## -$(LDSCRIPT): $(OPENCM3_DIR)/ld/linker.ld.S $(OPENCM3_DIR)/ld/devices.data +$(LDSCRIPT): $(OPENCM3_DIR)/ld/linker.ld.S $(DEVICES_DATA) @printf " GENLNK $(DEVICE)\n" $(Q)$(CPP) $(ARCH_FLAGS) $(shell $(OPENCM3_DIR)/scripts/genlink.py $(DEVICES_DATA) $(DEVICE) DEFS) -P -E $< -o $@ From 3afd16b5d98ef4b0a35959f1a7ecb476e4c1b7f6 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 27 Nov 2020 23:15:08 +0000 Subject: [PATCH 040/206] README: flag the wildwest-N preview branches Hey, we have a readme, let's keep it up to date? --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ba9819dc..6fbfbf9c 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,11 @@ From 0.8.0 to 1.0, we'll atempt to follow semver, but **EXPECT CHANGES**, as we attempt to clear up old APIs and remove deprecated functions. The 0.8.0 tag was placed to provide the "old stable" point before all the new code started landing. +_preview_ code often lands in the "wildwest-N" branches that appear and disappear +in the repository. Pull requests marked as "merged-dev" will be in this branch, +and will be closed when they merge to master. This is useful for bigger +interdependent patch sets, and also allows review of merge conflicts in public. + From 1.0, expect to follow semver, with functions (and defines!) being deprecated for a release before being removed. From c26eab2513921d70eca6d3783ea6fa4cf8556e47 Mon Sep 17 00:00:00 2001 From: Ben Brewer Date: Wed, 29 Jul 2020 18:12:28 +0100 Subject: [PATCH 041/206] stm32g4: Implement PWR --- include/libopencm3/stm32/g4/pwr.h | 196 ++++++++++++++++++++++++++++++ include/libopencm3/stm32/pwr.h | 2 + lib/stm32/g4/Makefile | 1 + lib/stm32/g4/pwr.c | 121 ++++++++++++++++++ 4 files changed, 320 insertions(+) create mode 100644 include/libopencm3/stm32/g4/pwr.h create mode 100644 lib/stm32/g4/pwr.c diff --git a/include/libopencm3/stm32/g4/pwr.h b/include/libopencm3/stm32/g4/pwr.h new file mode 100644 index 00000000..f46558be --- /dev/null +++ b/include/libopencm3/stm32/g4/pwr.h @@ -0,0 +1,196 @@ +/** @defgroup pwr_defines PWR Defines + * + * @ingroup STM32G4xx_defines + * + * @brief Defined Constants and Types for the STM32G4xx Power Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2016 Benjamin Levine + * @author @htmlonly © @endhtmlonly 2019 Guillaume Revaillot + * @author @htmlonly © @endhtmlonly 2020 Ben Brewer + * + * @date 29 July 2020 + * + * LGPL License Terms @ref lgpl_license + * */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Benjamin Levine + * Copyright (C) 2019 Guillaume Revaillot + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA PWR.H +The order of header inclusion is important. pwr.h includes the device +specific memorymap.h header before including this header file.*/ + +/**@{*/ +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + + + +/* --- PWR registers ------------------------------------------------------- */ + +#define PWR_CR1 MMIO32(POWER_CONTROL_BASE + 0x00) +#define PWR_CR2 MMIO32(POWER_CONTROL_BASE + 0x04) +#define PWR_CR3 MMIO32(POWER_CONTROL_BASE + 0x08) +#define PWR_CR4 MMIO32(POWER_CONTROL_BASE + 0x0C) +#define PWR_CR5 MMIO32(POWER_CONTROL_BASE + 0x80) +#define PWR_SR1 MMIO32(POWER_CONTROL_BASE + 0x10) +#define PWR_SR2 MMIO32(POWER_CONTROL_BASE + 0x14) +#define PWR_SCR MMIO32(POWER_CONTROL_BASE + 0x18) + +#define PWR_PORT_A MMIO32(POWER_CONTROL_BASE + 0x20) +#define PWR_PORT_B MMIO32(POWER_CONTROL_BASE + 0x28) +#define PWR_PORT_C MMIO32(POWER_CONTROL_BASE + 0x30) +#define PWR_PORT_D MMIO32(POWER_CONTROL_BASE + 0x38) +#define PWR_PORT_E MMIO32(POWER_CONTROL_BASE + 0x40) +#define PWR_PORT_F MMIO32(POWER_CONTROL_BASE + 0x48) +#define PWR_PORT_G MMIO32(POWER_CONTROL_BASE + 0x50) + +#define PWR_PUCR(pwr_port) MMIO32((pwr_port) + 0x00) +#define PWR_PDCR(pwr_port) MMIO32((pwr_port) + 0x04) + +/* --- PWR_CR1 values ------------------------------------------------------- */ + +#define PWR_CR1_LPR (1 << 14) + +#define PWR_CR1_VOS_SHIFT 9 +#define PWR_CR1_VOS_MASK 0x3 +#define PWR_CR1_VOS_RANGE_1 1 +#define PWR_CR1_VOS_RANGE_2 2 + +#define PWR_CR1_DBP (1 << 8) + +#define PWR_CR1_LPMS_SHIFT 0 +#define PWR_CR1_LPMS_MASK 0x07 +#define PWR_CR1_LPMS_STOP_0 0 +#define PWR_CR1_LPMS_STOP_1 1 +#define PWR_CR1_LPMS_STOP_2 2 +#define PWR_CR1_LPMS_STANDBY 3 +#define PWR_CR1_LPMS_SHUTDOWN 4 + +/* --- PWR_CR2 values ------------------------------------------------------- */ + +#define PWR_CR2_PVMEN2 (1 << 7) +#define PWR_CR2_PVMEN1 (1 << 6) + +#define PWR_CR2_PLS_SHIFT 1 +#define PWR_CR2_PLS_MASK 0x07 +/** @defgroup pwr_pls PVD level selection +@ingroup STM32G4_pwr_defines +@{*/ +#define PWR_CR2_PLS_2V0 0x00 +#define PWR_CR2_PLS_2V2 0x01 +#define PWR_CR2_PLS_2V4 0x02 +#define PWR_CR2_PLS_2V5 0x03 +#define PWR_CR2_PLS_2V6 0x04 +#define PWR_CR2_PLS_2V8 0x05 +#define PWR_CR2_PLS_2V9 0x06 +#define PWR_CR2_PLS_PVD_IN 0x07 +/**@}*/ + +#define PWR_CR2_PVDE (1 << 0) + +/* --- PWR_CR3 values ------------------------------------------------------- */ + +#define PWR_CR3_EIWUL (1 << 15) +#define PWR_CR3_UCPD1_DBDIS (1 << 15) +#define PWR_CR3_UCPD1_STDBY (1 << 15) +#define PWR_CR3_APC (1 << 10) +#define PWR_CR3_RRS (1 << 8) +#define PWR_CR3_EWUP5 (1 << 4) +#define PWR_CR3_EWUP4 (1 << 3) +#define PWR_CR3_EWUP3 (1 << 2) +#define PWR_CR3_EWUP2 (1 << 1) +#define PWR_CR3_EWUP1 (1 << 0) + +/* --- PWR_CR4 values ------------------------------------------------------- */ + +#define PWR_CR4_VBRS (1 << 9) +#define PWR_CR4_VBE (1 << 8) +#define PWR_CR4_WP5 (1 << 4) +#define PWR_CR4_WP4 (1 << 3) +#define PWR_CR4_WP3 (1 << 2) +#define PWR_CR4_WP2 (1 << 1) +#define PWR_CR4_WP1 (1 << 0) + +/* --- PWR_CR4 values ------------------------------------------------------- */ + +#define PWR_CR5_R1MODE_SHIFT 8 +#define PWR_CR5_R1MODE_MASK 0x1 +#define PWR_CR5_R1MODE_BOOST 0 +#define PWR_CR5_R1MODE_NORMAL 1 +#define PWR_CR5_R1MODE (PWR_CR5_R1MODE_MASK << PWR_CR5_R1MODE_SHIFT) + +/* --- PWR_SR1 values ------------------------------------------------------- */ + +#define PWR_SR1_WUFI (1 << 15) +#define PWR_SR1_SBF (1 << 8) +#define PWR_SR1_WUF5 (1 << 4) +#define PWR_SR1_WUF4 (1 << 3) +#define PWR_SR1_WUF3 (1 << 2) +#define PWR_SR1_WUF2 (1 << 1) +#define PWR_SR1_WUF1 (1 << 0) + +/* --- PWR_SR2 values ------------------------------------------------------- */ + +#define PWR_SR2_PVMO2 (1 << 15) +#define PWR_SR2_PVMO1 (1 << 14) +#define PWR_SR2_PVDO (1 << 11) +#define PWR_SR2_VOSF (1 << 10) +#define PWR_SR2_REGLPF (1 << 9) +#define PWR_SR2_REGLPS (1 << 8) + +/* --- PWR_SCR values ------------------------------------------------------- */ + +#define PWR_SCR_CSBF (1 << 8) +#define PWR_SCR_CWUF5 (1 << 4) +#define PWR_SCR_CWUF4 (1 << 3) +#define PWR_SCR_CWUF3 (1 << 2) +#define PWR_SCR_CWUF2 (1 << 1) +#define PWR_SCR_CWUF1 (1 << 0) + +/* --- PWR function prototypes ------------------------------------------- */ + +enum pwr_vos_scale { + PWR_SCALE1 = PWR_CR1_VOS_RANGE_1, + PWR_SCALE2 = PWR_CR1_VOS_RANGE_2, +}; + +BEGIN_DECLS + +void pwr_set_vos_scale(enum pwr_vos_scale scale); + +void pwr_disable_backup_domain_write_protect(void); +void pwr_enable_backup_domain_write_protect(void); + +void pwr_set_low_power_mode_selection(uint32_t lpms); + +void pwr_enable_power_voltage_detect(uint32_t pvd_level); +void pwr_disable_power_voltage_detect(void); + +void pwr_enable_boost(void); +void pwr_disable_boost(void); + +END_DECLS + +#endif +/**@}*/ diff --git a/include/libopencm3/stm32/pwr.h b/include/libopencm3/stm32/pwr.h index 69547eef..7844f7a2 100644 --- a/include/libopencm3/stm32/pwr.h +++ b/include/libopencm3/stm32/pwr.h @@ -40,6 +40,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include #else diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 01fe6b07..ee7f433b 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -36,6 +36,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs OBJS += gpio_common_all.o gpio_common_f0234.o +OBJS += pwr.o OBJS += rcc_common_all.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/g4/pwr.c b/lib/stm32/g4/pwr.c new file mode 100644 index 00000000..fdc5df0c --- /dev/null +++ b/lib/stm32/g4/pwr.c @@ -0,0 +1,121 @@ +/** @defgroup pwr_file PWR peripheral API + * + * @ingroup peripheral_apis + * + * @brief libopencm3 STM32G4xx Power Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2016 Benjamin Levine + * @author @htmlonly © @endhtmlonly 2019 Guillaume Revaillot + * @author @htmlonly © @endhtmlonly 2020 Ben Brewer + * + * @date 29 July 2020 + * + * This library supports the power control system for the + * STM32G4 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Benjamin Levine + * Copyright (C) 2019 Guillaume Revaillot + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ +#include + +void pwr_set_vos_scale(enum pwr_vos_scale scale) +{ + uint32_t reg32; + + reg32 = PWR_CR1 & ~(PWR_CR1_VOS_MASK << PWR_CR1_VOS_SHIFT); + reg32 |= (scale & PWR_CR1_VOS_MASK) << PWR_CR1_VOS_SHIFT; + PWR_CR1 = reg32; +} + +/** Disable Backup Domain Write Protection + * + * This allows backup domain registers to be changed. These registers are write + * protected after a reset. + */ +void pwr_disable_backup_domain_write_protect(void) +{ + PWR_CR1 |= PWR_CR1_DBP; +} + +/** Re-enable Backup Domain Write Protection + * + * This protects backup domain registers from inadvertent change. + */ +void pwr_enable_backup_domain_write_protect(void) +{ + PWR_CR1 &= ~PWR_CR1_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Select the low power mode used in deep sleep. + * @param lpms low power mode @ref pwr_cr1_lpms + */ +void pwr_set_low_power_mode_selection(uint32_t lpms) +{ + uint32_t reg32; + + reg32 = PWR_CR1; + reg32 &= ~(PWR_CR1_LPMS_MASK << PWR_CR1_LPMS_SHIFT); + PWR_CR1 = (reg32 | (lpms << PWR_CR1_LPMS_SHIFT)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Power Voltage Detector. + * @param[in] pvd_level Power Voltage Detector Falling Threshold voltage @ref pwr_pls. +*/ +void pwr_enable_power_voltage_detect(uint32_t pvd_level) +{ + uint32_t reg32; + + reg32 = PWR_CR2; + reg32 &= ~(PWR_CR2_PLS_MASK << PWR_CR2_PLS_SHIFT); + PWR_CR2 = (reg32 | (pvd_level << PWR_CR2_PLS_SHIFT) | PWR_CR2_PVDE); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Power Voltage Detector. +*/ +void pwr_disable_power_voltage_detect(void) +{ + PWR_CR2 &= ~PWR_CR2_PVDE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Boost Mode. +*/ +void pwr_enable_boost(void) +{ + PWR_CR5 &= ~PWR_CR5_R1MODE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Boost Mode. +*/ +void pwr_disable_boost(void) +{ + PWR_CR5 |= PWR_CR5_R1MODE; +} + +/**@}*/ From 59569bfb0407cc0351227dc24f35d05182f8e3dc Mon Sep 17 00:00:00 2001 From: Ben Brewer Date: Thu, 30 Jul 2020 11:48:43 +0100 Subject: [PATCH 042/206] stm32g4: Implement FLASH --- include/libopencm3/stm32/flash.h | 2 + include/libopencm3/stm32/g4/flash.h | 265 ++++++++++++++++++++++++++++ lib/stm32/g4/Makefile | 1 + lib/stm32/g4/flash.c | 209 ++++++++++++++++++++++ 4 files changed, 477 insertions(+) create mode 100644 include/libopencm3/stm32/g4/flash.h create mode 100644 lib/stm32/g4/flash.c diff --git a/include/libopencm3/stm32/flash.h b/include/libopencm3/stm32/flash.h index 7da5a697..01f62e6c 100644 --- a/include/libopencm3/stm32/flash.h +++ b/include/libopencm3/stm32/flash.h @@ -40,6 +40,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include #elif defined(GD32F1X0) diff --git a/include/libopencm3/stm32/g4/flash.h b/include/libopencm3/stm32/g4/flash.h new file mode 100644 index 00000000..9fdd1cd1 --- /dev/null +++ b/include/libopencm3/stm32/g4/flash.h @@ -0,0 +1,265 @@ +/** @defgroup flash_defines FLASH Defines + * + * @ingroup STM32G4xx_defines + * + * @brief Defined Constants and Types for the STM32G4xx Flash Control + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2016 Benjamin Levine + * @author @htmlonly © @endhtmlonly 2020 Ben Brewer + * + * @date 30 July 2020 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Benjamin Levine + * Copyright (C) 2020 Ben Brewer + * + * 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 . + */ + +/* + * For details see: + * RM0440 Reference manual: STM32G4 Series advanced ARM®-based 32-bit MCUs + * 15 April 2020, Doc ID 00355726 Rev 4 + */ + +/**@{*/ +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H + +#include +#include +#include + +/* --- FLASH registers ----------------------------------------------------- */ + +#define FLASH_ACR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x00) +#define FLASH_PDKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x04) +#define FLASH_KEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) +#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) +#define FLASH_SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) +#define FLASH_CR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) +#define FLASH_ECCR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x18) +#define FLASH_OPTR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x20) +#define FLASH_PCROP1SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x24) +#define FLASH_PCROP1ER MMIO32(FLASH_MEM_INTERFACE_BASE + 0x28) +#define FLASH_WRP1AR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x2C) +#define FLASH_WRP1BR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x30) +#define FLASH_PCROP2SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x44) +#define FLASH_PCROP2ER MMIO32(FLASH_MEM_INTERFACE_BASE + 0x48) +#define FLASH_WRP2AR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x4C) +#define FLASH_WRP2BR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x50) +#define FLASH_SEC1R MMIO32(FLASH_MEM_INTERFACE_BASE + 0x70) +#define FLASH_SEC2R MMIO32(FLASH_MEM_INTERFACE_BASE + 0x74) + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +#define FLASH_ACR_DBG_SWEN (1 << 18) +#define FLASH_ACR_SLEEP_PD (1 << 14) +#define FLASH_ACR_RUN_PD (1 << 13) +#define FLASH_ACR_PRFTEN (1 << 8) + +#define FLASH_ACR_LATENCY_SHIFT 0 +#define FLASH_ACR_LATENCY_MASK 0xf + +/* --- FLASH_SR values ----------------------------------------------------- */ + +#define FLASH_SR_BSY (1 << 16) +#define FLASH_SR_OPTVERR (1 << 15) +#define FLASH_SR_RDERR (1 << 14) +#define FLASH_SR_FASTERR (1 << 9) +#define FLASH_SR_MISERR (1 << 8) +#define FLASH_SR_PGSERR (1 << 7) +#define FLASH_SR_SIZERR (1 << 6) +#define FLASH_SR_PGAERR (1 << 5) +#define FLASH_SR_WRPERR (1 << 4) +#define FLASH_SR_PROGERR (1 << 3) +#define FLASH_SR_OPERR (1 << 1) +#define FLASH_SR_EOP (1 << 0) + +/* --- FLASH_CR values ----------------------------------------------------- */ + +#define FLASH_CR_LOCK (1 << 31) +#define FLASH_CR_OPTLOCK (1 << 30) +#define FLASH_CR_SEC_PROT2 (1 << 29) +#define FLASH_CR_SEC_PROT1 (1 << 28) +#define FLASH_CR_OBL_LAUNCH (1 << 27) +#define FLASH_CR_RDERRIE (1 << 26) +#define FLASH_CR_ERRIE (1 << 25) +#define FLASH_CR_EOPIE (1 << 24) +#define FLASH_CR_FSTPG (1 << 18) +#define FLASH_CR_OPTSTRT (1 << 17) +#define FLASH_CR_START (1 << 16) +#define FLASH_CR_MER2 (1 << 15) +#define FLASH_CR_BKER (1 << 11) +#define FLASH_CR_MER1 (1 << 2) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_PG (1 << 0) + +#define FLASH_CR_PNB_SHIFT 3 +#define FLASH_CR_PNB_MASK 0x7f + +/* --- FLASH_ECCR values -------------------------------------------------- */ + +#define FLASH_ECCR_ECCD (1 << 31) +#define FLASH_ECCR_ECCC (1 << 30) +#define FLASH_ECCR_ECCD2 (1 << 31) +#define FLASH_ECCR_ECCC2 (1 << 30) +#define FLASH_ECCR_ECCIE (1 << 24) +#define FLASH_ECCR_SYSF_ECC (1 << 22) +#define FLASH_ECCR_BK_ECC (1 << 21) + +#define FLASH_ECCR_ADDR_ECC_SHIFT 0 +#define FLASH_ECCR_ADDR_ECC_MASK 0x7ffff + +/* --- FLASH_OPTR values -------------------------------------------------- */ + +#define FLASH_OPTR_IRHEN (1 << 30) + +#define FLASH_OPTR_NRST_MODE_SHIFT 28 +#define FLASH_OPTR_NRST_MODE_MASK 0x3 +#define FLASH_OPTR_NRST_MODE_RESET 1 +#define FLASH_OPTR_NRST_MODE_GPIO 2 +#define FLASH_OPTR_NRST_MODE_BIDIR 3 + +#define FLASH_OPTR_nBOOT0 (1 << 27) +#define FLASH_OPTR_nSWBOOT0 (1 << 26) +#define FLASH_OPTR_SRAM_RST (1 << 25) +#define FLASH_OPTR_SRAM_PE (1 << 24) +#define FLASH_OPTR_nBOOT1 (1 << 23) +#define FLASH_OPTR_DUALBANK (1 << 21) +#define FLASH_OPTR_BFB2 (1 << 20) +#define FLASH_OPTR_WWDG_SW (1 << 19) +#define FLASH_OPTR_IWDG_STDBY (1 << 18) +#define FLASH_OPTR_IWDG_STOP (1 << 17) +#define FLASH_OPTR_IDWG_SW (1 << 16) +#define FLASH_OPTR_nRST_SHDW (1 << 14) +#define FLASH_OPTR_nRST_STDBY (1 << 13) +#define FLASH_OPTR_nRST_STOP (1 << 12) + +#define FLASH_OPTR_BOR_SHIFT 8 +#define FLASH_OPTR_BOR_MASK 0x7 +#define FLASH_OPTR_BOR_LEVEL_0 0 +#define FLASH_OPTR_BOR_LEVEL_1 1 +#define FLASH_OPTR_BOR_LEVEL_2 2 +#define FLASH_OPTR_BOR_LEVEL_3 3 +#define FLASH_OPTR_BOR_LEVEL_4 4 + +#define FLASH_OPTR_RDP_SHIFT 0 +#define FLASH_OPTR_RDP_MASK 0xff +#define FLASH_OPTR_RDP_LEVEL_0 0xAA +#define FLASH_OPTR_RDP_LEVEL_1 0xBB +#define FLASH_OPTR_RDP_LEVEL_2 0xCC + +/* --- FLASH_PCROP1SR values -------------------------------------------------- */ + +#define FLASH_PCROP1SR_PCROP1_STRT_SHIFT 0 +#define FLASH_PCROP1SR_PCROP1_STRT_MASK 0x7fff + +/* --- FLASH_PCROP1ER values -------------------------------------------------- */ + +#define FLASH_PCROP1ER_PCROP_RDP (1 << 31) +#define FLASH_PCROP1ER_PCROP1_END_SHIFT 0 +#define FLASH_PCROP1ER_PCROP1_END_MASK 0x7fff + +/* --- FLASH_WRP1AR values -------------------------------------------------- */ + +#define FLASH_WRP1AR_WRP1A_END_SHIFT 16 +#define FLASH_WRP1AR_WRP1A_END_MASK 0x7f + +#define FLASH_WRP1AR_WRP1A_STRT_SHIFT 0 +#define FLASH_WRP1AR_WRP1A_STRT_MASK 0x7f + +/* --- FLASH_WRP1BR values -------------------------------------------------- */ + +#define FLASH_WRP1BR_WRP1B_END_SHIFT 16 +#define FLASH_WRP1BR_WRP1B_END_MASK 0x7f + +#define FLASH_WRP1BR_WRP1B_STRT_SHIFT 0 +#define FLASH_WRP1BR_WRP1B_STRT_MASK 0x7f + +/* --- FLASH_PCROP2SR values -------------------------------------------------- */ + +#define FLASH_PCROP2SR_PCROP2_STRT_SHIFT 0 +#define FLASH_PCROP2SR_PCROP2_STRT_MASK 0x7fff + +/* --- FLASH_PCROP2ER values -------------------------------------------------- */ + +#define FLASH_PCROP2ER_PCROP2_END_SHIFT 0 +#define FLASH_PCROP2ER_PCROP2_END_MASK 0x7fff + +/* --- FLASH_WRP2AR values -------------------------------------------------- */ + +#define FLASH_WRP2AR_WRP2A_END_SHIFT 16 +#define FLASH_WRP2AR_WRP2A_END_MASK 0x7f + +#define FLASH_WRP2AR_WRP2A_STRT_SHIFT 0 +#define FLASH_WRP2AR_WRP2A_STRT_MASK 0x7f + +/* --- FLASH_WRP2BR values -------------------------------------------------- */ + +#define FLASH_WRP2BR_WRP2B_END_SHIFT 16 +#define FLASH_WRP2BR_WRP2B_END_MASK 0xff + +#define FLASH_WRP2BR_WRP2B_STRT_SHIFT 0 +#define FLASH_WRP2BR_WRP2B_STRT_MASK 0xff + +/* --- FLASH_SEC1R values -------------------------------------------------- */ + +#define FLASH_SEC1R_BOOT_LOCK (1 << 16) + +#define FLASH_SEC1R_SEC_SIZE1_SHIFT 0 +#define FLASH_SEC1R_SEC_SIZE1_MASK 0xff + +/* --- FLASH_SEC2R values -------------------------------------------------- */ + +#define FLASH_SEC2R_SEC_SIZE2_SHIFT 0 +#define FLASH_SEC2R_SEC_SIZE2_MASK 0xff + +/* --- FLASH Keys -----------------------------------------------------------*/ + +#define FLASH_PDKEYR_PDKEY1 ((uint32_t)0x04152637) +#define FLASH_PDKEYR_PDKEY2 ((uint32_t)0xfafbfcfd) + +#define FLASH_KEYR_KEY1 ((uint32_t)0x45670123) +#define FLASH_KEYR_KEY2 ((uint32_t)0xcdef89ab) + +#define FLASH_OPTKEYR_KEY1 ((uint32_t)0x08192a3b) +#define FLASH_OPTKEYR_KEY2 ((uint32_t)0x4c5d6e7f) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void flash_clear_progerr_flag(void); +void flash_clear_pgserr_flag(void); +void flash_clear_size_flag(void); +void flash_clear_pgaerr_flag(void); +void flash_clear_wrperr_flag(void); +void flash_lock_option_bytes(void); +void flash_program_double_word(uint32_t address, uint64_t data); +void flash_program(uint32_t address, uint8_t *data, uint32_t len); +void flash_erase_page(uint32_t page); +void flash_erase_all_pages(void); +void flash_program_option_bytes(uint32_t data); + +END_DECLS + +#endif +/**@}*/ diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index ee7f433b..5690c616 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -35,6 +35,7 @@ TGT_CFLAGS += $(DEBUG_FLAGS) TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs +OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += pwr.o OBJS += rcc_common_all.o diff --git a/lib/stm32/g4/flash.c b/lib/stm32/g4/flash.c new file mode 100644 index 00000000..352d2bbe --- /dev/null +++ b/lib/stm32/g4/flash.c @@ -0,0 +1,209 @@ +/** @defgroup flash_file FLASH peripheral API + * + * @ingroup peripheral_apis + * + * @brief libopencm3 STM32G4xx FLASH + * + * @version 1.0.0 + * + * Benjamin Levine + * Ben Brewer + * + * @date 30 July 2020 + * + * This library supports the FLASH memory controller in the STM32G4 + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * For the STM32G4xx, accessing FLASH memory is described briefly in + * section 3 of the STM32G4 Reference Manual. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Benjamin Levine + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/** @brief Wait until Last Operation has Ended + * This loops indefinitely until an operation (write or erase) has completed + * by testing the busy flag. + */ +void flash_wait_for_last_operation(void) +{ + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); +} + +/** @brief Clear the Programming Sequence Error Flag + * This flag is set when incorrect programming configuration has been made. + */ +void flash_clear_pgserr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGSERR; +} + +/** Clear programming size error flag */ +void flash_clear_size_flag(void) +{ + FLASH_SR |= FLASH_SR_SIZERR; +} + +/** @brief Clear the Programming Alignment Error Flag + */ +void flash_clear_pgaerr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGAERR; +} + +/** @brief Clear the Write Protect Error Flag + */ +void flash_clear_wrperr_flag(void) +{ + FLASH_SR |= FLASH_SR_WRPERR; +} + +/** @brief Clear the Programming Error Status Flag + */ +void flash_clear_progerr_flag(void) +{ + FLASH_SR |= FLASH_SR_PROGERR; +} + +/** @brief Clear All Status Flags + * Program error, end of operation, write protect error, busy. + */ +void flash_clear_status_flags(void) +{ + flash_clear_pgserr_flag(); + flash_clear_size_flag(); + flash_clear_pgaerr_flag(); + flash_clear_wrperr_flag(); + flash_clear_progerr_flag(); + flash_clear_eop_flag(); +} + +/** @brief Lock the Option Byte Access + * This disables write access to the option bytes. It is locked by default on + * reset. + */ +void flash_lock_option_bytes(void) +{ + FLASH_CR |= FLASH_CR_OPTLOCK; +} + +/** @brief Program a 64 bit word to FLASH + * + * This performs all operations necessary to program a 64 bit word to FLASH memory. + * The program error flag should be checked separately for the event that memory + * was not properly erased. + * + * @param[in] address Starting address in Flash. + * @param[in] data Double word to write + */ +void flash_program_double_word(uint32_t address, uint64_t data) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_CR_PG; + + /* Program the each word separately. */ + MMIO32(address) = (uint32_t)data; + MMIO32(address+4) = (uint32_t)(data >> 32); + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Disable writes to flash. */ + FLASH_CR &= ~FLASH_CR_PG; +} + +/** @brief Program a Data Block to FLASH + * This programs an arbitrary length data block to FLASH memory. + * The program error flag should be checked separately for the event that + * memory was not properly erased. + * @param[in] address Starting address in Flash. + * @param[in] data Pointer to start of data block. + * @param[in] len Length of data block in bytes (multiple of 8). + */ +void flash_program(uint32_t address, uint8_t *data, uint32_t len) +{ + for (uint32_t i = 0; i < len; i += 8) { + flash_program_double_word(address+i, *(uint64_t*)(data + i)); + } +} + +/** @brief Erase a page of FLASH + * @param[in] page (0 - 255 for bank 1, 256-511 for bank 2) + */ +void flash_erase_page(uint32_t page) +{ + flash_wait_for_last_operation(); + + /* page and bank are contiguous bits */ + FLASH_CR &= ~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_BKER); + if (page > 255) { + FLASH_CR |= FLASH_CR_BKER; + } + FLASH_CR |= page << FLASH_CR_PNB_SHIFT; + FLASH_CR |= FLASH_CR_PER; + FLASH_CR |= FLASH_CR_START; + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_PER; +} + +/** @brief Erase All FLASH + * This performs all operations necessary to erase all sectors in the FLASH + * memory. + */ +void flash_erase_all_pages(void) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_CR_MER1 | FLASH_CR_MER2; + FLASH_CR |= FLASH_CR_START; + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_MER1 & ~FLASH_CR_MER2; +} + +/** @brief Program the Option Bytes + * This performs all operations necessary to program the option bytes. + * The option bytes do not need to be erased first. + * @param[in] data value to be programmed. + */ +void flash_program_option_bytes(uint32_t data) +{ + flash_wait_for_last_operation(); + + if (FLASH_CR & FLASH_CR_OPTLOCK) { + flash_unlock_option_bytes(); + } + + FLASH_OPTR = data; + FLASH_CR |= FLASH_CR_OPTSTRT; + flash_wait_for_last_operation(); +} +/**@}*/ + From f4f75c92dd2429475b9eff91ad4dd2e7f01b0880 Mon Sep 17 00:00:00 2001 From: Ben Brewer Date: Mon, 30 Nov 2020 12:57:43 +0000 Subject: [PATCH 043/206] stm32g4: Implement RCC Co-authored-by: Sam Kirkham --- include/libopencm3/stm32/g4/rcc.h | 531 ++++++++++++--------- lib/stm32/g4/Makefile | 2 +- lib/stm32/g4/rcc.c | 766 ++++++++++++++++++++++++++++++ 3 files changed, 1084 insertions(+), 215 deletions(-) create mode 100644 lib/stm32/g4/rcc.c diff --git a/include/libopencm3/stm32/g4/rcc.h b/include/libopencm3/stm32/g4/rcc.h index bb1f809e..51e45c76 100644 --- a/include/libopencm3/stm32/g4/rcc.h +++ b/include/libopencm3/stm32/g4/rcc.h @@ -8,6 +8,8 @@ * @version 1.0.0 * * @author @htmlonly © @endhtmlonly 2020 Karl Palsson + * @author @htmlonly © @endhtmlonly 2020 Sam Kirkham + * @author @htmlonly © @endhtmlonly 2020 Ben Brewer * * LGPL License Terms @ref lgpl_license */ @@ -16,6 +18,8 @@ * This file is part of the libopencm3 project. * * Copyright (C) 2020 Karl Palsson + * Copyright (C) 2020 Sam Kirkham + * Copyright (C) 2020 Ben Brewer * * 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 @@ -37,6 +41,8 @@ #ifndef LIBOPENCM3_RCC_H #define LIBOPENCM3_RCC_H +#include + /** @defgroup rcc_registers RCC Registers * @{ */ @@ -47,24 +53,42 @@ #define RCC_CIER MMIO32(RCC_BASE + 0x18) #define RCC_CIFR MMIO32(RCC_BASE + 0x1c) #define RCC_CICR MMIO32(RCC_BASE + 0x20) -#define RCC_AHB1RSTR MMIO32(RCC_BASE + 0x28) -#define RCC_AHB2RSTR MMIO32(RCC_BASE + 0x2c) -#define RCC_AHB3RSTR MMIO32(RCC_BASE + 0x30) -#define RCC_APB1RSTR1 MMIO32(RCC_BASE + 0x38) -#define RCC_APB1RSTR2 MMIO32(RCC_BASE + 0x3c) -#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x40) -#define RCC_AHB1ENR MMIO32(RCC_BASE + 0x48) -#define RCC_AHB2ENR MMIO32(RCC_BASE + 0x4c) -#define RCC_AHB3ENR MMIO32(RCC_BASE + 0x50) -#define RCC_APB1ENR1 MMIO32(RCC_BASE + 0x58) -#define RCC_APB1ENR2 MMIO32(RCC_BASE + 0x5c) -#define RCC_APB2ENR MMIO32(RCC_BASE + 0x60) -#define RCC_AHB1SMENR MMIO32(RCC_BASE + 0x68) -#define RCC_AHB2SMENR MMIO32(RCC_BASE + 0x6c) -#define RCC_AHB3SMENR MMIO32(RCC_BASE + 0x70) -#define RCC_APB1SMENR1 MMIO32(RCC_BASE + 0x78) -#define RCC_APB1SMENR2 MMIO32(RCC_BASE + 0x7c) -#define RCC_APB2SMENR MMIO32(RCC_BASE + 0x80) +#define RCC_AHB1RSTR_OFFSET 0x28 +#define RCC_AHB1RSTR MMIO32(RCC_BASE + RCC_AHB1RSTR_OFFSET) +#define RCC_AHB2RSTR_OFFSET 0x2c +#define RCC_AHB2RSTR MMIO32(RCC_BASE + RCC_AHB2RSTR_OFFSET) +#define RCC_AHB3RSTR_OFFSET 0x30 +#define RCC_AHB3RSTR MMIO32(RCC_BASE + RCC_AHB3RSTR_OFFSET) +#define RCC_APB1RSTR1_OFFSET 0x38 +#define RCC_APB1RSTR1 MMIO32(RCC_BASE + RCC_APB1RSTR1_OFFSET) +#define RCC_APB1RSTR2_OFFSET 0x3c +#define RCC_APB1RSTR2 MMIO32(RCC_BASE + RCC_APB1RSTR2_OFFSET) +#define RCC_APB2RSTR_OFFSET 0x40 +#define RCC_APB2RSTR MMIO32(RCC_BASE + RCC_APB2RSTR_OFFSET) +#define RCC_AHB1ENR_OFFSET 0x48 +#define RCC_AHB1ENR MMIO32(RCC_BASE + RCC_AHB1ENR_OFFSET) +#define RCC_AHB2ENR_OFFSET 0x4c +#define RCC_AHB2ENR MMIO32(RCC_BASE + RCC_AHB2ENR_OFFSET) +#define RCC_AHB3ENR_OFFSET 0x50 +#define RCC_AHB3ENR MMIO32(RCC_BASE + RCC_AHB3ENR_OFFSET) +#define RCC_APB1ENR1_OFFSET 0x58 +#define RCC_APB1ENR1 MMIO32(RCC_BASE + RCC_APB1ENR1_OFFSET) +#define RCC_APB1ENR2_OFFSET 0x5c +#define RCC_APB1ENR2 MMIO32(RCC_BASE + RCC_APB1ENR2_OFFSET) +#define RCC_APB2ENR_OFFSET 0x60 +#define RCC_APB2ENR MMIO32(RCC_BASE + RCC_APB2ENR_OFFSET) +#define RCC_AHB1SMENR_OFFSET 0x68 +#define RCC_AHB1SMENR MMIO32(RCC_BASE + RCC_AHB1SMENR_OFFSET) +#define RCC_AHB2SMENR_OFFSET 0x6c +#define RCC_AHB2SMENR MMIO32(RCC_BASE + RCC_AHB2SMENR_OFFSET) +#define RCC_AHB3SMENR_OFFSET 0x70 +#define RCC_AHB3SMENR MMIO32(RCC_BASE + RCC_AHB3SMENR_OFFSET) +#define RCC_APB1SMENR1_OFFSET 0x78 +#define RCC_APB1SMENR1 MMIO32(RCC_BASE + RCC_APB1SMENR1_OFFSET) +#define RCC_APB1SMENR2_OFFSET 0x7c +#define RCC_APB1SMENR2 MMIO32(RCC_BASE + RCC_APB1SMENR2_OFFSET) +#define RCC_APB2SMENR_OFFSET 0x80 +#define RCC_APB2SMENR MMIO32(RCC_BASE + RCC_APB2SMENR_OFFSET) #define RCC_CCIPR MMIO32(RCC_BASE + 0x88) #define RCC_BDCR MMIO32(RCC_BASE + 0x90) #define RCC_CSR MMIO32(RCC_BASE + 0x94) @@ -91,7 +115,7 @@ * @{ */ #define RCC_ICSCR_HSITRIM_SHIFT 24 -#define RCC_ICSCR_HSITRIM_MASK 0x1f +#define RCC_ICSCR_HSITRIM_MASK 0x7f #define RCC_ICSCR_HSICAL_SHIFT 16 #define RCC_ICSCR_HSICAL_MASK 0xff /**@}*/ @@ -173,9 +197,12 @@ /** @defgroup rcc_pllcfgr_values RCC_PLLCFGR - PLL Configuration Register * @{ */ -#define RCC_CFGR_PLLPDIV_MASK 0x1f -#define RCC_CFGR_PLLPDIV_SHIFT 27 +#define RCC_PLLCFGR_PLLPDIV_MASK 0x1f +#define RCC_PLLCFGR_PLLPDIV_SHIFT 27 +/** @defgroup rcc_pllcfgr_pllr RCC_PLLCFGR PLLR values + * Set these bits correctly not to exceed 170 MHz on this domain. + * @{*/ #define RCC_PLLCFGR_PLLR_DIV2 0 #define RCC_PLLCFGR_PLLR_DIV4 1 #define RCC_PLLCFGR_PLLR_DIV6 2 @@ -198,17 +225,17 @@ #define RCC_PLLCFGR_PLLP BIT17 #define RCC_PLLCFGR_PLLP_DIV7 0 #define RCC_PLLCFGR_PLLP_DIV17 RCC_PLLCFGR_PLLP -#define RCC_PLLPEN (1 << 16) +#define RCC_PLLCFGR_PLLPEN (1 << 16) /** @defgroup rcc_pllcfgr_plln RCC_PLLCFGR PLLN values - * Allowed values 8 <= n <= 127, VCO output between 64 and 344 MHz + * Allowed values 8 <= n <= 127, VCO output limits specified in datasheet * @{*/ #define RCC_PLLCFGR_PLLN_SHIFT 8 #define RCC_PLLCFGR_PLLN_MASK 0x7f /**@}*/ /** @defgroup rcc_pllcfgr_pllm RCC_PLLCFGR PLLM values - * Allowed values 1 <= m <= 16, VCO input between 2.66 and 8 MHz + * Allowed values 1 <= m <= 16, VCO input limits specified in datasheet * @{*/ #define RCC_PLLCFGR_PLLM_SHIFT 0x4 #define RCC_PLLCFGR_PLLM_MASK 0xf @@ -270,7 +297,7 @@ #define RCC_AHB1RSTR_CRCRST (1 << 12) #define RCC_AHB1RSTR_FLASHRST (1 << 8) #define RCC_AHB1RSTR_FMACRST (1 << 4) -#define RCC_AHB1RSTR_CORDIC2RST (1 << 3) +#define RCC_AHB1RSTR_CORDICRST (1 << 3) #define RCC_AHB1RSTR_DMAMUX1RST (1 << 2) #define RCC_AHB1RSTR_DMA2RST (1 << 1) #define RCC_AHB1RSTR_DMA1RST (1 << 0) @@ -612,6 +639,8 @@ /** defgroup rcc_ccipr2_values RCC_CCIPR2 - Peripherals independent clock config register 2 * @{ */ +#define RCC_CCIPR2_SEL_MASK 0x3 + #define RCC_CCIPR2_QSPI_SYS 0 #define RCC_CCIPR2_QSPI_HSI16 1 #define RCC_CCIPR2_QSPI_PLLQ 2 @@ -683,6 +712,19 @@ #define RCC_CRRCR_HSI48ON BIT0 /**@}*/ +/** Enumerations for core system/bus clocks for user/driver/system access to base bus clocks + * not directly associated with a peripheral. */ +enum rcc_clock_source { + RCC_CPUCLK, + RCC_SYSCLK, + RCC_PERCLK, + RCC_SYSTICKCLK, + RCC_HCLK3, + RCC_AHBCLK, /* AHB1,2,4 all share base HCLK. */ + RCC_APB1CLK, /* Note: APB1 and PCLK1 in manual */ + RCC_APB2CLK, /* Note: APB2 and PCLK2 in manual */ +}; + /* --- Variable definitions ------------------------------------------------ */ extern uint32_t rcc_ahb_frequency; @@ -691,242 +733,303 @@ extern uint32_t rcc_apb2_frequency; /* --- Function prototypes ------------------------------------------------- */ -enum rcc_osc { - RCC_PLL, RCC_HSE, RCC_HSI16, RCC_LSE, RCC_LSI, RCC_HSI48 +enum rcc_clock_3v3 { + RCC_CLOCK_3V3_24MHZ, + RCC_CLOCK_3V3_48MHZ, + RCC_CLOCK_3V3_96MHZ, + RCC_CLOCK_3V3_170MHZ, + RCC_CLOCK_3V3_END }; +struct rcc_clock_scale { + uint8_t pllm; + uint16_t plln; + uint8_t pllp; + uint8_t pllq; + uint8_t pllr; + uint8_t pll_source; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + enum pwr_vos_scale vos_scale; + bool boost; + uint32_t flash_config; + uint8_t flash_waitstates; + uint32_t ahb_frequency; + uint32_t apb1_frequency; + uint32_t apb2_frequency; +}; + +extern const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_3V3_END]; +extern const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END]; +extern const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END]; +extern const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END]; + +enum rcc_osc { + RCC_HSI48, + RCC_PLL, + RCC_HSE, + RCC_HSI16, + RCC_LSE, + RCC_LSI +}; #define _REG_BIT(base, bit) (((base) << 5) + (bit)) enum rcc_periph_clken { /* AHB1 peripherals */ - RCC_CRC = _REG_BIT(0x48, 12), - RCC_FLASH = _REG_BIT(0x48, 8), - RCC_FMAC = _REG_BIT(0x48, 4), - RCC_CORDIC = _REG_BIT(0x48, 3), - RCC_DMAMUX1 = _REG_BIT(0x48, 2), - RCC_DMA2 = _REG_BIT(0x48, 1), - RCC_DMA1 = _REG_BIT(0x48, 0), + RCC_CRC = _REG_BIT(RCC_AHB1ENR_OFFSET, 12), + RCC_FLASH = _REG_BIT(RCC_AHB1ENR_OFFSET, 8), + RCC_FMAC = _REG_BIT(RCC_AHB1ENR_OFFSET, 4), + RCC_CORDIC = _REG_BIT(RCC_AHB1ENR_OFFSET, 3), + RCC_DMAMUX1 = _REG_BIT(RCC_AHB1ENR_OFFSET, 2), + RCC_DMA2 = _REG_BIT(RCC_AHB1ENR_OFFSET, 1), + RCC_DMA1 = _REG_BIT(RCC_AHB1ENR_OFFSET, 0), /* AHB2 peripherals */ - RCC_RNG = _REG_BIT(0x4c, 26), - RCC_AES = _REG_BIT(0x4c, 24), - RCC_DAC4 = _REG_BIT(0x4c, 19), - RCC_DAC3 = _REG_BIT(0x4c, 18), - RCC_DAC2 = _REG_BIT(0x4c, 17), - RCC_DAC1 = _REG_BIT(0x4c, 16), - RCC_ADC345 = _REG_BIT(0x4c, 14), - RCC_ADC12 = _REG_BIT(0x4c, 13), - RCC_ADC1 = _REG_BIT(0x4c, 13), /* Compatibility */ - RCC_GPIOG = _REG_BIT(0x4c, 6), - RCC_GPIOF = _REG_BIT(0x4c, 5), - RCC_GPIOE = _REG_BIT(0x4c, 4), - RCC_GPIOD = _REG_BIT(0x4c, 3), - RCC_GPIOC = _REG_BIT(0x4c, 2), - RCC_GPIOB = _REG_BIT(0x4c, 1), - RCC_GPIOA = _REG_BIT(0x4c, 0), + RCC_RNG = _REG_BIT(RCC_AHB2ENR_OFFSET, 26), + RCC_AES = _REG_BIT(RCC_AHB2ENR_OFFSET, 24), + RCC_DAC4 = _REG_BIT(RCC_AHB2ENR_OFFSET, 19), + RCC_DAC3 = _REG_BIT(RCC_AHB2ENR_OFFSET, 18), + RCC_DAC2 = _REG_BIT(RCC_AHB2ENR_OFFSET, 17), + RCC_DAC1 = _REG_BIT(RCC_AHB2ENR_OFFSET, 16), + RCC_ADC345 = _REG_BIT(RCC_AHB2ENR_OFFSET, 14), + RCC_ADC12 = _REG_BIT(RCC_AHB2ENR_OFFSET, 13), + RCC_ADC1 = _REG_BIT(RCC_AHB2ENR_OFFSET, 13), /* Compatibility */ + RCC_GPIOG = _REG_BIT(RCC_AHB2ENR_OFFSET, 6), + RCC_GPIOF = _REG_BIT(RCC_AHB2ENR_OFFSET, 5), + RCC_GPIOE = _REG_BIT(RCC_AHB2ENR_OFFSET, 4), + RCC_GPIOD = _REG_BIT(RCC_AHB2ENR_OFFSET, 3), + RCC_GPIOC = _REG_BIT(RCC_AHB2ENR_OFFSET, 2), + RCC_GPIOB = _REG_BIT(RCC_AHB2ENR_OFFSET, 1), + RCC_GPIOA = _REG_BIT(RCC_AHB2ENR_OFFSET, 0), /* AHB3 peripherals */ - RCC_QSPI = _REG_BIT(0x50, 8), - RCC_FMC = _REG_BIT(0x50, 0), + RCC_QSPI = _REG_BIT(RCC_AHB3ENR_OFFSET, 8), + RCC_FMC = _REG_BIT(RCC_AHB3ENR_OFFSET, 0), /* APB1 peripherals */ - RCC_LPTIM1 = _REG_BIT(0x58, 31), - RCC_I2C3 = _REG_BIT(0x58, 30), - RCC_PWR = _REG_BIT(0x58, 28), - RCC_FDCAN = _REG_BIT(0x58, 25), - RCC_USB = _REG_BIT(0x58, 23), - RCC_I2C2 = _REG_BIT(0x58, 22), - RCC_I2C1 = _REG_BIT(0x58, 21), - RCC_UART5 = _REG_BIT(0x58, 20), - RCC_UART4 = _REG_BIT(0x58, 19), - RCC_USART3 = _REG_BIT(0x58, 18), - RCC_USART2 = _REG_BIT(0x58, 17), - RCC_SPI3 = _REG_BIT(0x58, 15), - RCC_SPI2 = _REG_BIT(0x58, 14), - RCC_WWDG = _REG_BIT(0x58, 11), - RCC_RTCAPB = _REG_BIT(0x58, 10), - RCC_CRS = _REG_BIT(0x58, 8), - RCC_TIM7 = _REG_BIT(0x58, 5), - RCC_TIM6 = _REG_BIT(0x58, 4), - RCC_TIM5 = _REG_BIT(0x58, 3), - RCC_TIM4 = _REG_BIT(0x58, 2), - RCC_TIM3 = _REG_BIT(0x58, 1), - RCC_TIM2 = _REG_BIT(0x58, 0), + RCC_LPTIM1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 31), + RCC_I2C3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 30), + RCC_PWR = _REG_BIT(RCC_APB1ENR1_OFFSET, 28), + RCC_FDCAN = _REG_BIT(RCC_APB1ENR1_OFFSET, 25), + RCC_USB = _REG_BIT(RCC_APB1ENR1_OFFSET, 23), + RCC_I2C2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 22), + RCC_I2C1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 21), + RCC_UART5 = _REG_BIT(RCC_APB1ENR1_OFFSET, 20), + RCC_UART4 = _REG_BIT(RCC_APB1ENR1_OFFSET, 19), + RCC_USART3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 18), + RCC_USART2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 17), + RCC_SPI3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 15), + RCC_SPI2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 14), + RCC_WWDG = _REG_BIT(RCC_APB1ENR1_OFFSET, 11), + RCC_RTCAPB = _REG_BIT(RCC_APB1ENR1_OFFSET, 10), + RCC_CRS = _REG_BIT(RCC_APB1ENR1_OFFSET, 8), + RCC_TIM7 = _REG_BIT(RCC_APB1ENR1_OFFSET, 5), + RCC_TIM6 = _REG_BIT(RCC_APB1ENR1_OFFSET, 4), + RCC_TIM5 = _REG_BIT(RCC_APB1ENR1_OFFSET, 3), + RCC_TIM4 = _REG_BIT(RCC_APB1ENR1_OFFSET, 2), + RCC_TIM3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 1), + RCC_TIM2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 0), /* apb1-2 */ - RCC_UCPD1 = _REG_BIT(0x5c, 8), - RCC_I2C4 = _REG_BIT(0x5c, 1), - RCC_LPUART1 = _REG_BIT(0x5c, 0), + RCC_UCPD1 = _REG_BIT(RCC_APB1ENR2_OFFSET, 8), + RCC_I2C4 = _REG_BIT(RCC_APB1ENR2_OFFSET, 1), + RCC_LPUART1 = _REG_BIT(RCC_APB1ENR2_OFFSET, 0), /* APB2 peripherals */ - RCC_HRTIM1 = _REG_BIT(0x60, 26), - RCC_SAI1 = _REG_BIT(0x60, 21), - RCC_TIM20 = _REG_BIT(0x60, 20), - RCC_TIM17 = _REG_BIT(0x60, 18), - RCC_TIM16 = _REG_BIT(0x60, 17), - RCC_TIM15 = _REG_BIT(0x60, 16), - RCC_SPI4 = _REG_BIT(0x60, 15), - RCC_USART1 = _REG_BIT(0x60, 14), - RCC_TIM8 = _REG_BIT(0x60, 13), - RCC_SPI1 = _REG_BIT(0x60, 12), - RCC_TIM1 = _REG_BIT(0x60, 11), - RCC_SYSCFG = _REG_BIT(0x60, 0), + RCC_HRTIM1 = _REG_BIT(RCC_APB2ENR_OFFSET, 26), + RCC_SAI1 = _REG_BIT(RCC_APB2ENR_OFFSET, 21), + RCC_TIM20 = _REG_BIT(RCC_APB2ENR_OFFSET, 20), + RCC_TIM17 = _REG_BIT(RCC_APB2ENR_OFFSET, 18), + RCC_TIM16 = _REG_BIT(RCC_APB2ENR_OFFSET, 17), + RCC_TIM15 = _REG_BIT(RCC_APB2ENR_OFFSET, 16), + RCC_SPI4 = _REG_BIT(RCC_APB2ENR_OFFSET, 15), + RCC_USART1 = _REG_BIT(RCC_APB2ENR_OFFSET, 14), + RCC_TIM8 = _REG_BIT(RCC_APB2ENR_OFFSET, 13), + RCC_SPI1 = _REG_BIT(RCC_APB2ENR_OFFSET, 12), + RCC_TIM1 = _REG_BIT(RCC_APB2ENR_OFFSET, 11), + RCC_SYSCFG = _REG_BIT(RCC_APB2ENR_OFFSET, 0), /* AHB1 peripherals in sleep mode */ - SCC_CRC = _REG_BIT(0x68, 12), - SCC_SRAM1 = _REG_BIT(0x68, 9), - SCC_FLASH = _REG_BIT(0x68, 8), - SCC_FMAC = _REG_BIT(0x68, 4), - SCC_CORDIC = _REG_BIT(0x68, 3), - SCC_DMAMUX1 = _REG_BIT(0x68, 2), - SCC_DMA2 = _REG_BIT(0x68, 1), - SCC_DMA1 = _REG_BIT(0x68, 0), + SCC_CRC = _REG_BIT(RCC_AHB1SMENR_OFFSET, 12), + SCC_SRAM1 = _REG_BIT(RCC_AHB1SMENR_OFFSET, 9), + SCC_FLASH = _REG_BIT(RCC_AHB1SMENR_OFFSET, 8), + SCC_FMAC = _REG_BIT(RCC_AHB1SMENR_OFFSET, 4), + SCC_CORDIC = _REG_BIT(RCC_AHB1SMENR_OFFSET, 3), + SCC_DMAMUX1 = _REG_BIT(RCC_AHB1SMENR_OFFSET, 2), + SCC_DMA2 = _REG_BIT(RCC_AHB1SMENR_OFFSET, 1), + SCC_DMA1 = _REG_BIT(RCC_AHB1SMENR_OFFSET, 0), /* AHB2 peripherals in sleep mode */ - SCC_RNG = _REG_BIT(0x6c, 26), - SCC_AES = _REG_BIT(0x6c, 24), - SCC_DAC4 = _REG_BIT(0x6c, 19), - SCC_DAC3 = _REG_BIT(0x6c, 18), - SCC_DAC2 = _REG_BIT(0x6c, 17), - SCC_DAC1 = _REG_BIT(0x6c, 16), - SCC_ADC345 = _REG_BIT(0x6c, 14), - SCC_ADC12 = _REG_BIT(0x6c, 13), - SCC_ADC1 = _REG_BIT(0x6c, 13), /* Compatibility */ - SCC_CCMSRAM = _REG_BIT(0x6c, 10), - SCC_SRAM2 = _REG_BIT(0x6c, 9), - SCC_GPIOG = _REG_BIT(0x6c, 6), - SCC_GPIOF = _REG_BIT(0x6c, 5), - SCC_GPIOE = _REG_BIT(0x6c, 4), - SCC_GPIOD = _REG_BIT(0x6c, 3), - SCC_GPIOC = _REG_BIT(0x6c, 2), - SCC_GPIOB = _REG_BIT(0x6c, 1), - SCC_GPIOA = _REG_BIT(0x6c, 0), + SCC_RNG = _REG_BIT(RCC_AHB2SMENR_OFFSET, 26), + SCC_AES = _REG_BIT(RCC_AHB2SMENR_OFFSET, 24), + SCC_DAC4 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 19), + SCC_DAC3 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 18), + SCC_DAC2 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 17), + SCC_DAC1 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 16), + SCC_ADC345 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 14), + SCC_ADC12 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 13), + SCC_ADC1 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 13), /* Compatibility */ + SCC_CCMSRAM = _REG_BIT(RCC_AHB2SMENR_OFFSET, 10), + SCC_SRAM2 = _REG_BIT(RCC_AHB2SMENR_OFFSET, 9), + SCC_GPIOG = _REG_BIT(RCC_AHB2SMENR_OFFSET, 6), + SCC_GPIOF = _REG_BIT(RCC_AHB2SMENR_OFFSET, 5), + SCC_GPIOE = _REG_BIT(RCC_AHB2SMENR_OFFSET, 4), + SCC_GPIOD = _REG_BIT(RCC_AHB2SMENR_OFFSET, 3), + SCC_GPIOC = _REG_BIT(RCC_AHB2SMENR_OFFSET, 2), + SCC_GPIOB = _REG_BIT(RCC_AHB2SMENR_OFFSET, 1), + SCC_GPIOA = _REG_BIT(RCC_AHB2SMENR_OFFSET, 0), /* AHB3 peripherals in sleep mode */ - SCC_QSPI = _REG_BIT(0x70, 8), - SCC_FMC = _REG_BIT(0x70, 0), + SCC_QSPI = _REG_BIT(RCC_AHB3SMENR_OFFSET, 8), + SCC_FMC = _REG_BIT(RCC_AHB3SMENR_OFFSET, 0), /* APB1 peripherals in sleep mode */ - SCC_LPTIM1 = _REG_BIT(0x58, 31), - SCC_I2C3 = _REG_BIT(0x58, 30), - SCC_PWR = _REG_BIT(0x58, 28), - SCC_FDCAN = _REG_BIT(0x58, 25), - SCC_USB = _REG_BIT(0x58, 23), - SCC_I2C2 = _REG_BIT(0x58, 22), - SCC_I2C1 = _REG_BIT(0x58, 21), - SCC_UART5 = _REG_BIT(0x58, 20), - SCC_UART4 = _REG_BIT(0x58, 19), - SCC_USART3 = _REG_BIT(0x58, 18), - SCC_USART2 = _REG_BIT(0x58, 17), - SCC_SPI3 = _REG_BIT(0x58, 15), - SCC_SPI2 = _REG_BIT(0x58, 14), - SCC_WWDG = _REG_BIT(0x58, 11), - SCC_RTCAPB = _REG_BIT(0x58, 10), - SCC_CRS = _REG_BIT(0x58, 8), - SCC_TIM7 = _REG_BIT(0x58, 5), - SCC_TIM6 = _REG_BIT(0x58, 4), - SCC_TIM5 = _REG_BIT(0x58, 3), - SCC_TIM4 = _REG_BIT(0x58, 2), - SCC_TIM3 = _REG_BIT(0x58, 1), - SCC_TIM2 = _REG_BIT(0x58, 0), + SCC_LPTIM1 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 31), + SCC_I2C3 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 30), + SCC_PWR = _REG_BIT(RCC_APB1SMENR1_OFFSET, 28), + SCC_FDCAN = _REG_BIT(RCC_APB1SMENR1_OFFSET, 25), + SCC_USB = _REG_BIT(RCC_APB1SMENR1_OFFSET, 23), + SCC_I2C2 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 22), + SCC_I2C1 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 21), + SCC_UART5 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 20), + SCC_UART4 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 19), + SCC_USART3 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 18), + SCC_USART2 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 17), + SCC_SPI3 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 15), + SCC_SPI2 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 14), + SCC_WWDG = _REG_BIT(RCC_APB1SMENR1_OFFSET, 11), + SCC_RTCAPB = _REG_BIT(RCC_APB1SMENR1_OFFSET, 10), + SCC_CRS = _REG_BIT(RCC_APB1SMENR1_OFFSET, 8), + SCC_TIM7 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 5), + SCC_TIM6 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 4), + SCC_TIM5 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 3), + SCC_TIM4 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 2), + SCC_TIM3 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 1), + SCC_TIM2 = _REG_BIT(RCC_APB1SMENR1_OFFSET, 0), /* apb1-2 */ - SCC_UCPD1 = _REG_BIT(0x5c, 8), - SCC_I2C4 = _REG_BIT(0x5c, 1), - SCC_LPUART1 = _REG_BIT(0x5c, 0), + SCC_UCPD1 = _REG_BIT(RCC_APB1SMENR2_OFFSET, 8), + SCC_I2C4 = _REG_BIT(RCC_APB1SMENR2_OFFSET, 1), + SCC_LPUART1 = _REG_BIT(RCC_APB1SMENR2_OFFSET, 0), /* APB2 peripherals in sleep mode */ - SCC_HRTIM1 = _REG_BIT(0x60, 26), - SCC_SAI1 = _REG_BIT(0x60, 21), - SCC_TIM20 = _REG_BIT(0x60, 20), - SCC_TIM17 = _REG_BIT(0x60, 18), - SCC_TIM16 = _REG_BIT(0x60, 17), - SCC_TIM15 = _REG_BIT(0x60, 16), - SCC_SPI4 = _REG_BIT(0x60, 15), - SCC_USART1 = _REG_BIT(0x60, 14), - SCC_TIM8 = _REG_BIT(0x60, 13), - SCC_SPI1 = _REG_BIT(0x60, 12), - SCC_TIM1 = _REG_BIT(0x60, 11), - SCC_SYSCFG = _REG_BIT(0x60, 0), + SCC_HRTIM1 = _REG_BIT(RCC_APB2SMENR_OFFSET, 26), + SCC_SAI1 = _REG_BIT(RCC_APB2SMENR_OFFSET, 21), + SCC_TIM20 = _REG_BIT(RCC_APB2SMENR_OFFSET, 20), + SCC_TIM17 = _REG_BIT(RCC_APB2SMENR_OFFSET, 18), + SCC_TIM16 = _REG_BIT(RCC_APB2SMENR_OFFSET, 17), + SCC_TIM15 = _REG_BIT(RCC_APB2SMENR_OFFSET, 16), + SCC_SPI4 = _REG_BIT(RCC_APB2SMENR_OFFSET, 15), + SCC_USART1 = _REG_BIT(RCC_APB2SMENR_OFFSET, 14), + SCC_TIM8 = _REG_BIT(RCC_APB2SMENR_OFFSET, 13), + SCC_SPI1 = _REG_BIT(RCC_APB2SMENR_OFFSET, 12), + SCC_TIM1 = _REG_BIT(RCC_APB2SMENR_OFFSET, 11), + SCC_SYSCFG = _REG_BIT(RCC_APB2SMENR_OFFSET, 0), }; enum rcc_periph_rst { /* AHB1 peripherals */ - RST_CRC = _REG_BIT(0x28, 12), - RST_FLASH = _REG_BIT(0x28, 8), - RST_FMAC = _REG_BIT(0x28, 4), - RST_CORDIC = _REG_BIT(0x28, 3), - RST_DMAMUX1 = _REG_BIT(0x28, 2), - RST_DMA2 = _REG_BIT(0x28, 1), - RST_DMA1 = _REG_BIT(0x28, 0), + RST_CRC = _REG_BIT(RCC_AHB1RSTR_OFFSET, 12), + RST_FLASH = _REG_BIT(RCC_AHB1RSTR_OFFSET, 8), + RST_FMAC = _REG_BIT(RCC_AHB1RSTR_OFFSET, 4), + RST_CORDIC = _REG_BIT(RCC_AHB1RSTR_OFFSET, 3), + RST_DMAMUX1 = _REG_BIT(RCC_AHB1RSTR_OFFSET, 2), + RST_DMA2 = _REG_BIT(RCC_AHB1RSTR_OFFSET, 1), + RST_DMA1 = _REG_BIT(RCC_AHB1RSTR_OFFSET, 0), /* AHB2 peripherals */ - RST_RNG = _REG_BIT(0x2c, 26), - RST_AES = _REG_BIT(0x2c, 24), - RST_DAC4 = _REG_BIT(0x2c, 19), - RST_DAC3 = _REG_BIT(0x2c, 18), - RST_DAC2 = _REG_BIT(0x2c, 17), - RST_DAC1 = _REG_BIT(0x2c, 16), - RST_ADC345 = _REG_BIT(0x2c, 14), - RST_ADC12 = _REG_BIT(0x2c, 13), - RST_ADC1 = _REG_BIT(0x2c, 13), /* Compatibility */ - RST_GPIOG = _REG_BIT(0x2c, 6), - RST_GPIOF = _REG_BIT(0x2c, 5), - RST_GPIOE = _REG_BIT(0x2c, 4), - RST_GPIOD = _REG_BIT(0x2c, 3), - RST_GPIOC = _REG_BIT(0x2c, 2), - RST_GPIOB = _REG_BIT(0x2c, 1), - RST_GPIOA = _REG_BIT(0x2c, 0), + RST_RNG = _REG_BIT(RCC_AHB2RSTR_OFFSET, 26), + RST_AES = _REG_BIT(RCC_AHB2RSTR_OFFSET, 24), + RST_DAC4 = _REG_BIT(RCC_AHB2RSTR_OFFSET, 19), + RST_DAC3 = _REG_BIT(RCC_AHB2RSTR_OFFSET, 18), + RST_DAC2 = _REG_BIT(RCC_AHB2RSTR_OFFSET, 17), + RST_DAC1 = _REG_BIT(RCC_AHB2RSTR_OFFSET, 16), + RST_ADC345 = _REG_BIT(RCC_AHB2RSTR_OFFSET, 14), + RST_ADC12 = _REG_BIT(RCC_AHB2RSTR_OFFSET, 13), + RST_ADC1 = _REG_BIT(RCC_AHB2RSTR_OFFSET, 13), /* Compatibility */ + RST_GPIOG = _REG_BIT(RCC_AHB2RSTR_OFFSET, 6), + RST_GPIOF = _REG_BIT(RCC_AHB2RSTR_OFFSET, 5), + RST_GPIOE = _REG_BIT(RCC_AHB2RSTR_OFFSET, 4), + RST_GPIOD = _REG_BIT(RCC_AHB2RSTR_OFFSET, 3), + RST_GPIOC = _REG_BIT(RCC_AHB2RSTR_OFFSET, 2), + RST_GPIOB = _REG_BIT(RCC_AHB2RSTR_OFFSET, 1), + RST_GPIOA = _REG_BIT(RCC_AHB2RSTR_OFFSET, 0), /* AHB3 peripherals */ - RST_QSPI = _REG_BIT(0x30, 8), - RST_FMC = _REG_BIT(0x30, 0), + RST_QSPI = _REG_BIT(RCC_AHB3RSTR_OFFSET, 8), + RST_FMC = _REG_BIT(RCC_AHB3RSTR_OFFSET, 0), /* APB1 peripherals */ - RST_LPTIM1 = _REG_BIT(0x38, 31), - RST_I2C3 = _REG_BIT(0x38, 30), - RST_PWR = _REG_BIT(0x38, 28), - RST_FDCAN = _REG_BIT(0x38, 25), - RST_USB = _REG_BIT(0x38, 23), - RST_I2C2 = _REG_BIT(0x38, 22), - RST_I2C1 = _REG_BIT(0x38, 21), - RST_UART5 = _REG_BIT(0x38, 20), - RST_UART4 = _REG_BIT(0x38, 19), - RST_USART3 = _REG_BIT(0x38, 18), - RST_USART2 = _REG_BIT(0x38, 17), - RST_SPI3 = _REG_BIT(0x38, 15), - RST_SPI2 = _REG_BIT(0x38, 14), - RST_CRS = _REG_BIT(0x38, 8), - RST_TIM7 = _REG_BIT(0x38, 5), - RST_TIM6 = _REG_BIT(0x38, 4), - RST_TIM5 = _REG_BIT(0x38, 3), - RST_TIM4 = _REG_BIT(0x38, 2), - RST_TIM3 = _REG_BIT(0x38, 1), - RST_TIM2 = _REG_BIT(0x38, 0), + RST_LPTIM1 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 31), + RST_I2C3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 30), + RST_PWR = _REG_BIT(RCC_APB1RSTR1_OFFSET, 28), + RST_FDCAN = _REG_BIT(RCC_APB1RSTR1_OFFSET, 25), + RST_USB = _REG_BIT(RCC_APB1RSTR1_OFFSET, 23), + RST_I2C2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 22), + RST_I2C1 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 21), + RST_UART5 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 20), + RST_UART4 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 19), + RST_USART3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 18), + RST_USART2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 17), + RST_SPI3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 15), + RST_SPI2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 14), + RST_CRS = _REG_BIT(RCC_APB1RSTR1_OFFSET, 8), + RST_TIM7 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 5), + RST_TIM6 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 4), + RST_TIM5 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 3), + RST_TIM4 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 2), + RST_TIM3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 1), + RST_TIM2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 0), /* apb1-2 */ - RST_UCPD1 = _REG_BIT(0x3c, 8), - RST_I2C4 = _REG_BIT(0x3c, 1), - RST_LPUART1 = _REG_BIT(0x3c, 0), + RST_UCPD1 = _REG_BIT(RCC_APB1RSTR2_OFFSET, 8), + RST_I2C4 = _REG_BIT(RCC_APB1RSTR2_OFFSET, 1), + RST_LPUART1 = _REG_BIT(RCC_APB1RSTR2_OFFSET, 0), /* APB2 peripherals */ - RST_HRTIM1 = _REG_BIT(0x40, 26), - RST_SAI1 = _REG_BIT(0x40, 21), - RST_TIM20 = _REG_BIT(0x40, 20), - RST_TIM17 = _REG_BIT(0x40, 18), - RST_TIM16 = _REG_BIT(0x40, 17), - RST_TIM15 = _REG_BIT(0x40, 16), - RST_SPI4 = _REG_BIT(0x40, 15), - RST_USART1 = _REG_BIT(0x40, 14), - RST_TIM8 = _REG_BIT(0x40, 13), - RST_SPI1 = _REG_BIT(0x40, 12), - RST_TIM1 = _REG_BIT(0x40, 11), - RST_SYSCFG = _REG_BIT(0x40, 0), + RST_HRTIM1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 26), + RST_SAI1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 21), + RST_TIM20 = _REG_BIT(RCC_APB2RSTR_OFFSET, 20), + RST_TIM17 = _REG_BIT(RCC_APB2RSTR_OFFSET, 18), + RST_TIM16 = _REG_BIT(RCC_APB2RSTR_OFFSET, 17), + RST_TIM15 = _REG_BIT(RCC_APB2RSTR_OFFSET, 16), + RST_SPI4 = _REG_BIT(RCC_APB2RSTR_OFFSET, 15), + RST_USART1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 14), + RST_TIM8 = _REG_BIT(RCC_APB2RSTR_OFFSET, 13), + RST_SPI1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 12), + RST_TIM1 = _REG_BIT(RCC_APB2RSTR_OFFSET, 11), + RST_SYSCFG = _REG_BIT(RCC_APB2RSTR_OFFSET, 0), }; + +#undef _REG_BIT + #include BEGIN_DECLS +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_wait_for_sysclk_status(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_set_sysclk_source(uint32_t clk); +void rcc_set_pll_source(uint32_t pllsrc); +void rcc_set_ppre2(uint32_t ppre2); +void rcc_set_ppre1(uint32_t ppre1); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_main_pll(uint32_t pllsrc, uint32_t pllm, uint32_t plln, + uint32_t pllp, uint32_t pllq, uint32_t pllr); +uint32_t rcc_system_clock_source(void); +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); +void __attribute__((deprecated("Use rcc_clock_setup_pll as direct replacement"))) rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock); +void rcc_set_clock48_source(uint32_t clksel); END_DECLS diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 5690c616..019951ba 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -38,7 +38,7 @@ ARFLAGS = rcs OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += pwr.o -OBJS += rcc_common_all.o +OBJS += rcc.o rcc_common_all.o VPATH += ../../usb:../:../../cm3:../common VPATH += ../../ethernet diff --git a/lib/stm32/g4/rcc.c b/lib/stm32/g4/rcc.c new file mode 100644 index 00000000..f6bd2fff --- /dev/null +++ b/lib/stm32/g4/rcc.c @@ -0,0 +1,766 @@ +/** @defgroup rcc_file RCC peripheral API + * + * @ingroup peripheral_apis + * + * @brief libopencm3 STM32G4xx Reset and Clock Control + * + * @author @htmlonly © @endhtmlonly 2009 Federico Ruiz-Ugalde + * @author @htmlonly © @endhtmlonly 2009 Uwe Hermann + * @author @htmlonly © @endhtmlonly 2010 Thomas Otto + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian + * @author @htmlonly © @endhtmlonly 2020 Sam Kirkham + * @author @htmlonly © @endhtmlonly 2020 Ben Brewer + * + * @date 30 July 2020 + * + * This library supports the Reset and Clock Control System in the STM32 series + * of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2013 Frantisek Burian + * Copyright (C) 2020 Sam Kirkham + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + + +#include +#include +#include +#include + +/**@{*/ + +/* Set the default clock frequencies after reset. */ +uint32_t rcc_ahb_frequency = 16000000; +uint32_t rcc_apb1_frequency = 16000000; +uint32_t rcc_apb2_frequency = 16000000; + +const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_3V3_END] = { + { /* 24MHz */ + .pllm = 2, + .plln = 12, + .pllp = 0, + .pllq = 2, + .pllr = 4, + .pll_source = RCC_PLLCFGR_PLLSRC_HSI16, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE2, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 1, + .ahb_frequency = 24e6, + .apb1_frequency = 24e6, + .apb2_frequency = 24e6, + }, + { /* 48MHz */ + .pllm = 2, + .plln = 12, + .pllp = 0, + .pllq = 2, + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSI16, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 1, + .ahb_frequency = 48e6, + .apb1_frequency = 48e6, + .apb2_frequency = 48e6, + }, + { /* 96MHz */ + .pllm = 2, + .plln = 24, + .pllp = 0, + .pllq = 4, + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSI16, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 3, + .ahb_frequency = 96e6, + .apb1_frequency = 96e6, + .apb2_frequency = 96e6, + }, + { /* 170MHz */ + .pllm = 4, + .plln = 85, + .pllp = 0, + .pllq = 0, /* USB requires CRS at this speed. */ + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSI16, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = true, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 4, + .ahb_frequency = 170e6, + .apb1_frequency = 170e6, + .apb2_frequency = 170e6, + }, +}; + +const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 24MHz */ + .pllm = 1, + .plln = 12, + .pllp = 0, + .pllq = 2, + .pllr = 4, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE2, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 1, + .ahb_frequency = 24e6, + .apb1_frequency = 24e6, + .apb2_frequency = 24e6, + }, + { /* 48MHz */ + .pllm = 1, + .plln = 12, + .pllp = 0, + .pllq = 2, + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 1, + .ahb_frequency = 48e6, + .apb1_frequency = 48e6, + .apb2_frequency = 48e6, + }, + { /* 96MHz */ + .pllm = 1, + .plln = 24, + .pllp = 0, + .pllq = 4, + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 3, + .ahb_frequency = 96e6, + .apb1_frequency = 96e6, + .apb2_frequency = 96e6, + }, + { /* 170MHz */ + .pllm = 2, + .plln = 85, + .pllp = 0, + .pllq = 0, /* USB requires CRS at this speed. */ + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = true, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 4, + .ahb_frequency = 170e6, + .apb1_frequency = 170e6, + .apb2_frequency = 170e6, + }, +}; + + +const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 24MHz */ + .pllm = 2, + .plln = 16, + .pllp = 0, + .pllq = 2, + .pllr = 4, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE2, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 1, + .ahb_frequency = 24e6, + .apb1_frequency = 24e6, + .apb2_frequency = 24e6, + }, + { /* 48MHz */ + .pllm = 2, + .plln = 16, + .pllp = 0, + .pllq = 2, + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 1, + .ahb_frequency = 48e6, + .apb1_frequency = 48e6, + .apb2_frequency = 48e6, + }, + { /* 96MHz */ + .pllm = 2, + .plln = 32, + .pllp = 0, + .pllq = 4, + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 3, + .ahb_frequency = 96e6, + .apb1_frequency = 96e6, + .apb2_frequency = 96e6, + }, + { /* 170MHz */ + .pllm = 3, + .plln = 85, + .pllp = 0, + .pllq = 0, /* USB requires CRS at this speed. */ + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = true, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 4, + .ahb_frequency = 170e6, + .apb1_frequency = 170e6, + .apb2_frequency = 170e6, + }, +}; + +const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { + { /* 24MHz */ + .pllm = 2, + .plln = 12, + .pllp = 0, + .pllq = 2, + .pllr = 4, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE2, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 1, + .ahb_frequency = 24e6, + .apb1_frequency = 24e6, + .apb2_frequency = 24e6, + }, + { /* 48MHz */ + .pllm = 2, + .plln = 12, + .pllp = 0, + .pllq = 2, + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 1, + .ahb_frequency = 48e6, + .apb1_frequency = 48e6, + .apb2_frequency = 48e6, + }, + { /* 96MHz */ + .pllm = 2, + .plln = 24, + .pllp = 0, + .pllq = 4, + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = false, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 3, + .ahb_frequency = 96e6, + .apb1_frequency = 96e6, + .apb2_frequency = 96e6, + }, + { /* 170MHz */ + .pllm = 4, + .plln = 85, + .pllp = 0, + .pllq = 0, /* USB requires CRS at this speed. */ + .pllr = 2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSE, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPREx_NODIV, + .ppre2 = RCC_CFGR_PPREx_NODIV, + .vos_scale = PWR_SCALE1, + .boost = true, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN, + .flash_waitstates = 4, + .ahb_frequency = 170e6, + .apb1_frequency = 170e6, + .apb2_frequency = 170e6, + }, +}; + + + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CICR |= RCC_CICR_HSI48RDYC; + break; + case RCC_PLL: + RCC_CICR |= RCC_CICR_PLLRDYC; + break; + case RCC_HSE: + RCC_CICR |= RCC_CICR_HSERDYC; + break; + case RCC_HSI16: + RCC_CICR |= RCC_CICR_HSIRDYC; + break; + case RCC_LSE: + RCC_CICR |= RCC_CICR_LSERDYC; + break; + case RCC_LSI: + RCC_CICR |= RCC_CICR_LSIRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CIER |= RCC_CIER_HSI48RDYIE; + break; + case RCC_PLL: + RCC_CIER |= RCC_CIER_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIER |= RCC_CIER_HSERDYIE; + break; + case RCC_HSI16: + RCC_CIER |= RCC_CIER_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIER |= RCC_CIER_LSERDYIE; + break; + case RCC_LSI: + RCC_CIER |= RCC_CIER_LSIRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CIER &= ~RCC_CIER_HSI48RDYIE; + break; + case RCC_PLL: + RCC_CIER &= ~RCC_CIER_PLLRDYIE; + break; + case RCC_HSE: + RCC_CIER &= ~RCC_CIER_HSERDYIE; + break; + case RCC_HSI16: + RCC_CIER &= ~RCC_CIER_HSIRDYIE; + break; + case RCC_LSE: + RCC_CIER &= ~RCC_CIER_LSERDYIE; + break; + case RCC_LSI: + RCC_CIER &= ~RCC_CIER_LSIRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + return ((RCC_CIFR & RCC_CIFR_HSI48RDYF) != 0); + case RCC_PLL: + return ((RCC_CIFR & RCC_CIFR_PLLRDYF) != 0); + case RCC_HSE: + return ((RCC_CIFR & RCC_CIFR_HSERDYF) != 0); + case RCC_HSI16: + return ((RCC_CIFR & RCC_CIFR_HSIRDYF) != 0); + case RCC_LSE: + return ((RCC_CIFR & RCC_CIFR_LSERDYF) != 0); + case RCC_LSI: + return ((RCC_CIFR & RCC_CIFR_LSIRDYF) != 0); + } + return 0; +} + +void rcc_css_int_clear(void) +{ + RCC_CICR |= RCC_CICR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIFR & RCC_CIFR_CSSF) != 0); +} + +bool rcc_is_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + return RCC_CRRCR & RCC_CRRCR_HSI48RDY; + case RCC_PLL: + return RCC_CR & RCC_CR_PLLRDY; + case RCC_HSE: + return RCC_CR & RCC_CR_HSERDY; + case RCC_HSI16: + return RCC_CR & RCC_CR_HSIRDY; + case RCC_LSE: + return RCC_BDCR & RCC_BDCR_LSERDY; + case RCC_LSI: + return RCC_CSR & RCC_CSR_LSIRDY; + } + return false; +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + while (!rcc_is_osc_ready(osc)); +} + +void rcc_wait_for_sysclk_status(enum rcc_osc osc) +{ + switch (osc) { + case RCC_PLL: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWx_PLL); + break; + case RCC_HSE: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWx_HSE); + break; + case RCC_HSI16: + while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWx_HSI16); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CRRCR |= RCC_CRRCR_HSI48ON; + break; + case RCC_PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case RCC_HSI16: + RCC_CR |= RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case RCC_LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case RCC_HSI48: + RCC_CRRCR &= ~RCC_CRRCR_HSI48ON; + break; + case RCC_PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case RCC_HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case RCC_HSI16: + RCC_CR &= ~RCC_CR_HSION; + break; + case RCC_LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case RCC_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_set_sysclk_source(uint32_t clk) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_SW_MASK << RCC_CFGR_SW_SHIFT); + RCC_CFGR = (reg32 | (clk << RCC_CFGR_SW_SHIFT)); +} + +void rcc_set_pll_source(uint32_t pllsrc) +{ + uint32_t reg32; + + reg32 = RCC_PLLCFGR; + reg32 &= ~(RCC_PLLCFGR_PLLSRC_MASK << RCC_PLLCFGR_PLLSRC_SHIFT); + RCC_PLLCFGR = (reg32 | (pllsrc << RCC_PLLCFGR_PLLSRC_SHIFT)); +} + +void rcc_set_ppre2(uint32_t ppre2) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE2_MASK << RCC_CFGR_PPRE2_SHIFT); + RCC_CFGR = (reg32 | (ppre2 << RCC_CFGR_PPRE2_SHIFT)); +} + +void rcc_set_ppre1(uint32_t ppre1) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_PPRE1_MASK << RCC_CFGR_PPRE1_SHIFT); + RCC_CFGR = (reg32 | (ppre1 << RCC_CFGR_PPRE1_SHIFT)); +} + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(RCC_CFGR_HPRE_MASK << RCC_CFGR_HPRE_SHIFT); + RCC_CFGR = (reg32 | (hpre << RCC_CFGR_HPRE_SHIFT)); +} + +/** + * Reconfigures the main PLL for a HSE source. + * Any reserved bits are kept at their reset values. + * @param pllsrc Source for the main PLL input clock + * @param pllm Divider for the main PLL input clock + * @param plln Main PLL multiplication factor for VCO + * @param pllp Main PLL divider for ADC + * @param pllq Main PLL divider for QUADSPI, FDCAN, USB, SAI & I2S + * @param pllr Main PLL divider for main system clock + */ +void rcc_set_main_pll(uint32_t pllsrc, uint32_t pllm, uint32_t plln, + uint32_t pllp, uint32_t pllq, uint32_t pllr) +{ + bool pllpen = (pllp != 0); + bool pllqen = (pllq != 0); + bool pllren = (pllr != 0); + + pllm -= 1; + + uint32_t pllpdiv = pllp; + pllp = (pllpdiv == 17); + if ((pllpdiv == 7) || (pllpdiv == 17)) { + pllpdiv = 0; + } + + pllr = (pllr >> 1) - 1; + pllq = (pllq >> 1) - 1; + + RCC_PLLCFGR = ((pllsrc & RCC_PLLCFGR_PLLSRC_MASK) << RCC_PLLCFGR_PLLSRC_SHIFT) | + ((pllm & RCC_PLLCFGR_PLLM_MASK) << RCC_PLLCFGR_PLLM_SHIFT) | + ((plln & RCC_PLLCFGR_PLLN_MASK) << RCC_PLLCFGR_PLLN_SHIFT) | + (pllpen ? RCC_PLLCFGR_PLLPEN : 0 ) | + (pllp ? RCC_PLLCFGR_PLLP_DIV17 : RCC_PLLCFGR_PLLP_DIV7) | + (pllqen ? RCC_PLLCFGR_PLLQEN : 0 ) | + ((pllq & RCC_PLLCFGR_PLLQ_MASK) << RCC_PLLCFGR_PLLQ_SHIFT) | + (pllren ? RCC_PLLCFGR_PLLREN : 0 ) | + ((pllr & RCC_PLLCFGR_PLLR_MASK) << RCC_PLLCFGR_PLLR_SHIFT) | + ((pllpdiv & RCC_PLLCFGR_PLLPDIV_MASK) << RCC_PLLCFGR_PLLPDIV_SHIFT); +} + +uint32_t rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK; +} + +/** + * Setup clocks to run from PLL. + * + * The arguments provide the pll source, multipliers, dividers, all that's + * needed to establish a system clock. + * + * @param clock clock information structure. + */ +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) +{ + /* Enable internal high-speed oscillator (HSI16). */ + rcc_osc_on(RCC_HSI16); + rcc_wait_for_osc_ready(RCC_HSI16); + + /* Select HSI16 as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SWx_HSI16); + + /* Enable external high-speed oscillator (HSE). */ + if (clock->pll_source == RCC_PLLCFGR_PLLSRC_HSE) { + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + } + + /* Set the VOS scale mode */ + rcc_periph_clock_enable(RCC_PWR); + pwr_set_vos_scale(clock->vos_scale); + + if (clock->boost) { + pwr_enable_boost(); + } else { + pwr_disable_boost(); + } + + /* + * Set prescalers for AHB, ADC, APB1, APB2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + /* Disable PLL oscillator before changing its configuration. */ + rcc_osc_off(RCC_PLL); + + /* Configure the PLL oscillator. */ + rcc_set_main_pll(clock->pll_source, + clock->pllm, clock->plln, + clock->pllp, clock->pllq, clock->pllr); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Configure flash settings. */ + if (clock->flash_config & FLASH_ACR_DCEN) { + flash_dcache_enable(); + } else { + flash_dcache_disable(); + } + if (clock->flash_config & FLASH_ACR_ICEN) { + flash_icache_enable(); + } else { + flash_icache_disable(); + } + flash_set_ws(clock->flash_waitstates); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SWx_PLL); + + /* Wait for PLL clock to be selected. */ + rcc_wait_for_sysclk_status(RCC_PLL); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; + + /* Disable internal high-speed oscillator. */ + if (clock->pll_source == RCC_PLLCFGR_PLLSRC_HSE) { + rcc_osc_off(RCC_HSI16); + } +} + +/** + * Setup clocks with the HSE. + * + * @deprecated replaced by rcc_clock_setup_pll as a drop in replacement. + * @see rcc_clock_setup_pll which supports HSI16 as well as HSE, using the same + * clock structures. + */ +void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock) +{ + rcc_clock_setup_pll(clock); +} + +/** Set clock source for 48MHz clock + * + * The 48 MHz clock is derived from one of the four following sources: + * - PLLQ VCO (RCC_CCIPR_CLK48_PLLQ) + * - HSI48 internal oscillator (RCC_CCIPR_CLK48_HSI48) + * + * @param clksel One of the definitions above + */ +void rcc_set_clock48_source(uint32_t clksel) +{ + RCC_CCIPR &= ~(RCC_CCIPR_SEL_MASK << RCC_CCIPR_CLK48_SHIFT); + RCC_CCIPR |= (clksel << RCC_CCIPR_CLK48_SHIFT); +} + +/**@}*/ From 0fbf6e8cc122ee2bed42d4a28d6889549128897e Mon Sep 17 00:00:00 2001 From: Sam Kirkham Date: Wed, 29 Jul 2020 12:35:25 +0100 Subject: [PATCH 044/206] stm32g4: Add support for Timers --- include/libopencm3/stm32/g4/timer.h | 35 +++++++++++++++++++++++++++++ include/libopencm3/stm32/timer.h | 2 ++ lib/stm32/g4/Makefile | 1 + 3 files changed, 38 insertions(+) create mode 100644 include/libopencm3/stm32/g4/timer.h diff --git a/include/libopencm3/stm32/g4/timer.h b/include/libopencm3/stm32/g4/timer.h new file mode 100644 index 00000000..06a661c7 --- /dev/null +++ b/include/libopencm3/stm32/g4/timer.h @@ -0,0 +1,35 @@ +/** @defgroup timer_defines Timer Defines + * + * @brief Defined Constants and Types for the STM32G4xx Timers + * + * @ingroup STM32G4xx_defines + * + * @version 1.0.0 + * + * @date 10 Jul 2020 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_TIMER_H +#define LIBOPENCM3_TIMER_H + +#include + +#endif diff --git a/include/libopencm3/stm32/timer.h b/include/libopencm3/stm32/timer.h index 32ddd157..a1d10a5c 100644 --- a/include/libopencm3/stm32/timer.h +++ b/include/libopencm3/stm32/timer.h @@ -42,6 +42,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include #else diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 019951ba..6fbaebb2 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -39,6 +39,7 @@ OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += pwr.o OBJS += rcc.o rcc_common_all.o +OBJS += timer_common_all.o timer_common_f0234.o VPATH += ../../usb:../:../../cm3:../common VPATH += ../../ethernet From 17d6660491e28acdd5baaf7e7e3634ab49032faf Mon Sep 17 00:00:00 2001 From: Sam Kirkham Date: Wed, 29 Jul 2020 12:37:04 +0100 Subject: [PATCH 045/206] stm32g4: Add support for DMAMUX Co-authored-by: Ben Brewer --- include/libopencm3/stm32/dmamux.h | 2 + include/libopencm3/stm32/g4/dmamux.h | 216 +++++++++++++++++++++++++++ lib/stm32/g4/Makefile | 1 + 3 files changed, 219 insertions(+) create mode 100644 include/libopencm3/stm32/g4/dmamux.h diff --git a/include/libopencm3/stm32/dmamux.h b/include/libopencm3/stm32/dmamux.h index 291bc7d9..09a190c4 100644 --- a/include/libopencm3/stm32/dmamux.h +++ b/include/libopencm3/stm32/dmamux.h @@ -22,6 +22,8 @@ #if defined(STM32G0) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined." #endif diff --git a/include/libopencm3/stm32/g4/dmamux.h b/include/libopencm3/stm32/g4/dmamux.h new file mode 100644 index 00000000..1a746620 --- /dev/null +++ b/include/libopencm3/stm32/g4/dmamux.h @@ -0,0 +1,216 @@ +/** @defgroup dmamux_defines DMAMUX Defines + +@ingroup STM32G4xx_defines + +@brief Defined Constants and Types for the STM32G4xx DMAMUX + +@version 1.0.0 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DMAMUX_H +#define LIBOPENCM3_DMAMUX_H +/**@{*/ + +#include + + /** @defgroup dmamux_reg_base DMAMUX register base addresses + * @{ + */ +#define DMAMUX1 DMAMUX_BASE +/**@}*/ + +/* --- DMAMUX_CxCR values ------------------------------------ */ + +/** @defgroup dmamux_cxcr_sync_id SYNCID Synchronization input selected +@{*/ +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE0 0 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE1 1 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE2 2 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE3 3 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE4 4 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE5 5 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE6 6 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE7 7 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE8 8 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE9 9 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE10 10 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE11 11 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE12 12 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE13 13 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE14 14 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE15 15 +#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH0_EVT 16 +#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH1_EVT 17 +#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH2_EVT 18 +#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH3_EVT 19 +#define DMAMUX_CxCR_SYNC_ID_LPTIM1_OUT 20 + + +/** @defgroup dmamux_cxcr_dmareq_id DMAREQID DMA request line selected +@{*/ +#define DMAMUX_CxCR_DMAREQ_ID_DMAMUX_REQ_GEN0 1 +#define DMAMUX_CxCR_DMAREQ_ID_DMAMUX_REQ_GEN1 2 +#define DMAMUX_CxCR_DMAREQ_ID_DMAMUX_REQ_GEN2 3 +#define DMAMUX_CxCR_DMAREQ_ID_DMAMUX_REQ_GEN3 4 +#define DMAMUX_CxCR_DMAREQ_ID_ADC1 5 +#define DMAMUX_CxCR_DMAREQ_ID_DAC1_CH1 6 +#define DMAMUX_CxCR_DMAREQ_ID_DAC1_CH2 7 +#define DMAMUX_CxCR_DMAREQ_ID_TIM6_UP 8 +#define DMAMUX_CxCR_DMAREQ_ID_TIM7_UP 9 +#define DMAMUX_CxCR_DMAREQ_ID_SPI1_RX 10 +#define DMAMUX_CxCR_DMAREQ_ID_SPI1_TX 11 +#define DMAMUX_CxCR_DMAREQ_ID_SPI2_RX 12 +#define DMAMUX_CxCR_DMAREQ_ID_SPI2_TX 13 +#define DMAMUX_CxCR_DMAREQ_ID_SPI3_RX 14 +#define DMAMUX_CxCR_DMAREQ_ID_SPI3_TX 15 +#define DMAMUX_CxCR_DMAREQ_ID_I2C1_RX 16 +#define DMAMUX_CxCR_DMAREQ_ID_I2C1_TX 17 +#define DMAMUX_CxCR_DMAREQ_ID_I2C2_RX 18 +#define DMAMUX_CxCR_DMAREQ_ID_I2C2_TX 19 +#define DMAMUX_CxCR_DMAREQ_ID_I2C3_RX 20 +#define DMAMUX_CxCR_DMAREQ_ID_I2C3_TX 21 +#define DMAMUX_CxCR_DMAREQ_ID_I2C4_RX 22 +#define DMAMUX_CxCR_DMAREQ_ID_I2C4_TX 23 +#define DMAMUX_CxCR_DMAREQ_ID_UART1_RX 24 +#define DMAMUX_CxCR_DMAREQ_ID_UART1_TX 25 +#define DMAMUX_CxCR_DMAREQ_ID_UART2_RX 26 +#define DMAMUX_CxCR_DMAREQ_ID_UART2_TX 27 +#define DMAMUX_CxCR_DMAREQ_ID_UART3_RX 28 +#define DMAMUX_CxCR_DMAREQ_ID_UART3_TX 29 +#define DMAMUX_CxCR_DMAREQ_ID_UART4_RX 30 +#define DMAMUX_CxCR_DMAREQ_ID_UART4_TX 31 +#define DMAMUX_CxCR_DMAREQ_ID_UART5_RX 32 +#define DMAMUX_CxCR_DMAREQ_ID_UART5_TX 33 +#define DMAMUX_CxCR_DMAREQ_ID_LPUART1_RX 34 +#define DMAMUX_CxCR_DMAREQ_ID_LPUART1_TX 35 +#define DMAMUX_CxCR_DMAREQ_ID_ADC2 36 +#define DMAMUX_CxCR_DMAREQ_ID_ADC3 37 +#define DMAMUX_CxCR_DMAREQ_ID_ADC4 38 +#define DMAMUX_CxCR_DMAREQ_ID_ADC5 39 +#define DMAMUX_CxCR_DMAREQ_ID_QUADSPI 40 +#define DMAMUX_CxCR_DMAREQ_ID_DAC2_CH1 41 +#define DMAMUX_CxCR_DMAREQ_ID_TIM1_CH1 42 +#define DMAMUX_CxCR_DMAREQ_ID_TIM1_CH2 43 +#define DMAMUX_CxCR_DMAREQ_ID_TIM1_CH3 44 +#define DMAMUX_CxCR_DMAREQ_ID_TIM1_CH4 45 +#define DMAMUX_CxCR_DMAREQ_ID_TIM1_UP 46 +#define DMAMUX_CxCR_DMAREQ_ID_TIM1_TRIG 47 +#define DMAMUX_CxCR_DMAREQ_ID_TIM1_COM 48 +#define DMAMUX_CxCR_DMAREQ_ID_TIM8_CH1 49 +#define DMAMUX_CxCR_DMAREQ_ID_TIM8_CH2 50 +#define DMAMUX_CxCR_DMAREQ_ID_TIM8_CH3 51 +#define DMAMUX_CxCR_DMAREQ_ID_TIM8_CH4 52 +#define DMAMUX_CxCR_DMAREQ_ID_TIM8_UP 53 +#define DMAMUX_CxCR_DMAREQ_ID_TIM8_TRIG 54 +#define DMAMUX_CxCR_DMAREQ_ID_TIM8_COM 55 +#define DMAMUX_CxCR_DMAREQ_ID_TIM2_CH1 56 +#define DMAMUX_CxCR_DMAREQ_ID_TIM2_CH2 57 +#define DMAMUX_CxCR_DMAREQ_ID_TIM2_CH3 58 +#define DMAMUX_CxCR_DMAREQ_ID_TIM2_CH4 59 +#define DMAMUX_CxCR_DMAREQ_ID_TIM2_UP 60 +#define DMAMUX_CxCR_DMAREQ_ID_TIM3_CH1 61 +#define DMAMUX_CxCR_DMAREQ_ID_TIM3_CH2 62 +#define DMAMUX_CxCR_DMAREQ_ID_TIM3_CH3 63 +#define DMAMUX_CxCR_DMAREQ_ID_TIM3_CH4 64 +#define DMAMUX_CxCR_DMAREQ_ID_TIM3_UP 65 +#define DMAMUX_CxCR_DMAREQ_ID_TIM3_TRIG 66 +#define DMAMUX_CxCR_DMAREQ_ID_TIM4_CH1 67 +#define DMAMUX_CxCR_DMAREQ_ID_TIM4_CH2 68 +#define DMAMUX_CxCR_DMAREQ_ID_TIM4_CH3 69 +#define DMAMUX_CxCR_DMAREQ_ID_TIM4_CH4 70 +#define DMAMUX_CxCR_DMAREQ_ID_TIM4_UP 71 +#define DMAMUX_CxCR_DMAREQ_ID_TIM5_CH1 72 +#define DMAMUX_CxCR_DMAREQ_ID_TIM5_CH2 73 +#define DMAMUX_CxCR_DMAREQ_ID_TIM5_CH3 74 +#define DMAMUX_CxCR_DMAREQ_ID_TIM5_CH4 75 +#define DMAMUX_CxCR_DMAREQ_ID_TIM5_UP 76 +#define DMAMUX_CxCR_DMAREQ_ID_TIM5_TRIG 77 +#define DMAMUX_CxCR_DMAREQ_ID_TIM15_CH1 78 +#define DMAMUX_CxCR_DMAREQ_ID_TIM15_UP 79 +#define DMAMUX_CxCR_DMAREQ_ID_TIM15_TRIG 80 +#define DMAMUX_CxCR_DMAREQ_ID_TIM15_COM 81 +#define DMAMUX_CxCR_DMAREQ_ID_TIM16_CH1 82 +#define DMAMUX_CxCR_DMAREQ_ID_TIM16_UP 83 +#define DMAMUX_CxCR_DMAREQ_ID_TIM17_CH1 84 +#define DMAMUX_CxCR_DMAREQ_ID_TIM17_UP 85 +#define DMAMUX_CxCR_DMAREQ_ID_TIM20_CH1 86 +#define DMAMUX_CxCR_DMAREQ_ID_TIM20_CH2 87 +#define DMAMUX_CxCR_DMAREQ_ID_TIM20_CH3 88 +#define DMAMUX_CxCR_DMAREQ_ID_TIM20_CH4 89 +#define DMAMUX_CxCR_DMAREQ_ID_TIM20_UP 90 +#define DMAMUX_CxCR_DMAREQ_ID_AES_IN 91 +#define DMAMUX_CxCR_DMAREQ_ID_AES_OUT 92 +#define DMAMUX_CxCR_DMAREQ_ID_TIM20_TRIG 93 +#define DMAMUX_CxCR_DMAREQ_ID_TIM20_COM 94 +#define DMAMUX_CxCR_DMAREQ_ID_HRTIM_MASTER 95 +#define DMAMUX_CxCR_DMAREQ_ID_HRTIM_TIMA 96 +#define DMAMUX_CxCR_DMAREQ_ID_HRTIM_TIMB 97 +#define DMAMUX_CxCR_DMAREQ_ID_HRTIM_TIMC 98 +#define DMAMUX_CxCR_DMAREQ_ID_HRTIM_TIMD 99 +#define DMAMUX_CxCR_DMAREQ_ID_HRTIM_TIME 100 +#define DMAMUX_CxCR_DMAREQ_ID_HRTIM_TIMF 101 +#define DMAMUX_CxCR_DMAREQ_ID_DAC3_CH1 102 +#define DMAMUX_CxCR_DMAREQ_ID_DAC3_CH2 103 +#define DMAMUX_CxCR_DMAREQ_ID_DAC4_CH1 104 +#define DMAMUX_CxCR_DMAREQ_ID_DAC4_CH2 105 +#define DMAMUX_CxCR_DMAREQ_ID_SPI4_RX 106 +#define DMAMUX_CxCR_DMAREQ_ID_SPI4_TX 107 +#define DMAMUX_CxCR_DMAREQ_ID_SAI1_A 108 +#define DMAMUX_CxCR_DMAREQ_ID_SAI1_B 109 +#define DMAMUX_CxCR_DMAREQ_ID_FMAC_READ 110 +#define DMAMUX_CxCR_DMAREQ_ID_FMAC_WRITE 111 +#define DMAMUX_CxCR_DMAREQ_ID_CORDIC_READ 112 +#define DMAMUX_CxCR_DMAREQ_ID_CORDIC_WRITE 113 +#define DMAMUX_CxCR_DMAREQ_ID_UCPD1_RX 114 +#define DMAMUX_CxCR_DMAREQ_ID_UCPD1_TX 115 + +/**@}*/ + +/* --- DMAMUX_RGxCR values ----------------------------------- */ + +/** @defgroup dmamux_rgxcr_sig_id SIGID DMA request trigger input selected +@{*/ +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE0 0 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE1 1 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE2 2 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE3 3 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE4 4 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE5 5 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE6 6 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE7 7 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE8 8 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE9 9 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE10 10 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE11 11 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE12 12 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE13 13 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE14 14 +#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE15 15 +#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH0_EVT 16 +#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH1_EVT 17 +#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH2_EVT 18 +#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH3_EVT 19 +#define DMAMUX_CxCR_SYNC_ID_LPTIM1_OUT 20 +/**@}*/ + +/**@}*/ +#endif diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 6fbaebb2..be5087d8 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -35,6 +35,7 @@ TGT_CFLAGS += $(DEBUG_FLAGS) TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs +OBJS += dmamux.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += pwr.o From b84bf6e244847304af17903642af7b2c33f837ac Mon Sep 17 00:00:00 2001 From: Sam Kirkham Date: Wed, 29 Jul 2020 12:35:11 +0100 Subject: [PATCH 046/206] stm32g4: Add support for DMA --- include/libopencm3/stm32/dma.h | 2 ++ include/libopencm3/stm32/g4/dma.h | 39 +++++++++++++++++++++++++++++++ lib/stm32/g4/Makefile | 1 + 3 files changed, 42 insertions(+) create mode 100644 include/libopencm3/stm32/g4/dma.h diff --git a/include/libopencm3/stm32/dma.h b/include/libopencm3/stm32/dma.h index f914cf09..b780550d 100644 --- a/include/libopencm3/stm32/dma.h +++ b/include/libopencm3/stm32/dma.h @@ -40,6 +40,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined." #endif diff --git a/include/libopencm3/stm32/g4/dma.h b/include/libopencm3/stm32/g4/dma.h new file mode 100644 index 00000000..7ce66dee --- /dev/null +++ b/include/libopencm3/stm32/g4/dma.h @@ -0,0 +1,39 @@ +/** @defgroup dma_defines DMA Defines + * + * @ingroup STM32G4xx_defines + * + * @brief Defined Constants and Types for the STM32G4xx DMA Controller + * + * @version 1.0.0 + * + * @date 9 July 2020 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DMA_H +#define LIBOPENCM3_DMA_H + +#include + +#define DMA_CHANNEL8 8 + +#endif + diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index be5087d8..d4771707 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -35,6 +35,7 @@ TGT_CFLAGS += $(DEBUG_FLAGS) TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs +OBJS += dma_common_l1f013.o OBJS += dmamux.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o From 7219b329026da918f92e6e89e4941a841bb4c774 Mon Sep 17 00:00:00 2001 From: Ben Brewer Date: Mon, 17 Aug 2020 16:10:45 +0100 Subject: [PATCH 047/206] stm32: adc_common_v2: Make EXTSEL and ALIGN definitions per chip STM32G4 uses v2 ADC but has EXTSEL and ALIGN fields modified, rather than making a v3 ADC for these minor changes, the definitions have been moved to the chip specific headers, so that the common code can work for G4 onwards. --- include/libopencm3/stm32/common/adc_common_v2.h | 3 --- include/libopencm3/stm32/common/adc_common_v2_multi.h | 5 ----- include/libopencm3/stm32/common/adc_common_v2_single.h | 5 ----- include/libopencm3/stm32/f0/adc.h | 10 ++++++++++ include/libopencm3/stm32/f3/adc.h | 10 ++++++++++ include/libopencm3/stm32/g0/adc.h | 8 ++++++++ include/libopencm3/stm32/l0/adc.h | 10 ++++++++++ include/libopencm3/stm32/l4/adc.h | 10 ++++++++++ 8 files changed, 48 insertions(+), 13 deletions(-) diff --git a/include/libopencm3/stm32/common/adc_common_v2.h b/include/libopencm3/stm32/common/adc_common_v2.h index bd3845a1..cfb5a17d 100644 --- a/include/libopencm3/stm32/common/adc_common_v2.h +++ b/include/libopencm3/stm32/common/adc_common_v2.h @@ -150,9 +150,6 @@ specific memorymap.h header before including this header file.*/ #define ADC_CFGR1_EXTEN_BOTH_EDGES (0x3 << 10) /**@}*/ -/** ALIGN: Data alignment */ -#define ADC_CFGR1_ALIGN (1 << 5) - #define ADC_CFGR1_RES_MASK (0x3 << 3) /** @defgroup adc_cfgr1_res RES: Data resolution @{*/ diff --git a/include/libopencm3/stm32/common/adc_common_v2_multi.h b/include/libopencm3/stm32/common/adc_common_v2_multi.h index 374889b1..901c65a6 100644 --- a/include/libopencm3/stm32/common/adc_common_v2_multi.h +++ b/include/libopencm3/stm32/common/adc_common_v2_multi.h @@ -143,11 +143,6 @@ specific memorymap.h header before including this header file.*/ #define ADC_CFGR1_DISCNUM_MASK (0x7 << ADC_CFGR1_DISCNUM_SHIFT) #define ADC_CFGR1_DISCNUM_VAL(x) (((x) - 1) << ADC_CFGR1_DISCNUM_SHIFT) -/* EXTSEL[3:0]: External trigger selection for regular group */ -#define ADC_CFGR1_EXTSEL_SHIFT 6 -#define ADC_CFGR1_EXTSEL_MASK (0xf << ADC_CFGR1_EXTSEL_SHIFT) -#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) - /* ADC_SQRx Values: Regular Sequence ordering------------------------------- */ #define ADC_SQR1_L_SHIFT 0 diff --git a/include/libopencm3/stm32/common/adc_common_v2_single.h b/include/libopencm3/stm32/common/adc_common_v2_single.h index 32616cf4..71db68d9 100644 --- a/include/libopencm3/stm32/common/adc_common_v2_single.h +++ b/include/libopencm3/stm32/common/adc_common_v2_single.h @@ -58,11 +58,6 @@ specific memorymap.h header before including this header file.*/ /** Auto off mode */ #define ADC_CFGR1_AUTOFF (1 << 15) -#define ADC_CFGR1_EXTSEL_SHIFT 6 -#define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) -/** EXTSEL[2:0]: External trigger selection for regular group */ -#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) - /** SCANDIR: Scan Sequence Direction: Upwards Scan (0), Downwards(1) */ #define ADC_CFGR1_SCANDIR (1 << 2) /**@}*/ diff --git a/include/libopencm3/stm32/f0/adc.h b/include/libopencm3/stm32/f0/adc.h index bc88a578..543bd5ae 100644 --- a/include/libopencm3/stm32/f0/adc.h +++ b/include/libopencm3/stm32/f0/adc.h @@ -71,6 +71,16 @@ /* Register values */ /*****************************************************************************/ +/* ADC_CFGR1 Values ---------------------------------------------------------*/ + +/** ALIGN: Data alignment */ +#define ADC_CFGR1_ALIGN (1 << 5) + +/* EXTSEL[2:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 6 +#define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + /* ADC_CFGR2 Values ---------------------------------------------------------*/ #define ADC_CFGR2_CKMODE_SHIFT 30 diff --git a/include/libopencm3/stm32/f3/adc.h b/include/libopencm3/stm32/f3/adc.h index 5465cf72..067822f6 100644 --- a/include/libopencm3/stm32/f3/adc.h +++ b/include/libopencm3/stm32/f3/adc.h @@ -209,6 +209,16 @@ #define ADC_CR_ADVREGEN_DISABLE (0x2 << 28) #define ADC_CR_ADVREGEN_MASK (0x3 << 28) +/* ADC_CFGR1 Values ---------------------------------------------------------*/ + +/** ALIGN: Data alignment */ +#define ADC_CFGR1_ALIGN (1 << 5) + +/* EXTSEL[2:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 6 +#define ADC_CFGR1_EXTSEL_MASK (0xf << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + /****************************************************************************/ /* ADC_SMPRx ADC Sample Time Selection for Channels */ /** @defgroup adc_sample ADC Sample Time Selection values diff --git a/include/libopencm3/stm32/g0/adc.h b/include/libopencm3/stm32/g0/adc.h index b40e32b5..e2b65d35 100644 --- a/include/libopencm3/stm32/g0/adc.h +++ b/include/libopencm3/stm32/g0/adc.h @@ -121,6 +121,14 @@ /** @addtogroup adc_cfgr1 @{*/ +/** ALIGN: Data alignment */ +#define ADC_CFGR1_ALIGN (1 << 5) + +/* EXTSEL[2:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 6 +#define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + /** CHSELRMOD: Mode Selection of the ADC_CHSELR register */ #define ADC_CFGR1_CHSELRMOD (1 << 21) diff --git a/include/libopencm3/stm32/l0/adc.h b/include/libopencm3/stm32/l0/adc.h index 7fd99f38..102ada5e 100644 --- a/include/libopencm3/stm32/l0/adc.h +++ b/include/libopencm3/stm32/l0/adc.h @@ -57,6 +57,16 @@ #define ADC_CALFACT(adc) MMIO32((adc) + 0xB4) /* Register values */ +/* ADC_CFGR1 Values ---------------------------------------------------------*/ + +/** ALIGN: Data alignment */ +#define ADC_CFGR1_ALIGN (1 << 5) + +/* EXTSEL[2:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 6 +#define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + /* ADC_CFGR2 Values ---------------------------------------------------------*/ #define ADC_CFGR2_CKMODE_SHIFT 30 diff --git a/include/libopencm3/stm32/l4/adc.h b/include/libopencm3/stm32/l4/adc.h index e01852fd..572c6f31 100644 --- a/include/libopencm3/stm32/l4/adc.h +++ b/include/libopencm3/stm32/l4/adc.h @@ -62,6 +62,16 @@ /* ADVREGEN: Voltage regulator enable bit */ #define ADC_CR_ADVREGEN (1 << 28) +/* ADC_CFGR1 Values ---------------------------------------------------------*/ + +/** ALIGN: Data alignment */ +#define ADC_CFGR1_ALIGN (1 << 5) + +/* EXTSEL[2:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 6 +#define ADC_CFGR1_EXTSEL_MASK (0xf << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + /****************************************************************************/ /* ADC_SMPRx ADC Sample Time Selection for Channels */ From cdf235ca0c4d43bfe2fc4c8b7c563cd113230b4f Mon Sep 17 00:00:00 2001 From: Sam Kirkham Date: Wed, 29 Jul 2020 12:34:40 +0100 Subject: [PATCH 048/206] stm32g4: Add support for ADC Co-authored-by: Ben Brewer --- include/libopencm3/stm32/adc.h | 2 + include/libopencm3/stm32/g4/adc.h | 613 ++++++++++++++++++++ include/libopencm3/stm32/g4/memorymap.h | 6 +- lib/stm32/g4/Makefile | 1 + lib/stm32/g4/adc.c | 720 ++++++++++++++++++++++++ 5 files changed, 1339 insertions(+), 3 deletions(-) create mode 100644 include/libopencm3/stm32/g4/adc.h create mode 100644 lib/stm32/g4/adc.c diff --git a/include/libopencm3/stm32/adc.h b/include/libopencm3/stm32/adc.h index fed4a3b7..3f2de8a7 100644 --- a/include/libopencm3/stm32/adc.h +++ b/include/libopencm3/stm32/adc.h @@ -38,6 +38,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined." #endif diff --git a/include/libopencm3/stm32/g4/adc.h b/include/libopencm3/stm32/g4/adc.h new file mode 100644 index 00000000..b9a0cd25 --- /dev/null +++ b/include/libopencm3/stm32/g4/adc.h @@ -0,0 +1,613 @@ +/** @defgroup adc_defines ADC Defines + * + * @brief Defined Constants and Types for the STM32G4xx Analog to Digital + * converter + * + * @ingroup STM32G4xx_defines + * + * @version 1.0.0 + * + * @date 10 Jul 2020 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_ADC_H +#define LIBOPENCM3_ADC_H + +#include +#include + +/**@{*/ + +/** @defgroup adc_reg_base ADC register base addresses +@ingroup STM32xx_adc_defines +@{*/ +#define ADC1 ADC1_BASE +#define ADC2 ADC2_BASE +#define ADC3 ADC3_BASE +#define ADC4 ADC4_BASE +#define ADC5 ADC5_BASE +/**@}*/ + + +/*----------- ADC registers -------------------------------------- */ +/** ADC_GCOMP Gain compensation Register */ +#define ADC_GCOMP(adc) MMIO32((adc) + 0xC0) + +/*------- ADC_CR values ---------*/ + +/* DEEPPWD: Deep power down */ +#define ADC_CR_DEEPPWD (1 << 29) + +/** ADVREGEN: ADC voltage regulator enable bit */ +#define ADC_CR_ADVREGEN (1 << 28) + +/*------- ADC_CFGR1 values ---------*/ + +/** ALIGN: Data alignment */ +#define ADC_CFGR1_ALIGN (1 << 15) + +/** EXTSEL[4:0]: External trigger selection for regular group */ +#define ADC_CFGR1_EXTSEL_SHIFT 5 +#define ADC_CFGR1_EXTSEL_MASK (0x1f << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) + +/** CFGR1: ADC configuration register */ +#define ADC12_CFGR1_EXTSEL_TIM1_CC1 ADC_CFGR1_EXTSEL_VAL(0) +#define ADC12_CFGR1_EXTSEL_TIM1_CC2 ADC_CFGR1_EXTSEL_VAL(1) +#define ADC12_CFGR1_EXTSEL_TIM1_CC3 ADC_CFGR1_EXTSEL_VAL(2) +#define ADC12_CFGR1_EXTSEL_TIM2_CC2 ADC_CFGR1_EXTSEL_VAL(3) +#define ADC12_CFGR1_EXTSEL_TIM3_TRGO ADC_CFGR1_EXTSEL_VAL(4) +#define ADC12_CFGR1_EXTSEL_TIM4_CC4 ADC_CFGR1_EXTSEL_VAL(5) +#define ADC12_CFGR1_EXTSEL_EXTI11 ADC_CFGR1_EXTSEL_VAL(6) +#define ADC12_CFGR1_EXTSEL_TIM8_TRGO ADC_CFGR1_EXTSEL_VAL(7) +#define ADC12_CFGR1_EXTSEL_TIM8_TRGO2 ADC_CFGR1_EXTSEL_VAL(8) +#define ADC12_CFGR1_EXTSEL_TIM1_TRGO ADC_CFGR1_EXTSEL_VAL(9) +#define ADC12_CFGR1_EXTSEL_TIM1_TRGO2 ADC_CFGR1_EXTSEL_VAL(10) +#define ADC12_CFGR1_EXTSEL_TIM2_TRGO ADC_CFGR1_EXTSEL_VAL(11) +#define ADC12_CFGR1_EXTSEL_TIM4_TRGO ADC_CFGR1_EXTSEL_VAL(12) +#define ADC12_CFGR1_EXTSEL_TIM6_TRGO ADC_CFGR1_EXTSEL_VAL(13) +#define ADC12_CFGR1_EXTSEL_TIM15_TRGO ADC_CFGR1_EXTSEL_VAL(14) +#define ADC12_CFGR1_EXTSEL_TIM3_CC4 ADC_CFGR1_EXTSEL_VAL(15) +#define ADC12_CFGR1_EXTSEL_TIM20_TRGO ADC_CFGR1_EXTSEL_VAL(16) +#define ADC12_CFGR1_EXTSEL_TIM20_TRGO2 ADC_CFGR1_EXTSEL_VAL(17) +#define ADC12_CFGR1_EXTSEL_TIM20_CC1 ADC_CFGR1_EXTSEL_VAL(18) +#define ADC12_CFGR1_EXTSEL_TIM20_CC2 ADC_CFGR1_EXTSEL_VAL(19) +#define ADC12_CFGR1_EXTSEL_TIM20_CC3 ADC_CFGR1_EXTSEL_VAL(20) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG1 ADC_CFGR1_EXTSEL_VAL(21) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG3 ADC_CFGR1_EXTSEL_VAL(22) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG5 ADC_CFGR1_EXTSEL_VAL(23) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG6 ADC_CFGR1_EXTSEL_VAL(24) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG7 ADC_CFGR1_EXTSEL_VAL(25) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG8 ADC_CFGR1_EXTSEL_VAL(26) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG9 ADC_CFGR1_EXTSEL_VAL(27) +#define ADC12_CFGR1_EXTSEL_HRTIM_ADC_TRG10 ADC_CFGR1_EXTSEL_VAL(28) +#define ADC12_CFGR1_EXTSEL_LPTIMOUT ADC_CFGR1_EXTSEL_VAL(29) +#define ADC12_CFGR1_EXTSEL_TIM7_TRGO ADC_CFGR1_EXTSEL_VAL(30) + +#define ADC345_CFGR1_EXTSEL_TIM3_CC1 ADC_CFGR1_EXTSEL_VAL(0) +#define ADC345_CFGR1_EXTSEL_TIM2_CC3 ADC_CFGR1_EXTSEL_VAL(1) +#define ADC345_CFGR1_EXTSEL_TIM1_CC3 ADC_CFGR1_EXTSEL_VAL(2) +#define ADC345_CFGR1_EXTSEL_TIM8_CC1 ADC_CFGR1_EXTSEL_VAL(3) +#define ADC345_CFGR1_EXTSEL_TIM3_TRGO ADC_CFGR1_EXTSEL_VAL(4) +#define ADC345_CFGR1_EXTSEL_EXTI2 ADC_CFGR1_EXTSEL_VAL(5) +#define ADC345_CFGR1_EXTSEL_TIM4_CC1 ADC_CFGR1_EXTSEL_VAL(6) +#define ADC345_CFGR1_EXTSEL_TIM8_TRGO ADC_CFGR1_EXTSEL_VAL(7) +#define ADC345_CFGR1_EXTSEL_TIM8_TRGO2 ADC_CFGR1_EXTSEL_VAL(8) +#define ADC345_CFGR1_EXTSEL_TIM1_TRGO ADC_CFGR1_EXTSEL_VAL(9) +#define ADC345_CFGR1_EXTSEL_TIM1_TRGO2 ADC_CFGR1_EXTSEL_VAL(10) +#define ADC345_CFGR1_EXTSEL_TIM2_TRGO ADC_CFGR1_EXTSEL_VAL(11) +#define ADC345_CFGR1_EXTSEL_TIM4_TRGO ADC_CFGR1_EXTSEL_VAL(12) +#define ADC345_CFGR1_EXTSEL_TIM6_TRGO ADC_CFGR1_EXTSEL_VAL(13) +#define ADC345_CFGR1_EXTSEL_TIM15_TRGO ADC_CFGR1_EXTSEL_VAL(14) +#define ADC345_CFGR1_EXTSEL_TIM2_CC1 ADC_CFGR1_EXTSEL_VAL(15) +#define ADC345_CFGR1_EXTSEL_TIM20_TRGO ADC_CFGR1_EXTSEL_VAL(16) +#define ADC345_CFGR1_EXTSEL_TIM20_TRGO2 ADC_CFGR1_EXTSEL_VAL(17) +#define ADC345_CFGR1_EXTSEL_TIM20_CC1 ADC_CFGR1_EXTSEL_VAL(18) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG2 ADC_CFGR1_EXTSEL_VAL(19) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG4 ADC_CFGR1_EXTSEL_VAL(20) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG1 ADC_CFGR1_EXTSEL_VAL(21) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG3 ADC_CFGR1_EXTSEL_VAL(22) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG5 ADC_CFGR1_EXTSEL_VAL(23) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG6 ADC_CFGR1_EXTSEL_VAL(24) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG7 ADC_CFGR1_EXTSEL_VAL(25) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG8 ADC_CFGR1_EXTSEL_VAL(26) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG9 ADC_CFGR1_EXTSEL_VAL(27) +#define ADC345_CFGR1_EXTSEL_HRTIM_ADC_TRG10 ADC_CFGR1_EXTSEL_VAL(28) +#define ADC345_CFGR1_EXTSEL_LPTIMOUT ADC_CFGR1_EXTSEL_VAL(29) +#define ADC345_CFGR1_EXTSEL_TIM7_TRGO ADC_CFGR1_EXTSEL_VAL(30) + +/*------- ADC_CFGR2 values ---------*/ + +/** ROVSE: Regular Oversampling Enable */ +#define ADC_CFGR2_ROVSE (1 << 0) + +/** JOVSE: Injected Oversampling Enable */ +#define ADC_CFGR2_JOVSE (1 << 1) + +/** OVSR[2:0]: Oversampling ratio */ +#define ADC_CFGR2_OVSR_SHIFT 2 +#define ADC_CFGR2_OVSR_MASK (0x7 << ADC_CFGR2_OVSR_SHIFT) +#define ADC_CFGR2_OVSR_VAL(x) ((x) << ADC_CFGR2_OVSR_SHIFT) + +#define ADC_CFGR2_OVSR_2x ADC_CFGR2_OVSR_VAL(0) +#define ADC_CFGR2_OVSR_4x ADC_CFGR2_OVSR_VAL(1) +#define ADC_CFGR2_OVSR_8x ADC_CFGR2_OVSR_VAL(2) +#define ADC_CFGR2_OVSR_16x ADC_CFGR2_OVSR_VAL(3) +#define ADC_CFGR2_OVSR_32x ADC_CFGR2_OVSR_VAL(4) +#define ADC_CFGR2_OVSR_64x ADC_CFGR2_OVSR_VAL(5) +#define ADC_CFGR2_OVSR_128x ADC_CFGR2_OVSR_VAL(6) +#define ADC_CFGR2_OVSR_256x ADC_CFGR2_OVSR_VAL(7) + +/** OVSS[3:0]: Oversampling shift */ +#define ADC_CFGR2_OVSS_SHIFT 5 +#define ADC_CFGR2_OVSS_MASK (0xf << ADC_CFGR2_OVSS_SHIFT) +#define ADC_CFGR2_OVSS_VAL(x) ((x) << ADC_CFGR2_OVSS_SHIFT) + +/** TROVS: Triggered Regular Oversampling */ +#define ADC_CFGR2_TROVS (1 << 9) + +/** ROVSM: Regular Oversampling mode */ +#define ADC_CFGR2_ROVSM (1 << 10) + +/** GCOMP: Gain compensation mode */ +#define ADC_CFGR2_GCOMP (1 << 16) + +/** SWTRIG: Software trigger bit for sampling time control trigger mode */ +#define ADC_CFGR2_SWTRIG (1 << 25) + +/** BULB: Bulb sampling mode */ +#define ADC_CFGR2_BULB (1 << 26) + +/** SMPTRIG: Sampling time control trigger mode */ +#define ADC_CFGR2_SMPTRIG (1 << 27) + +/****************************************************************************/ +/* ADC_SMPRx ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample ADC Sample Time Selection values +@ingroup adc_defines + +@{*/ +#define ADC_SMPR_SMP_2DOT5CYC 0x0 +#define ADC_SMPR_SMP_6DOT5CYC 0x1 +#define ADC_SMPR_SMP_12DOT5CYC 0x2 +#define ADC_SMPR_SMP_24DOT5CYC 0x3 +#define ADC_SMPR_SMP_47DOT5CYC 0x4 +#define ADC_SMPR_SMP_92DOT5CYC 0x5 +#define ADC_SMPR_SMP_247DOT5CYC 0x6 +#define ADC_SMPR_SMP_640DOT5CYC 0x7 + +#define ADC_SMPR1_SMP_PLUSONE (1 << 31) + +/**@}*/ + +/* SMPx[2:0]: Channel x sampling time selection */ + +/*------- ADC_T2 values ---------*/ + +/* Bits 23:16 HT2[7:0]: Analog watchdog 2 higher threshold */ + +/* Bit 7:0 LT2[7:0]: Analog watchdog 2 lower threshold */ + + +/*------- ADC_T3 values ---------*/ + +/* Bits 23:16 HT3[7:0]: Analog watchdog 3 higher threshold */ + +/* Bit 7:0 LT3[7:0]: Analog watchdog 3 lower threshold */ + + +/*------- ADC_DR values ---------*/ + +/* Bits 15:0 RDATA[15:0]: Regular Data converted */ + + +/*------- ADC_JSQR values ---------*/ + +#define ADC_JSQR_JL_LSB 0 +#define ADC_JSQR_JL_SHIFT 0 +#define ADC_JSQR_JSQ4_LSB 27 +#define ADC_JSQR_JSQ3_LSB 21 +#define ADC_JSQR_JSQ2_LSB 15 +#define ADC_JSQR_JSQ1_LSB 9 + +#define ADC_JSQR_JSQ_VAL(n, val) ((val) << (((n) - 1) * 6 + 8)) +#define ADC_JSQR_JL_VAL(val) (((val) - 1) << ADC_JSQR_JL_SHIFT) + +/* Bits 31:27 JSQ4[4:0]: 4th conversion in the injected sequence */ + +/* Bits 25:21 JSQ3[4:0]: 3rd conversion in the injected sequence */ + +/* Bits 19:15 JSQ2[4:0]: 2nd conversion in the injected sequence */ + +/* Bits 13:9 JSQ1[4:0]: 1st conversion in the injected sequence */ + +/* + * JEXTEN[1:0]: External Trigger Enable and Polarity Selection for injected + * channels + */ +#define ADC_JSQR_JEXTEN_DISABLED (0x0 << 7) +#define ADC_JSQR_JEXTEN_RISING_EDGE (0x1 << 7) +#define ADC_JSQR_JEXTEN_FALLING_EDGE (0x2 << 7) +#define ADC_JSQR_JEXTEN_BOTH_EDGES (0x3 << 7) + +#define ADC_JSQR_JEXTEN_MASK (0x3 << 7) + +/* JEXTSEL[3:0]: External Trigger Selection for injected group */ +#define ADC_JSQR_JEXTSEL_SHIFT 2 + +#define ADC12_JSQR_JEXTSEL_TIM1_TRGO (0 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM1_CC4 (1 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM2_TRGO (2 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM2_CC1 (3 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM3_CC4 (4 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM4_TRGO (5 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_EXTI15 (6 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM8_CC4 (7 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM1_TRGO2 (8 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM8_TRGO (9 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM8_TRGO2 (10 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM3_CC3 (11 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM3_TRGO (12 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM3_CC1 (13 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM6_TRGO (14 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM15_TRGO (15 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM20_TRGO (16 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM20_TRGO2 (17 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM20_CC4 (18 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG2 (19 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG4 (20 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG5 (21 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG6 (22 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG7 (23 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG8 (24 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG9 (25 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_HRTIM_ADC_TRG10 (26 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM16_CC1 (27 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_LPTIMOUT (29 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC12_JSQR_JEXTSEL_TIM7_TRGO (30 << ADC_JSQR_JEXTSEL_SHIFT) + +#define ADC345_JSQR_JEXTSEL_TIM1_TRGO (0 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM1_CC4 (1 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM2_TRGO (2 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM8_CC2 (3 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM4_CC3 (4 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM4_TRGO (5 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM4_CC4 (6 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM8_CC4 (7 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM1_TRGO2 (8 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM8_TRGO (9 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM8_TRGO2 (10 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM1_CC3 (11 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM3_TRGO (12 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_EXTI3 (13 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM6_TRGO (14 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM15_TRGO (15 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM20_TRGO (16 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM20_TRGO2 (17 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM20_CC2 (18 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG2 (19 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG4 (20 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG5 (21 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG6 (22 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG7 (23 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG8 (24 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG9 (25 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG10 (26 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG1 (27 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_HRTIM_ADC_TRG3 (28 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_LPTIMOUT (29 << ADC_JSQR_JEXTSEL_SHIFT) +#define ADC345_JSQR_JEXTSEL_TIM7_TRGO (30 << ADC_JSQR_JEXTSEL_SHIFT) + +#define ADC_JSQR_JEXTSEL_MASK (0x1F << ADC_JSQR_JEXTSEL_SHIFT) + +/* JL[1:0]: Injected channel sequence length */ +#define ADC_JSQR_JL_1_CONVERSION (0x0 << 0) +#define ADC_JSQR_JL_2_CONVERSIONS (0x1 << 0) +#define ADC_JSQR_JL_3_CONVERSIONS (0x2 << 0) +#define ADC_JSQR_JL_4_CONVERSIONS (0x3 << 0) + +/*------- ADC_OFR1 values ---------*/ + +/* OFFSET1_EN: Offset 1 Enable */ +#define ADC_OFR1_OFFSET1_EN (1 << 31) + +/* Bits 30:26 OFFSET1_CH[4:0]: Channel selection for the Data offset 1 */ + +/* + * Bits 11:0 OFFSET1[11:0]: Data offset y for the channel programmed into bits + * OFFSET1_CH[4:0] + */ + + +/*------- ADC_OFR2 values ---------*/ + +/* OFFSET2_EN: Offset 2 Enable */ +#define ADC_OFR2_OFFSET2_EN (1 << 31) + +/* Bits 30:26 OFFSET2_CH[4:0]: Channel selection for the Data offset 2 */ + +/* + * Bits 11:0 OFFSET2[11:0]: Data offset y for the channel programmed into bits + * OFFSET2_CH[4:0] + */ + + +/*------- ADC_OFR3 values ---------*/ + +/* OFFSET3_EN: Offset 3 Enable */ +#define ADC_OFR3_OFFSET3_EN (1 << 31) + +/* Bits 30:26 OFFSET3_CH[4:0]: Channel selection for the Data offset 3 */ + +/* + * Bits 11:0 OFFSET3[11:0]: Data offset y for the channel programmed into bits + * OFFSET3_CH[4:0] + */ + + +/*------- ADC_OFR4 values ---------*/ + +/* OFFSET4_EN: Offset 4 Enable */ +#define ADC_OFR4_OFFSET4_EN (1 << 31) + +/* Bits 30:26 OFFSET4_CH[4:0]: Channel selection for the Data offset 4 */ + +/* + * Bits 11:0 OFFSET4[11:0]: Data offset y for the channel programmed into bits + * OFFSET4_CH[4:0] + */ + + +/*------- ADC_JDRy, y= 1..4 values -------*/ + +/* Bits 15:0 JDATA[15:0]: Injected data */ + + +/*------- ADC_AWD2CR values ---------*/ + +/* Bits 18:1 AWD2CH[18:1]: Analog watchdog 2 channel selection */ + + +/*------- ADC_AWD3CR values ---------*/ + +/* Bits 18:1 AWD3CH[18:1]: Analog watchdog 3 channel selection */ + +/*--------------- ADC_CSR values ------------------------*/ + +/* Bit 26 JQOVF_SLV: Injected Context Queue Overflow flag of the slave ADC */ +#define ADC_CSR_JQOVF_SLV (1 << 26) + +/* Bit 25 AWD3_SLV: Analog watchdog 3 flag of the slave ADC */ +#define ADC_CSR_AWD3_SLV (1 << 25) + +/* Bit 24 AWD2_SLV: Analog watchdog 2 flag of the slave ADC */ +#define ADC_CSR_AWD2_SLV (1 << 24) + +/* Bit 23 AWD1_SLV: Analog watchdog 1 flag of the slave ADC */ +#define ADC_CSR_AWD1_SLV (1 << 23) + +/* Bit 22 JEOS_SLV: End of injected sequence flag of the slave ADC */ +#define ADC_CSR_JEOS_SLV (1 << 22) + +/* Bit 21 JEOC_SLV: End of injected conversion flag of the slave ADC */ +#define ADC_CSR_JEOC_SLV (1 << 21) + +/* Bit 20 OVR_SLV: Overrun flag of the slave ADC */ +#define ADC_CSR_OVR_SLV (1 << 20) + +/* Bit 19 EOS_SLV: End of regular sequence flag of the slave ADC */ +#define ADC_CSR_EOS_SLV (1 << 19) + +/* Bit 18 EOC_SLV: End of regular conversion of the slave ADC */ +#define ADC_CSR_EOC_SLV (1 << 18) + +/* Bit 17 EOSMP_SLV: End of Sampling phase flag of the slave ADC */ +#define ADC_CSR_EOSMP_SLV (1 << 17) + +/* Bit 16 ADRDY_SLV: Slave ADC ready */ +#define ADC_CSR_ADRDY_SLV (1 << 16) + +/* Bit 10 JQOVF_MST: Injected Context Queue Overflow flag of the master ADC */ +#define ADC_CSR_JQOVF_MST (1 << 10) + +/* Bit 9 AWD3_MST: Analog watchdog 3 flag of the master ADC */ +#define ADC_CSR_AWD3_MST (1 << 9) + +/* Bit 8 AWD2_MST: Analog watchdog 2 flag of the master ADC */ +#define ADC_CSR_AWD2_MST (1 << 8) + +/* Bit 7 AWD1_MST: Analog watchdog 1 flag of the master ADC */ +#define ADC_CSR_AWD1_MST (1 << 7) + +/* Bit 6 JEOS_MST: End of injected sequence flag of the master ADC */ +#define ADC_CSR_JEOS_MST (1 << 6) + +/* Bit 5 JEOC_MST: End of injected conversion flag of the master ADC */ +#define ADC_CSR_JEOC_MST (1 << 5) + +/* Bit 4 OVR_MST: Overrun flag of the master ADC */ +#define ADC_CSR_OVR_MST (1 << 4) + +/* Bit 3 EOS_MST: End of regular sequence flag of the master ADC */ +#define ADC_CSR_EOS_MST (1 << 3) + +/* Bit 2 EOC_MST: End of regular conversion of the master ADC */ +#define ADC_CSR_EOC_MST (1 << 2) + +/* Bit 1 EOSMP_MST: End of Sampling phase flag of the master ADC */ +#define ADC_CSR_EOSMP_MST (1 << 1) + +/* Bit 0 ADRDY_MST: Master ADC ready */ +#define ADC_CSR_ADRDY_MST (1 << 0) + + +/*-------- ADC_CCR values ------------*/ + +/* Bits 21:18 PRESC[21:18]: ADC Prescaler */ +#define ADC_CCR_PRESC_MASK (0xf) +#define ADC_CCR_PRESC_SHIFT (18) +/** @defgroup adc_ccr_presc ADC clock prescaler + *@{*/ +#define ADC_CCR_PRESC_NODIV (0x0 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV1 (0x1 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV2 (0x2 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV6 (0x3 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV8 (0x4 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV10 (0x5 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV12 (0x6 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV16 (0x7 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV32 (0x8 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV64 (0x9 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV128 (0x10 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_DIV256 (0x11 << ADC_CCR_PRESC_SHIFT) +/**@}*/ + +/* CKMODE[1:0]: ADC clock mode */ +#define ADC_CCR_CKMODE_CKX (0x0 << 16) +#define ADC_CCR_CKMODE_DIV1 (0x1 << 16) +#define ADC_CCR_CKMODE_DIV2 (0x2 << 16) +#define ADC_CCR_CKMODE_DIV4 (0x3 << 16) + +#define ADC_CCR_CKMODE_MASK (0x3 << 16) + +/* MDMA[1:0]: Direct memory access mode for dual ADC mode */ +#define ADC_CCR_MDMA_DISABLE (0x0 << 14) +/*#define ADC_CCR_MDMA_RESERVED (0x1 << 14)*/ +#define ADC_CCR_MDMA_12_10_BIT (0x2 << 14) +#define ADC_CCR_MDMA_8_6_BIT (0x3 << 14) + +/* DMACFG: DMA configuration (for dual ADC mode) */ +#define ADC_CCR_DMACFG (1 << 13) + +/* DELAY: Delay between 2 sampling phases */ +#define ADC_CCR_DELAY_SHIFT 8 + +/* DUAL[4:0]: Dual ADC mode selection */ +/****************************************************************************/ +/** @defgroup adc_multi_mode ADC Multi mode selection +@ingroup adc_defines + +@{*/ + +/** All ADCs independent */ +#define ADC_CCR_DUAL_INDEPENDENT 0x0 + +/* Dual modes: (ADC1 master + ADC2 slave or ADC3 master + ADC4 slave) */ +/** + * Dual modes combined regular simultaneous + + * injected simultaneous mode. + */ +#define ADC_CCR_DUAL_REG_SIMUL_AND_INJECTED_SIMUL 0x1 +/** + * Dual mode Combined regular simultaneous + + * alternate trigger mode. + */ +#define ADC_CCR_DUAL_REG_SIMUL_AND_ALTERNATE_TRIG 0x2 +/** + * Dual mode Combined interleaved mode + + * injected simultaneous mode. + */ +#define ADC_CCR_DUAL_REG_INTERLEAVED_AND_INJECTED_SIMUL 0x3 + +/** Dual mode Injected simultaneous mode only. */ +#define ADC_CCR_DUAL_INJECTED_SIMUL 0x5 +/** Dual mode Regular simultaneous mode only. */ +#define ADC_CCR_DUAL_REGULAR_SIMUL 0x6 +/** Dual mode Interleaved mode only. */ +#define ADC_CCR_DUAL_INTERLEAVED 0x7 +/** Dual mode Alternate trigger mode only. */ +#define ADC_CCR_DUAL_ALTERNATE_TRIG 0x9 +/**@}*/ + +#define ADC_CCR_DUAL_MASK (0x1f) +#define ADC_CCR_DUAL_SHIFT 0 + + +/*---------------- ADC_CDR values -----------------*/ + +/* Bits 31:16 RDATA_SLV[15:0]: Regular data of the slave ADC */ + +/* Bits 15:0 RDATA_MST[15:0]: Regular data of the master ADC. */ + +/** @defgroup adc_channel ADC Channel Numbers + * @ingroup adc_defines + * + *@{*/ +#define ADC_CHANNEL_TEMP 16 +#define ADC_CHANNEL_VBAT 17 +#define ADC_CHANNEL_VREF 18 +/**@}*/ + +#define ADC_CHANNEL_COUNT 19 +#define ADC_CHANNEL_IS_FAST(x) ((x) <= 5) + + +BEGIN_DECLS + +void adc_enable_analog_watchdog_regular(uint32_t adc); +void adc_disable_analog_watchdog_regular(uint32_t adc); +void adc_enable_analog_watchdog_injected(uint32_t adc); +void adc_disable_analog_watchdog_injected(uint32_t adc); +void adc_enable_discontinuous_mode_regular(uint32_t adc, uint8_t length); +void adc_disable_discontinuous_mode_regular(uint32_t adc); +void adc_enable_discontinuous_mode_injected(uint32_t adc); +void adc_disable_discontinuous_mode_injected(uint32_t adc); +void adc_enable_automatic_injected_group_conversion(uint32_t adc); +void adc_disable_automatic_injected_group_conversion(uint32_t adc); +void adc_enable_analog_watchdog_on_all_channels(uint32_t adc); +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, + uint8_t channel); +void adc_enable_eoc_interrupt_injected(uint32_t adc); +void adc_disable_eoc_interrupt_injected(uint32_t adc); +void adc_enable_eos_interrupt_injected(uint32_t adc); +void adc_disable_eos_interrupt_injected(uint32_t adc); +void adc_enable_all_awd_interrupt(uint32_t adc); +void adc_disable_all_awd_interrupt(uint32_t adc); +void adc_enable_eos_interrupt(uint32_t adc); +void adc_disable_eos_interrupt(uint32_t adc); +void adc_start_conversion_injected(uint32_t adc); +void adc_disable_external_trigger_regular(uint32_t adc); +void adc_disable_external_trigger_injected(uint32_t adc); +void adc_set_watchdog_high_threshold(uint32_t adc, uint16_t threshold); +void adc_set_watchdog_low_threshold(uint32_t adc, uint16_t threshold); +void adc_set_injected_sequence(uint32_t adc, uint8_t length, uint8_t channel[]); +bool adc_eoc_injected(uint32_t adc); +bool adc_eos_injected(uint32_t adc); +uint32_t adc_read_injected(uint32_t adc, uint8_t reg); +void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset); +void adc_set_clk_source(uint32_t adc, uint32_t source); +void adc_set_clk_prescale(uint32_t adc, uint32_t prescaler); +void adc_set_multi_mode(uint32_t adc, uint32_t mode); +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity); +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity); +bool adc_awd(uint32_t adc); +void adc_enable_deeppwd(uint32_t adc); +void adc_disable_deeppwd(uint32_t adc); + +END_DECLS + +/**@}*/ + + +#endif + diff --git a/include/libopencm3/stm32/g4/memorymap.h b/include/libopencm3/stm32/g4/memorymap.h index 06a958c4..56a16617 100644 --- a/include/libopencm3/stm32/g4/memorymap.h +++ b/include/libopencm3/stm32/g4/memorymap.h @@ -105,10 +105,10 @@ /* AHB2 */ #define ADC1_BASE (PERIPH_BASE_AHB2 + 0x0000) -#define ADC2_BASE ADC1_BASE +#define ADC2_BASE (ADC1_BASE + 0x0100) #define ADC3_BASE (PERIPH_BASE_AHB2 + 0x0400) -#define ADC4_BASE ADC3_BASE -#define ADC5_BASE ADC3_BASE +#define ADC4_BASE (ADC3_BASE + 0x0100) +#define ADC5_BASE (ADC3_BASE + 0x0200) #define DAC1_BASE (PERIPH_BASE_AHB2 + 0x0800) #define DAC2_BASE (PERIPH_BASE_AHB2 + 0x0c00) #define DAC3_BASE (PERIPH_BASE_AHB2 + 0x1000) diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index d4771707..5c1bfdca 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -35,6 +35,7 @@ TGT_CFLAGS += $(DEBUG_FLAGS) TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs +OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += dma_common_l1f013.o OBJS += dmamux.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o diff --git a/lib/stm32/g4/adc.c b/lib/stm32/g4/adc.c new file mode 100644 index 00000000..4ce7ad72 --- /dev/null +++ b/lib/stm32/g4/adc.c @@ -0,0 +1,720 @@ +/** @defgroup adc_file ADC + * + * @ingroup STM32G4xx + * + * @brief libopencm3 STM32G4xx ADC + * + * @version 1.0.0 + * + * @date 10 Jul 2020 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#include + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @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(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_AWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @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_disable_analog_watchdog_regular(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_AWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @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(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_JAWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @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(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_JAWD1EN; +} + +/*---------------------------------------------------------------------------*/ +/** @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 + * whole group has been converted, the next trigger will restart conversion of + * the subgroup at the beginning of the whole group. + * + * @param[in] adc ADC block register address base @ref adc_reg_base + * @param[in] length Number of channels in the group @ref adc_cr1_discnum + */ +void adc_enable_discontinuous_mode_regular(uint32_t adc, uint8_t length) +{ + if ((length-1) > 7) { + return; + } + ADC_CFGR1(adc) |= ADC_CFGR1_DISCEN; + ADC_CFGR1(adc) |= ((length-1) << ADC_CFGR1_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(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_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(uint32_t adc) +{ + ADC_CFGR1(adc) |= ADC_CFGR1_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(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_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(uint32_t adc) +{ + adc_disable_external_trigger_injected(adc); + ADC_CFGR1(adc) |= ADC_CFGR1_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(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_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(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_AWD1SGL; +} + +/*---------------------------------------------------------------------------*/ +/** @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 numbe + * @ref adc_watchdog_channel + */ + +void adc_enable_analog_watchdog_on_selected_channel(uint32_t adc, + uint8_t channel) +{ + ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_AWD1CH) | + ADC_CFGR1_AWD1CH_VAL(channel); + + ADC_CFGR1(adc) |= ADC_CFGR1_AWD1EN | ADC_CFGR1_AWD1SGL; +} + + +/*---------------------------------------------------------------------------*/ +/** @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(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_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(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_JEOCIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Injected End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_eos_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_JEOSIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Injected End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_eos_interrupt_injected(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_JEOSIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_all_awd_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_AWD1IE; + ADC_IER(adc) |= ADC_IER_AWD2IE; + ADC_IER(adc) |= ADC_IER_AWD3IE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_all_awd_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_AWD1IE; + ADC_IER(adc) &= ~ADC_IER_AWD2IE; + ADC_IER(adc) &= ~ADC_IER_AWD3IE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Regular End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_enable_eos_interrupt(uint32_t adc) +{ + ADC_IER(adc) |= ADC_IER_EOSIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Regular End-Of-Sequence Interrupt + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_disable_eos_interrupt(uint32_t adc) +{ + ADC_IER(adc) &= ~ADC_IER_EOSIE; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Injected Channels + * + * This starts conversion on a set of defined injected channels. + * Depending on the configuration bits JEXTEN, a conversion will start + * immediately (software trigger configuration) or once an injected hardware + * trigger event occurs (hardware trigger configuration). + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ + +void adc_start_conversion_injected(uint32_t adc) +{ + /* Start conversion on injected channels. */ + ADC_CR(adc) |= ADC_CR_JADSTART; +} + + +/** ADC Set Analog Watchdog Upper Threshold. + * @param[in] adc ADC block register address base + * @ref adc_reg_base + * @param[in] threshold Upper threshold value + */ +void adc_set_watchdog_high_threshold(uint32_t adc, uint16_t threshold) +{ + uint32_t reg32 = 0; + uint32_t mask = 0xf000ffff; + + reg32 |= (threshold << 16); + reg32 &= ~mask; /* clear masked bits. */ + + ADC_TR1(adc) = (ADC_TR1(adc) & mask) | reg32; + ADC_TR2(adc) = (ADC_TR2(adc) & mask) | reg32; + ADC_TR3(adc) = (ADC_TR3(adc) & mask) | reg32; +} + +/** ADC Set Analog Watchdog Lower Threshold. + * @param[in] adc ADC block register address base + * @ref adc_reg_base + * @param[in] threshold Lower threshold value + */ +void adc_set_watchdog_low_threshold(uint32_t adc, uint16_t threshold) +{ + uint32_t reg32 = 0; + uint32_t mask = 0xfffff000; + reg32 = (uint32_t)threshold; + reg32 &= ~mask; /* clear masked bits. */ + + ADC_TR1(adc) = (ADC_TR1(adc) & mask) | reg32; + ADC_TR2(adc) = (ADC_TR2(adc) & mask) | reg32; + ADC_TR3(adc) = (ADC_TR3(adc) & mask) | reg32; +} + + +/*---------------------------------------------------------------------------*/ +/** @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(uint32_t adc, uint8_t length, uint8_t channel[]) +{ + uint32_t reg32 = 0; + uint8_t i = 0; + + /* Maximum sequence length is 4 channels. Minimum sequence is 1.*/ + if ((length - 1) > 3) { + return; + } + + for (i = 0; i < length; i++) { + reg32 |= ADC_JSQR_JSQ_VAL(4 - i, channel[length - i - 1]); + } + + reg32 |= ADC_JSQR_JL_VAL(length); + + ADC_JSQR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Conversion Flag for Injected Conversion + * + * This flag is set by hardware at the end of each injected conversion of a + * channel when a new data is available in the corresponding ADCx_JDRy register. + * + * @param[in] adc Unsigned int32. ADC block register address base + * @ref adc_reg_base + * @returns bool. End of conversion flag. + */ + +bool adc_eoc_injected(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_JEOC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Sequence Flag for Injected Conversions + * + * 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_eos_injected(uint32_t adc) +{ + return ADC_ISR(adc) & ADC_ISR_JEOS; +} + + +/*---------------------------------------------------------------------------*/ +/** @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. + */ + +uint32_t adc_read_injected(uint32_t adc, uint8_t 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(uint32_t adc, uint8_t reg, uint32_t offset) +{ + switch (reg) { + case 1: + ADC_OFR1(adc) |= ADC_OFR1_OFFSET1_EN; + ADC_OFR1(adc) |= offset; + break; + case 2: + ADC_OFR2(adc) |= ADC_OFR2_OFFSET2_EN; + ADC_OFR2(adc) |= offset; + break; + case 3: + ADC_OFR3(adc) |= ADC_OFR3_OFFSET3_EN; + ADC_OFR3(adc) |= offset; + break; + case 4: + ADC_OFR4(adc) |= ADC_OFR4_OFFSET4_EN; + ADC_OFR4(adc) |= offset; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Source + * + * The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. + * + * @param adc peripheral of choice @ref adc_reg_base + * @param[in] source Unsigned int32. Source value for ADC Clock @ref + * adc_ccr_adcpre + */ +void adc_set_clk_source(uint32_t adc, uint32_t source) +{ + uint32_t reg32 = ((ADC_CCR(adc) & ~ADC_CCR_CKMODE_MASK) | source); + ADC_CCR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Prescale + * + * The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. + * + * @param adc peripheral of choice @ref adc_reg_base + * @param[in] prescale Unsigned int32. Prescale value for ADC Clock @ref + * adc_ccr_adcpre + */ +void adc_set_clk_prescale(uint32_t adc, uint32_t ckmode) +{ + uint32_t reg32 = ((ADC_CCR(adc) & ~ADC_CCR_CKMODE_MASK) | ckmode); + ADC_CCR(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC set multi mode + * + * The multiple mode can uses these arrangement: + * - ADC1 as master and ADC2 as slave + * - ADC3 as master and ADC4 as slave + * + * This setting is applied to ADC master only (ADC1 or ADC3). + * + * The various modes possible are described in the reference manual. + * + * @param adc peripheral of choice @ref adc_reg_base + * @param[in] mode Multiple mode selection from @ref adc_multi_mode + */ +void adc_set_multi_mode(uint32_t adc, uint32_t mode) +{ + ADC_CCR(adc) &= ~(ADC_CCR_DUAL_MASK << ADC_CCR_DUAL_SHIFT); + ADC_CCR(adc) |= (mode << ADC_CCR_DUAL_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @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(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CFGR1(adc); + + reg32 &= ~(ADC_CFGR1_EXTSEL_MASK | ADC_CFGR1_EXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CFGR1(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(uint32_t adc) +{ + ADC_CFGR1(adc) &= ~ADC_CFGR1_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(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_JSQR(adc); + + reg32 &= ~(ADC_JSQR_JEXTSEL_MASK | ADC_JSQR_JEXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_JSQR(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(uint32_t adc) +{ + ADC_JSQR(adc) &= ~ADC_JSQR_JEXTEN_MASK; +} + + +/*---------------------------------------------------------------------------*/ +/** @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(uint32_t adc) +{ + return (ADC_ISR(adc) & ADC_ISR_AWD1) && + (ADC_ISR(adc) & ADC_ISR_AWD2) && + (ADC_ISR(adc) & ADC_ISR_AWD3); +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable Deep-Power-Down Mdoe + * + * Deep-power-down mode allows additional power saving by internally switching + * off to reduce leakage currents. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ +void adc_enable_deeppwd(uint32_t adc) +{ + ADC_CR(adc) |= ADC_CR_DEEPPWD; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable Deep-Power-Down Mdoe + * + * Deep-power-down mode allows additional power saving by internally switching + * off to reduce leakage currents. + * + * @param[in] adc Unsigned int32. ADC block register address base @ref + * adc_reg_base + */ +void adc_disable_deeppwd(uint32_t adc) +{ + ADC_CR(adc) &= ~ADC_CR_DEEPPWD; +} + + +/** + * Enable the ADC Voltage regulator + * Before any use of the ADC, the ADC Voltage regulator must be enabled. + * You must wait up to 10uSecs afterwards before trying anything else. + * @param[in] adc ADC block register address base + * @sa adc_disable_regulator + */ +void adc_enable_regulator(uint32_t adc) +{ + ADC_CR(adc) |= ADC_CR_ADVREGEN; +} + +/** + * Disable the ADC Voltage regulator + * You can disable the adc vreg when not in use to save power + * @param[in] adc ADC block register address base + * @sa adc_enable_regulator + */ +void adc_disable_regulator(uint32_t adc) +{ + ADC_CR(adc) &= ~ADC_CR_ADVREGEN; +} + +/**@}*/ + + From 82b4626ae3003f5d18cc7b36c8e0e0b3d53ccaa0 Mon Sep 17 00:00:00 2001 From: Sam Kirkham Date: Wed, 29 Jul 2020 12:39:49 +0100 Subject: [PATCH 049/206] stm32g4: Add support for USB Co-authored-by: Ben Brewer --- include/libopencm3/stm32/g4/st_usbfs.h | 27 ++++++++++++++++++++++++++ include/libopencm3/stm32/st_usbfs.h | 2 ++ lib/stm32/g4/Makefile | 4 ++++ 3 files changed, 33 insertions(+) create mode 100644 include/libopencm3/stm32/g4/st_usbfs.h diff --git a/include/libopencm3/stm32/g4/st_usbfs.h b/include/libopencm3/stm32/g4/st_usbfs.h new file mode 100644 index 00000000..7b65d2b8 --- /dev/null +++ b/include/libopencm3/stm32/g4/st_usbfs.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY ! + * Use top-level + */ + +#ifndef LIBOPENCM3_ST_USBFS_H +# error Do not include directly ! +#else + +#include + +#endif diff --git a/include/libopencm3/stm32/st_usbfs.h b/include/libopencm3/stm32/st_usbfs.h index 08f5d247..9f0cb5e0 100644 --- a/include/libopencm3/stm32/st_usbfs.h +++ b/include/libopencm3/stm32/st_usbfs.h @@ -35,6 +35,8 @@ # include #elif defined(STM32L4) # include +#elif defined(STM32G4) +# include #else # error "STM32 family not defined or not supported." #endif diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 5c1bfdca..9b59fbaf 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -44,6 +44,10 @@ OBJS += pwr.o OBJS += rcc.o rcc_common_all.o OBJS += timer_common_all.o timer_common_f0234.o +OBJS += usb.o usb_control.o usb_standard.o usb_msc.o +OBJS += usb_hid.o +OBJS += st_usbfs_core.o st_usbfs_v2.o + VPATH += ../../usb:../:../../cm3:../common VPATH += ../../ethernet From 98855377c63beda2119aeabf55ef3023c2a676d0 Mon Sep 17 00:00:00 2001 From: Ben Brewer Date: Mon, 3 Aug 2020 14:25:45 +0100 Subject: [PATCH 050/206] stm32g4: Enable CRS --- include/libopencm3/stm32/crs.h | 2 ++ lib/stm32/g4/Makefile | 1 + 2 files changed, 3 insertions(+) diff --git a/include/libopencm3/stm32/crs.h b/include/libopencm3/stm32/crs.h index 69858bc2..a41cfbb1 100644 --- a/include/libopencm3/stm32/crs.h +++ b/include/libopencm3/stm32/crs.h @@ -26,6 +26,8 @@ # include #elif defined(STM32L4) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined or not supported for this peripheral" #endif diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 9b59fbaf..f970ba8a 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -36,6 +36,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o +OBJS += crs_common_all.o OBJS += dma_common_l1f013.o OBJS += dmamux.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o From f82053000c99ccf9824692d2ded41eb7a4e7da07 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 1 Dec 2020 23:13:38 +0000 Subject: [PATCH 051/206] stm32: crs: fix doxygen We need per device header includes to make the per target documentation generation work properly. The dispatch headers are to dispatch to the _target_ not directly to the final implementation, remember, the final required headers for each may be multiple files, plus extra definitions! --- include/libopencm3/stm32/common/crs_common_all.h | 8 +------- include/libopencm3/stm32/crs.h | 8 ++++---- include/libopencm3/stm32/f0/crs.h | 12 ++++++++++++ include/libopencm3/stm32/g4/crs.h | 12 ++++++++++++ include/libopencm3/stm32/l0/crs.h | 12 ++++++++++++ include/libopencm3/stm32/l4/crs.h | 12 ++++++++++++ lib/stm32/common/crs_common_all.c | 10 ++++++---- 7 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 include/libopencm3/stm32/f0/crs.h create mode 100644 include/libopencm3/stm32/g4/crs.h create mode 100644 include/libopencm3/stm32/l0/crs.h create mode 100644 include/libopencm3/stm32/l4/crs.h diff --git a/include/libopencm3/stm32/common/crs_common_all.h b/include/libopencm3/stm32/common/crs_common_all.h index 2ce29f36..cdd70a4d 100644 --- a/include/libopencm3/stm32/common/crs_common_all.h +++ b/include/libopencm3/stm32/common/crs_common_all.h @@ -1,10 +1,4 @@ -/** @defgroup CRS_defines CRS Defines - * - * @brief STM32 Clock Recovery System: Defined Constants and Types - * - * @ingroup STM32_defines - * - * @version 1.0.0 +/** @addtogroup crs_defines * * @date 5 Feb 2014 * diff --git a/include/libopencm3/stm32/crs.h b/include/libopencm3/stm32/crs.h index a41cfbb1..6a6cbd28 100644 --- a/include/libopencm3/stm32/crs.h +++ b/include/libopencm3/stm32/crs.h @@ -21,13 +21,13 @@ #include #if defined(STM32F0) -# include +# include #elif defined(STM32L0) -# include +# include #elif defined(STM32L4) -# include +# include #elif defined(STM32G4) -# include +# include #else # error "stm32 family not defined or not supported for this peripheral" #endif diff --git a/include/libopencm3/stm32/f0/crs.h b/include/libopencm3/stm32/f0/crs.h new file mode 100644 index 00000000..4e6e2592 --- /dev/null +++ b/include/libopencm3/stm32/f0/crs.h @@ -0,0 +1,12 @@ +/** @defgroup crs_defines CRS Defines + * + * @brief Defined Constants and Types for the Clock Recovery System. + * + * @ingroup STM32F0xx_defines + * + *LGPL License Terms @ref lgpl_license + */ + +#pragma once + +#include diff --git a/include/libopencm3/stm32/g4/crs.h b/include/libopencm3/stm32/g4/crs.h new file mode 100644 index 00000000..4a3ab10d --- /dev/null +++ b/include/libopencm3/stm32/g4/crs.h @@ -0,0 +1,12 @@ +/** @defgroup crs_defines CRS Defines + * + * @brief Defined Constants and Types for the Clock Recovery System. + * + * @ingroup STM32G4xx_defines + * + *LGPL License Terms @ref lgpl_license + */ + +#pragma once + +#include diff --git a/include/libopencm3/stm32/l0/crs.h b/include/libopencm3/stm32/l0/crs.h new file mode 100644 index 00000000..5bfc4cfb --- /dev/null +++ b/include/libopencm3/stm32/l0/crs.h @@ -0,0 +1,12 @@ +/** @defgroup crs_defines CRS Defines + * + * @brief Defined Constants and Types for the Clock Recovery System. + * + * @ingroup STM32L0xx_defines + * + *LGPL License Terms @ref lgpl_license + */ + +#pragma once + +#include diff --git a/include/libopencm3/stm32/l4/crs.h b/include/libopencm3/stm32/l4/crs.h new file mode 100644 index 00000000..21b120f0 --- /dev/null +++ b/include/libopencm3/stm32/l4/crs.h @@ -0,0 +1,12 @@ +/** @defgroup crs_defines CRS Defines + * + * @brief Defined Constants and Types for the Clock Recovery System. + * + * @ingroup STM32L4xx_defines + * + *LGPL License Terms @ref lgpl_license + */ + +#pragma once + +#include diff --git a/lib/stm32/common/crs_common_all.c b/lib/stm32/common/crs_common_all.c index 2ebc9610..fce9ad4d 100644 --- a/lib/stm32/common/crs_common_all.c +++ b/lib/stm32/common/crs_common_all.c @@ -1,8 +1,7 @@ -/** @defgroup crs_file CRS +/** @addtogroup crs_file CRS peripheral API + * @ingroup peripheral_apis * - * @ingroup STM32xx - * - * @brief libopencm3 STM32 Clock Recovery Subsystem + * @brief (USB) STM32 Clock Recovery Subsystem * * @version 1.0.0 * @@ -27,6 +26,8 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ +/**@{*/ + #include #include @@ -46,3 +47,4 @@ void crs_autotrim_usb_enable(void) CRS_CR |= CRS_CR_CEN; } +/**@}*/ \ No newline at end of file From 382dde5a6dba9bc9dbb2240682193872d8c4ad5c Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 1 Dec 2020 23:37:26 +0000 Subject: [PATCH 052/206] stm32f7/g4: usb: enable all classes --- lib/stm32/f7/Makefile | 9 +++++++-- lib/stm32/g4/Makefile | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/stm32/f7/Makefile b/lib/stm32/f7/Makefile index fc7c092e..6fc8c1f3 100644 --- a/lib/stm32/f7/Makefile +++ b/lib/stm32/f7/Makefile @@ -67,8 +67,13 @@ OBJS += usart_common_all.o usart_common_v2.o # Ethernet OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz80x1.o -OBJS += usb.o usb_standard.o usb_control.o usb_dwc_common.o \ - usb_f107.o usb_f207.o usb_msc.o +OBJS += usb.o usb_standard.o usb_control.o +OBJS += usb_audio.o +OBJS += usb_cdc.o +OBJS += usb_hid.o +OBJS += usb_midi.o +OBJS += usb_msc.o +OBJS += usb_dwc_common.o usb_f107.o usb_f207.o VPATH += ../../usb:../:../../cm3:../common VPATH += ../../ethernet diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index f970ba8a..c5e4f594 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -45,8 +45,12 @@ OBJS += pwr.o OBJS += rcc.o rcc_common_all.o OBJS += timer_common_all.o timer_common_f0234.o -OBJS += usb.o usb_control.o usb_standard.o usb_msc.o +OBJS += usb.o usb_control.o usb_standard.o +OBJS += usb_audio.o +OBJS += usb_cdc.o OBJS += usb_hid.o +OBJS += usb_midi.o +OBJS += usb_msc.o OBJS += st_usbfs_core.o st_usbfs_v2.o VPATH += ../../usb:../:../../cm3:../common From 8435287300e5ca9af9f889c529e7b1fa019c42fb Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 2 Dec 2020 00:04:44 +0000 Subject: [PATCH 053/206] stm32: dma: doxygen fixups Use a single @defgroup for the "root" of a common heirarchy, and only addtogroup for additions. This prevents an alphabetically "first" entry from being used as the documentation for the entire group. --- lib/stm32/common/dma_common_csel.c | 5 +---- lib/stm32/common/dma_common_f24.c | 3 ++- lib/stm32/common/dma_common_l1f013.c | 3 ++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/stm32/common/dma_common_csel.c b/lib/stm32/common/dma_common_csel.c index 4cf1fca9..0dbce57b 100644 --- a/lib/stm32/common/dma_common_csel.c +++ b/lib/stm32/common/dma_common_csel.c @@ -1,7 +1,4 @@ -/** @addtogroup dma_file DMA peripheral API -@ingroup peripheral_apis - -LGPL License Terms @ref lgpl_license +/** @addtogroup dma_file */ /* * This file is part of the libopencm3 project. diff --git a/lib/stm32/common/dma_common_f24.c b/lib/stm32/common/dma_common_f24.c index 2c61b548..ac583316 100644 --- a/lib/stm32/common/dma_common_f24.c +++ b/lib/stm32/common/dma_common_f24.c @@ -1,5 +1,6 @@ -/** @addtogroup dma_file DMA peripheral API +/** @defgroup dma_file DMA peripheral API @ingroup peripheral_apis +@brief DMA library for the multi stream controller found in f2/f4/f7 parts. @author @htmlonly © @endhtmlonly 2012 Ken Sarkies diff --git a/lib/stm32/common/dma_common_l1f013.c b/lib/stm32/common/dma_common_l1f013.c index 2f9190a4..439d2bfa 100644 --- a/lib/stm32/common/dma_common_l1f013.c +++ b/lib/stm32/common/dma_common_l1f013.c @@ -1,5 +1,6 @@ -/** @addtogroup dma_file DMA peripheral API +/** @defgroup dma_file DMA peripheral API @ingroup peripheral_apis +@brief DMA library for the multi channel controller found in F0/1/3 & L/G parts. @author @htmlonly © @endhtmlonly 2010 Thomas Otto From e923a6fe6a40cc7af692f828448f91c4100686bb Mon Sep 17 00:00:00 2001 From: Ben Brewer Date: Tue, 18 Aug 2020 14:50:15 +0100 Subject: [PATCH 054/206] stm32g4: Add support for OPAMP Move implementations into common and split into v1 and v2. --- .../stm32/common/opamp_common_all.h | 99 ++++++++++++++++ .../libopencm3/stm32/common/opamp_common_v1.h | 86 ++++++++++++++ .../libopencm3/stm32/common/opamp_common_v2.h | 111 ++++++++++++++++++ include/libopencm3/stm32/f3/opamp.h | 92 +-------------- include/libopencm3/stm32/g4/opamp.h | 70 +++++++++++ include/libopencm3/stm32/opamp.h | 2 + .../{f3/opamp.c => common/opamp_common_all.c} | 52 +------- lib/stm32/common/opamp_common_v1.c | 56 +++++++++ lib/stm32/common/opamp_common_v2.c | 52 ++++++++ lib/stm32/f3/Makefile | 2 +- lib/stm32/g4/Makefile | 1 + 11 files changed, 484 insertions(+), 139 deletions(-) create mode 100644 include/libopencm3/stm32/common/opamp_common_all.h create mode 100644 include/libopencm3/stm32/common/opamp_common_v1.h create mode 100644 include/libopencm3/stm32/common/opamp_common_v2.h create mode 100644 include/libopencm3/stm32/g4/opamp.h rename lib/stm32/{f3/opamp.c => common/opamp_common_all.c} (75%) create mode 100644 lib/stm32/common/opamp_common_v1.c create mode 100644 lib/stm32/common/opamp_common_v2.c diff --git a/include/libopencm3/stm32/common/opamp_common_all.h b/include/libopencm3/stm32/common/opamp_common_all.h new file mode 100644 index 00000000..eb6d6f34 --- /dev/null +++ b/include/libopencm3/stm32/common/opamp_common_all.h @@ -0,0 +1,99 @@ +/** @addtogroup opamp_defines + * + * @date 10 Dec 2020 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @cond */ +#if defined(LIBOPENCM3_OPAMP_H) +/** @endcond */ +#ifndef LIBOPENCM3_OPAMP_COMMON_ALL_H +#define LIBOPENCM3_OPAMP_COMMON_ALL_H +/**@{*/ + +/* OpAmp registers */ + +/* Control and status register (OPAMPx_CSR) */ +#define OPAMP_CSR(opamp_base) MMIO32((opamp_base) + 0x00) + +/* OPAMPx_CSR values */ + +#define OPAMP_CSR_LOCK (0x1 << 31) + +#define OPAMP_CSR_TSTREF (0x1 << 29) + +#define OPAMP_CSR_TRIMOFFSETN_MASK (0x1f) +#define OPAMP_CSR_TRIMOFFSETN_SHIFT (24) + +#define OPAMP_CSR_TRIMOFFSETP_MASK (0x1f) +#define OPAMP_CSR_TRIMOFFSETP_SHIFT (19) + +#define OPAMP_CSR_CALSEL_MASK (0x3) +#define OPAMP_CSR_CALSEL_SHIFT (12) +#define OPAMP_CSR_CALSEL_3P3_PERCENT (0x0) +#define OPAMP_CSR_CALSEL_10_PERCENT (0x1) +#define OPAMP_CSR_CALSEL_50_PERCENT (0x2) +#define OPAMP_CSR_CALSEL_90_PERCENT (0x3) + +#define OPAMP_CSR_CALON (0x1 << 11) + +#define OPAMP_CSR_VM_SEL_MASK (0x3) +#define OPAMP_CSR_VM_SEL_SHIFT (5) + +#define OPAMP_CSR_VP_SEL_MASK (0x3) +#define OPAMP_CSR_VP_SEL_SHIFT (2) + +#define OPAMP_CSR_FORCE_VP (0x1 << 1) +#define OPAMP_CSR_EN (0x1 << 0) + + +BEGIN_DECLS + +void opamp_enable(uint32_t base); +void opamp_disable(uint32_t base); +void opamp_lock(uint32_t base); + +void opamp_set_calsel(uint32_t base, uint32_t calsel); +void opamp_tstref_enable(uint32_t base); +void opamp_tstref_disable(uint32_t base); +void opamp_force_vp_enable(uint32_t base); +void opamp_force_vp_disable(uint32_t base); +void opamp_cal_enable(uint32_t base); +void opamp_cal_disable(uint32_t base); + +void opamp_trimoffsetn_set(uint32_t base, uint32_t trim); +void opamp_trimoffsetp_set(uint32_t base, uint32_t trim); +void opamp_user_trim_enable(uint32_t base); +void opamp_user_trim_disable(uint32_t base); + +void opamp_pga_gain_select(uint32_t base, uint32_t gain); + +void opamp_vp_select(uint32_t base, uint32_t vp); +void opamp_vm_select(uint32_t base, uint32_t vm); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#warning "opamp_common_all.h should not be included directly, only via opamp.h" +#endif +/** @endcond */ diff --git a/include/libopencm3/stm32/common/opamp_common_v1.h b/include/libopencm3/stm32/common/opamp_common_v1.h new file mode 100644 index 00000000..ee3bf267 --- /dev/null +++ b/include/libopencm3/stm32/common/opamp_common_v1.h @@ -0,0 +1,86 @@ +/** @addtogroup opamp_defines + * + * @date 10 Dec 2020 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @cond */ +#if defined(LIBOPENCM3_OPAMP_H) +/** @endcond */ +#ifndef LIBOPENCM3_OPAMP_COMMON_V1_H +#define LIBOPENCM3_OPAMP_COMMON_V1_H +/**@{*/ + +#include + +/* OPAMPx_CSR values */ + +#define OPAMP_CSR_OUTCAL_MASK (0x1) +#define OPAMP_CSR_OUTCAL_SHIFT (30) +#define OPAMP_CSR_OUTCAL_NON_LO_INV (0x0) +#define OPAMP_CSR_OUTCAL_NON_HI_INV (0x1) + +#define OPAMP_CSR_USER_TRIM (0x1 << 18) + +#define OPAMP_CSR_PGA_GAIN_MASK (0xf) +#define OPAMP_CSR_PGA_GAIN_SHIFT (14) +#define OPAMP_CSR_PGA_GAIN_2 (0x0) +#define OPAMP_CSR_PGA_GAIN_4 (0x1) +#define OPAMP_CSR_PGA_GAIN_8 (0x2) +#define OPAMP_CSR_PGA_GAIN_16 (0x3) +#define OPAMP_CSR_PGA_GAIN_2_MINUS_VM0 (0x8) +#define OPAMP_CSR_PGA_GAIN_4_MINUS_VM0 (0x9) +#define OPAMP_CSR_PGA_GAIN_8_MINUS_VM0 (0xa) +#define OPAMP_CSR_PGA_GAIN_16_MINUS_VM0 (0xb) +#define OPAMP_CSR_PGA_GAIN_2_MINUS_VM1 (0xc) +#define OPAMP_CSR_PGA_GAIN_4_MINUS_VM1 (0xd) +#define OPAMP_CSR_PGA_GAIN_8_MINUS_VM1 (0xe) +#define OPAMP_CSR_PGA_GAIN_16_MINUS_VM1 (0xf) + +#define OPAMP_CSR_VPS_SEL_MASK (0x3) +#define OPAMP_CSR_VPS_SEL_SHIFT (9) + +#define OPAMP_CSR_VMS_SEL_MASK (0x1) +#define OPAMP_CSR_VMS_SEL_SHIFT (8) + +#define OPAMP_CSR_TCM_EN (0x1 << 7) + +#define OPAMP_CSR_VM_SEL_PGA_MODE (0x2) +#define OPAMP_CSR_VM_SEL_FOLLOWER_MODE (0x3) + + +BEGIN_DECLS + +bool opamp_read_outcal(uint32_t base); + +void opamp_vps_select(uint32_t base, uint32_t vps); +void opamp_vms_select(uint32_t base, uint32_t vms); +void opamp_tcm_enable(uint32_t base); +void opamp_tcm_disable(uint32_t base); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#warning "opamp_common_v1.h should not be included directly, only via opamp.h" +#endif +/** @endcond */ diff --git a/include/libopencm3/stm32/common/opamp_common_v2.h b/include/libopencm3/stm32/common/opamp_common_v2.h new file mode 100644 index 00000000..c073fdd4 --- /dev/null +++ b/include/libopencm3/stm32/common/opamp_common_v2.h @@ -0,0 +1,111 @@ +/** @addtogroup opamp_defines + * + * @date 10 Dec 2020 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @cond */ +#if defined(LIBOPENCM3_OPAMP_H) +/** @endcond */ +#ifndef LIBOPENCM3_OPAMP_COMMON_V2_H +#define LIBOPENCM3_OPAMP_COMMON_V2_H +/**@{*/ + +#include + +/* OpAmp registers */ + +/* Timer controlled mode register (OPAMPx_TMCR) */ +#define OPAMP_TCMR(opamp_base) MMIO32((opamp_base) + 0x18) + +/* OPAMPx_CSR values */ + +#define OPAMP_CSR_CALOUT_MASK (0x1) +#define OPAMP_CSR_CALOUT_SHIFT (30) +#define OPAMP_CSR_CALOUT_UNSUCC (0x0) +#define OPAMP_CSR_CALOUT_SUCC (0x1) + +#define OPAMP_CSR_PGA_GAIN_MASK (0x1f) +#define OPAMP_CSR_PGA_GAIN_SHIFT (14) + +/* Non-inverting gain*/ +#define OPAMP_CSR_PGA_GAIN_2 (0x00) +#define OPAMP_CSR_PGA_GAIN_4 (0x01) +#define OPAMP_CSR_PGA_GAIN_8 (0x02) +#define OPAMP_CSR_PGA_GAIN_16 (0x03) +#define OPAMP_CSR_PGA_GAIN_32 (0x04) +#define OPAMP_CSR_PGA_GAIN_64 (0x05) +/* Inverting gain -n/non-inverting gain y with VINM0 pin for input bias */ +#define OPAMP_CSR_PGA_INV_GAIN_MINUS_1_GAIN_2_VM0 (0x08) +#define OPAMP_CSR_PGA_INV_GAIN_MINUS_3_GAIN_4_VM0 (0x09) +#define OPAMP_CSR_PGA_INV_GAIN_MINUS_7_GAIN_8_VM0 (0x0A) +#define OPAMP_CSR_PGA_INV_GAIN_MINUS_15_GAIN_16_VM0 (0x0B) +#define OPAMP_CSR_PGA_INV_GAIN_MINUS_31_GAIN_32_VM0 (0x0C) +#define OPAMP_CSR_PGA_INV_GAIN_MINUS_63_GAIN_64_VM0 (0x0D) +/* Non-inverting gain with filtering on VINM0 */ +#define OPAMP_CSR_PGA_FILT_VM0_GAIN_2 (0x10) +#define OPAMP_CSR_PGA_FILT_VM0_GAIN_4 (0x11) +#define OPAMP_CSR_PGA_FILT_VM0_GAIN_8 (0x12) +#define OPAMP_CSR_PGA_FILT_VM0_GAIN_16 (0x13) +#define OPAMP_CSR_PGA_FILT_VM0_GAIN_32 (0x14) +#define OPAMP_CSR_PGA_FILT_VM0_GAIN_64 (0x15) +/* Inverting gain -x/non-inverting gain y with VINM0 pin for input bias + * VINM1 for filtering*/ +#define OPAMP_CSR_PGA_FILT_VM1_INV_GAIN_MINUS_1_GAIN_2_VM0 (0x18) +#define OPAMP_CSR_PGA_FILT_VM1_INV_GAIN_MINUS_3_GAIN_4_VM0 (0x19) +#define OPAMP_CSR_PGA_FILT_VM1_INV_GAIN_MINUS_7_GAIN_8_VM0 (0x1a) +#define OPAMP_CSR_PGA_FILT_VM1_INV_GAIN_MINUS_15_GAIN_16_VM0 (0x1B) +#define OPAMP_CSR_PGA_FILT_VM1_INV_GAIN_MINUS_31_GAIN_32_VM0 (0x1c) +#define OPAMP_CSR_PGA_FILT_VM1_INV_GAIN_MINUS_63_GAIN_64_VM0 (0x1d) + +#define OPAMP_CSR_OPAINTOEN (0x1 << 8) + +#define OPAMP_CSR_OPAHSM (0x1 << 7) + +#define OPAMP_CSR_VM_SEL_VINM0_IN (0x0) +#define OPAMP_CSR_VM_SEL_VINM1_IN (0x1) +#define OPAMP_CSR_VM_SEL_PGA_MODE (0x2) +#define OPAMP_CSR_VM_SEL_OUT_IN (0x3) + +#define OPAMP_CSR_USER_TRIM (0x1 << 4) + +#define OPAMP_CSR_VP_SEL_VINP0 (0x0) +#define OPAMP_CSR_VP_SEL_VINP1 (0x1) +#define OPAMP_CSR_VP_SEL_VINP2 (0x2) + +BEGIN_DECLS + +bool opamp_read_calout(uint32_t base); + +void opamp_high_speed_mode_enable(uint32_t base); +void opamp_high_speed_mode_disable(uint32_t base); + +void opamp_output_set_internal(uint32_t base); +void opamp_output_set_external(uint32_t base); + +END_DECLS +/**@}*/ + +#endif +/** @cond */ +#else +#warning "opamp_common_v2.h should not be included directly, only via opamp.h" +#endif +/** @endcond */ diff --git a/include/libopencm3/stm32/f3/opamp.h b/include/libopencm3/stm32/f3/opamp.h index 54f2d422..ad236a11 100644 --- a/include/libopencm3/stm32/f3/opamp.h +++ b/include/libopencm3/stm32/f3/opamp.h @@ -32,6 +32,8 @@ #define LIBOPENCM3_OPAMP_H /**@{*/ +#include + #define OPAMP1 (OPAMP_BASE + 0x38) #define OPAMP2 (OPAMP_BASE + 0x3C) #define OPAMP3 (OPAMP_BASE + 0x40) @@ -40,7 +42,6 @@ /* OpAmp registers */ /* Control and status register (OPAMPx_CSR) */ -#define OPAMP_CSR(opamp_base) MMIO32((opamp_base) + 0x00) #define OPAMP1_CSR OPAMP_CSR(OPAMP1) #define OPAMP2_CSR OPAMP_CSR(OPAMP2) #define OPAMP3_CSR OPAMP_CSR(OPAMP3) @@ -48,49 +49,6 @@ /* OPAMPx_CSR values */ -#define OPAMP_CSR_LOCK (0x1 << 31) - -#define OPAMP_CSR_OUTCAL_MASK (0x1) -#define OPAMP_CSR_OUTCAL_SHIFT (30) -#define OPAMP_CSR_OUTCAL_NON_LO_INV (0x0) -#define OPAMP_CSR_OUTCAL_NON_HI_INV (0x1) - -#define OPAMP_CSR_TSTREF (0x1 << 29) - -#define OPAMP_CSR_TRIMOFFSETN_MASK (0x1f) -#define OPAMP_CSR_TRIMOFFSETN_SHIFT (24) - -#define OPAMP_CSR_TRIMOFFSETP_MASK (0x1f) -#define OPAMP_CSR_TRIMOFFSETP_SHIFT (19) - -#define OPAMP_CSR_USER_TRIM (0x1 << 18) - -#define OPAMP_CSR_PGA_GAIN_MASK (0xf) -#define OPAMP_CSR_PGA_GAIN_SHIFT (14) -#define OPAMP_CSR_PGA_GAIN_2 (0x0) -#define OPAMP_CSR_PGA_GAIN_4 (0x1) -#define OPAMP_CSR_PGA_GAIN_8 (0x2) -#define OPAMP_CSR_PGA_GAIN_16 (0x3) -#define OPAMP_CSR_PGA_GAIN_2_MINUS_VM0 (0x8) -#define OPAMP_CSR_PGA_GAIN_4_MINUS_VM0 (0x9) -#define OPAMP_CSR_PGA_GAIN_8_MINUS_VM0 (0xa) -#define OPAMP_CSR_PGA_GAIN_16_MINUS_VM0 (0xb) -#define OPAMP_CSR_PGA_GAIN_2_MINUS_VM1 (0xc) -#define OPAMP_CSR_PGA_GAIN_4_MINUS_VM1 (0xd) -#define OPAMP_CSR_PGA_GAIN_8_MINUS_VM1 (0xe) -#define OPAMP_CSR_PGA_GAIN_16_MINUS_VM1 (0xf) - -#define OPAMP_CSR_CALSEL_MASK (0x3) -#define OPAMP_CSR_CALSEL_SHIFT (12) -#define OPAMP_CSR_CALSEL_3P3_PERCENT (0x0) -#define OPAMP_CSR_CALSEL_10_PERCENT (0x1) -#define OPAMP_CSR_CALSEL_50_PERCENT (0x2) -#define OPAMP_CSR_CALSEL_90_PERCENT (0x3) - -#define OPAMP_CSR_CALON (0x1 << 11) - -#define OPAMP_CSR_VPS_SEL_MASK (0x3) -#define OPAMP_CSR_VPS_SEL_SHIFT (9) #define OPAMP1_CSR_VPS_SEL_PA7 (0x0) #define OPAMP1_CSR_VPS_SEL_PA5 (0x1) #define OPAMP1_CSR_VPS_SEL_PA3 (0x2) @@ -108,8 +66,6 @@ #define OPAMP4_CSR_VPS_SEL_PA4 (0x2) #define OPAMP4_CSR_VPS_SEL_PB13 (0x3) -#define OPAMP_CSR_VMS_SEL_MASK (0x1) -#define OPAMP_CSR_VMS_SEL_SHIFT (8) #define OPAMP1_CSR_VMS_SEL_PC5 (0x0) #define OPAMP1_CSR_VMS_SEL_PA3 (0x1) #define OPAMP2_CSR_VMS_SEL_PC5 (0x0) @@ -119,12 +75,6 @@ #define OPAMP4_CSR_VMS_SEL_PB10 (0x0) #define OPAMP4_CSR_VMS_SEL_PD8 (0x1) -#define OPAMP_CSR_TCM_EN (0x1 << 7) - -#define OPAMP_CSR_VM_SEL_MASK (0x3) -#define OPAMP_CSR_VM_SEL_SHIFT (5) -#define OPAMP_CSR_VM_SEL_PGA_MODE (0x2) -#define OPAMP_CSR_VM_SEL_FOLLOWER_MODE (0x3) #define OPAMP1_CSR_VM_SEL_PC5 (0x0) #define OPAMP1_CSR_VM_SEL_PA3 (0x1) #define OPAMP2_CSR_VM_SEL_PC5 (0x0) @@ -134,8 +84,6 @@ #define OPAMP4_CSR_VM_SEL_PB10 (0x0) #define OPAMP4_CSR_VM_SEL_PD8 (0x1) -#define OPAMP_CSR_VP_SEL_MASK (0x3) -#define OPAMP_CSR_VP_SEL_SHIFT (2) #define OPAMP1_CSR_VP_SEL_PA7 (0x0) #define OPAMP1_CSR_VP_SEL_PA5 (0x1) #define OPAMP1_CSR_VP_SEL_PA3 (0x2) @@ -153,41 +101,5 @@ #define OPAMP4_CSR_VP_SEL_PA4 (0x2) #define OPAMP4_CSR_VP_SEL_PB13 (0x3) -#define OPAMP_CSR_FORCE_VP (0x1 << 1) -#define OPAMP_CSR_EN (0x1 << 0) - - -BEGIN_DECLS - -void opamp_enable(uint32_t base); -void opamp_disable(uint32_t base); -void opamp_lock(uint32_t base); - -void opamp_set_calsel(uint32_t base, uint32_t calsel); -bool opamp_read_outcal(uint32_t base); -void opamp_tstref_enable(uint32_t base); -void opamp_tstref_disable(uint32_t base); -void opamp_force_vp_enable(uint32_t base); -void opamp_force_vp_disable(uint32_t base); -void opamp_cal_enable(uint32_t base); -void opamp_cal_disable(uint32_t base); - -void opamp_trimoffsetn_set(uint32_t base, uint32_t trim); -void opamp_trimoffsetp_set(uint32_t base, uint32_t trim); -void opamp_user_trim_enable(uint32_t base); -void opamp_user_trim_disable(uint32_t base); - -void opamp_pga_gain_select(uint32_t base, uint32_t gain); - -void opamp_vp_select(uint32_t base, uint32_t vp); -void opamp_vm_select(uint32_t base, uint32_t vm); - -void opamp_vps_select(uint32_t base, uint32_t vps); -void opamp_vms_select(uint32_t base, uint32_t vms); -void opamp_tcm_enable(uint32_t base); -void opamp_tcm_disable(uint32_t base); - -END_DECLS - /**@}*/ #endif diff --git a/include/libopencm3/stm32/g4/opamp.h b/include/libopencm3/stm32/g4/opamp.h new file mode 100644 index 00000000..c3a04832 --- /dev/null +++ b/include/libopencm3/stm32/g4/opamp.h @@ -0,0 +1,70 @@ +/** @defgroup opamp_defines OPAMP Defines + * + * @brief libopencm3 Defined Constants and Types for the STM32G4xx + * Operational Amplifier module + * + * @ingroup STM32G4xx_defines + * + * @version 1.0.0 + * + * @date 10 Dec 2020 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_OPAMP_H +#define LIBOPENCM3_OPAMP_H +/**@{*/ + +#include + +#define OPAMP1 (OPAMP_BASE + 0x00) +#define OPAMP2 (OPAMP_BASE + 0x04) +#define OPAMP3 (OPAMP_BASE + 0x08) +#define OPAMP4 (OPAMP_BASE + 0x0C) +#define OPAMP5 (OPAMP_BASE + 0x10) +#define OPAMP6 (OPAMP_BASE + 0x14) + +/* OpAmp registers */ + +/* Control and status register (OPAMPx_CSR) */ +#define OPAMP1_CSR OPAMP_CSR(OPAMP1) +#define OPAMP2_CSR OPAMP_CSR(OPAMP2) +#define OPAMP3_CSR OPAMP_CSR(OPAMP3) +#define OPAMP4_CSR OPAMP_CSR(OPAMP4) +#define OPAMP5_CSR OPAMP_CSR(OPAMP5) +#define OPAMP6_CSR OPAMP_CSR(OPAMP6) + +#define OPAMP1_TCMR OPAMP_TCMR(OPAMP1) +#define OPAMP2_TCMR OPAMP_TCMR(OPAMP2) +#define OPAMP3_TCMR OPAMP_TCMR(OPAMP3) +#define OPAMP4_TCMR OPAMP_TCMR(OPAMP4) +#define OPAMP5_TCMR OPAMP_TCMR(OPAMP5) +#define OPAMP6_TCMR OPAMP_TCMR(OPAMP6) + +/* OPAMPx_CSR values */ +#define OPAMP1_CSR_VP_SEL_DAC3CH1 (0x3) +#define OPAMP2_CSR_VP_SEL_VINP3 (0x3) +#define OPAMP3_CSR_VP_SEL_DAC3CH2 (0x3) +#define OPAMP4_CSR_VP_SEL_DAC4CH1 (0x3) +#define OPAMP5_CSR_VP_SEL_DAC4CH2 (0x3) +#define OPAMP6_CSR_VP_SEL_DAC3CH1 (0x3) + +/**@}*/ +#endif diff --git a/include/libopencm3/stm32/opamp.h b/include/libopencm3/stm32/opamp.h index bde4a3a6..56e2823d 100644 --- a/include/libopencm3/stm32/opamp.h +++ b/include/libopencm3/stm32/opamp.h @@ -22,6 +22,8 @@ #if defined(STM32F3) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined." #endif diff --git a/lib/stm32/f3/opamp.c b/lib/stm32/common/opamp_common_all.c similarity index 75% rename from lib/stm32/f3/opamp.c rename to lib/stm32/common/opamp_common_all.c index 702e8eb0..49f24550 100644 --- a/lib/stm32/f3/opamp.c +++ b/lib/stm32/common/opamp_common_all.c @@ -1,14 +1,5 @@ -/** @defgroup opamp_file OPAMP - * - * @ingroup STM32F3xx - * - * @brief libopencm3 STM32F3xx OPAMP - * - * @version 1.0.0 - * - * @date 22 May 2020 - * - * LGPL License Terms @ref lgpl_license +/** @addtogroup opamp_file OPAMP peripheral API + * @ingroup peripheral_apis */ /* @@ -27,6 +18,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ + /**@{*/ #include @@ -46,29 +38,12 @@ void opamp_lock(uint32_t base) OPAMP_CSR(base) |= OPAMP_CSR_LOCK; } - void opamp_set_calsel(uint32_t base, uint32_t calsel) { OPAMP_CSR(base) &= ~(OPAMP_CSR_CALSEL_MASK << OPAMP_CSR_CALSEL_SHIFT); OPAMP_CSR(base) |= calsel << OPAMP_CSR_CALSEL_SHIFT; } -bool opamp_read_outcal(uint32_t base) -{ - return (OPAMP_CSR(base) >> OPAMP_CSR_OUTCAL_SHIFT) - & OPAMP_CSR_OUTCAL_MASK; -} - -void opamp_tcm_enable(uint32_t base) -{ - OPAMP_CSR(base) |= OPAMP_CSR_TCM_EN; -} - -void opamp_tcm_disable(uint32_t base) -{ - OPAMP_CSR(base) &= ~OPAMP_CSR_TCM_EN; -} - void opamp_force_vp_enable(uint32_t base) { OPAMP_CSR(base) |= OPAMP_CSR_FORCE_VP; @@ -89,7 +64,6 @@ void opamp_cal_disable(uint32_t base) OPAMP_CSR(base) &= ~OPAMP_CSR_CALON; } - void opamp_trimoffsetn_set(uint32_t base, uint32_t trim) { OPAMP_CSR(base) &= ~(OPAMP_CSR_TRIMOFFSETN_MASK @@ -114,7 +88,6 @@ void opamp_user_trim_disable(uint32_t base) OPAMP_CSR(base) &= ~OPAMP_CSR_USER_TRIM; } - void opamp_pga_gain_select(uint32_t base, uint32_t gain) { OPAMP_CSR(base) &= ~(OPAMP_CSR_PGA_GAIN_MASK @@ -122,7 +95,6 @@ void opamp_pga_gain_select(uint32_t base, uint32_t gain) OPAMP_CSR(base) |= gain << OPAMP_CSR_PGA_GAIN_SHIFT; } - void opamp_vp_select(uint32_t base, uint32_t vp) { OPAMP_CSR(base) &= ~(OPAMP_CSR_VP_SEL_MASK @@ -137,20 +109,4 @@ void opamp_vm_select(uint32_t base, uint32_t vm) OPAMP_CSR(base) |= vm << OPAMP_CSR_VM_SEL_SHIFT; } - -void opamp_vps_select(uint32_t base, uint32_t vps) -{ - OPAMP_CSR(base) &= ~(OPAMP_CSR_VPS_SEL_MASK - << OPAMP_CSR_VPS_SEL_SHIFT); - OPAMP_CSR(base) |= vps << OPAMP_CSR_VPS_SEL_SHIFT; -} - -void opamp_vms_select(uint32_t base, uint32_t vms) -{ - OPAMP_CSR(base) &= ~(OPAMP_CSR_VMS_SEL_MASK - << OPAMP_CSR_VMS_SEL_SHIFT); - OPAMP_CSR(base) |= vms << OPAMP_CSR_VMS_SEL_SHIFT; -} - -/**@}*/ - +/*@}*/ diff --git a/lib/stm32/common/opamp_common_v1.c b/lib/stm32/common/opamp_common_v1.c new file mode 100644 index 00000000..3f665d4c --- /dev/null +++ b/lib/stm32/common/opamp_common_v1.c @@ -0,0 +1,56 @@ +/** @addtogroup opamp_file OPAMP peripheral API + * @ingroup peripheral_apis + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +bool opamp_read_outcal(uint32_t base) +{ + return (OPAMP_CSR(base) >> OPAMP_CSR_OUTCAL_SHIFT) + & OPAMP_CSR_OUTCAL_MASK; +} + +void opamp_tcm_enable(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_TCM_EN; +} + +void opamp_tcm_disable(uint32_t base) +{ + OPAMP_CSR(base) &= ~OPAMP_CSR_TCM_EN; +} + +void opamp_vps_select(uint32_t base, uint32_t vps) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_VPS_SEL_MASK + << OPAMP_CSR_VPS_SEL_SHIFT); + OPAMP_CSR(base) |= vps << OPAMP_CSR_VPS_SEL_SHIFT; +} + +void opamp_vms_select(uint32_t base, uint32_t vms) +{ + OPAMP_CSR(base) &= ~(OPAMP_CSR_VMS_SEL_MASK + << OPAMP_CSR_VMS_SEL_SHIFT); + OPAMP_CSR(base) |= vms << OPAMP_CSR_VMS_SEL_SHIFT; +} + +/*@}*/ diff --git a/lib/stm32/common/opamp_common_v2.c b/lib/stm32/common/opamp_common_v2.c new file mode 100644 index 00000000..3641edf1 --- /dev/null +++ b/lib/stm32/common/opamp_common_v2.c @@ -0,0 +1,52 @@ +/** @addtogroup opamp_file OPAMP peripheral API + * @ingroup peripheral_apis + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +bool opamp_read_calout(uint32_t base) +{ + return (OPAMP_CSR(base) >> OPAMP_CSR_CALOUT_SHIFT) & + OPAMP_CSR_CALOUT_MASK; +} + +void opamp_high_speed_mode_enable(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_OPAHSM; +} + +void opamp_high_speed_mode_disable(uint32_t base) +{ + OPAMP_CSR(base) &= ~OPAMP_CSR_OPAHSM; +} + +void opamp_output_set_internal(uint32_t base) +{ + OPAMP_CSR(base) |= OPAMP_CSR_OPAINTOEN; +} + +void opamp_output_set_external(uint32_t base) +{ + OPAMP_CSR(base) &= ~OPAMP_CSR_OPAINTOEN; +} + +/*@}*/ diff --git a/lib/stm32/f3/Makefile b/lib/stm32/f3/Makefile index a88d277d..6d6df239 100644 --- a/lib/stm32/f3/Makefile +++ b/lib/stm32/f3/Makefile @@ -46,7 +46,7 @@ OBJS += flash.o flash_common_all.o flash_common_f.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += i2c_common_v2.o OBJS += iwdg_common_all.o -OBJS += opamp.o +OBJS += opamp_common_all.o opamp_common_v1.o OBJS += pwr_common_v1.o OBJS += rcc.o rcc_common_all.o OBJS += spi_common_all.o spi_common_v2.o diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index c5e4f594..cfdc585a 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -41,6 +41,7 @@ OBJS += dma_common_l1f013.o OBJS += dmamux.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o +OBJS += opamp_common_all.o opamp_common_v2.o OBJS += pwr.o OBJS += rcc.o rcc_common_all.o OBJS += timer_common_all.o timer_common_f0234.o From 6f81e492905269fafbd305ccaa2d79a70a94da2e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 10 Dec 2020 21:34:49 +0000 Subject: [PATCH 055/206] stm32:crc: simplify doxygen and fix groupings The @cond stuff has always been a lot of work for the rare cases of people trying to include things by hand. Just drop it --- .../libopencm3/stm32/common/crc_common_all.h | 26 ++----------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/include/libopencm3/stm32/common/crc_common_all.h b/include/libopencm3/stm32/common/crc_common_all.h index 360e5cc1..c01b97a3 100644 --- a/include/libopencm3/stm32/common/crc_common_all.h +++ b/include/libopencm3/stm32/common/crc_common_all.h @@ -27,12 +27,7 @@ The order of header inclusion is important. crc.h includes the device specific memorymap.h header before including this header file.*/ -/** @cond */ -#ifdef LIBOPENCM3_CRC_H -/** @endcond */ -#ifndef LIBOPENCM3_CRC_COMMON_ALL_H -#define LIBOPENCM3_CRC_COMMON_ALL_H - +#pragma once /**@{*/ /*****************************************************************************/ @@ -53,7 +48,7 @@ specific memorymap.h header before including this header file.*/ /** CRC_CR Control register */ #define CRC_CR MMIO32(CRC_BASE + 0x08) -/*@}*/ +/**@}*/ /*****************************************************************************/ /* Register values */ @@ -76,17 +71,8 @@ specific memorymap.h header before including this header file.*/ #define CRC_CR_RESET (1 << 0) /**@}*/ -/*****************************************************************************/ -/* API definitions */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* API Functions */ -/*****************************************************************************/ - BEGIN_DECLS -/* TODO */ /** * Reset the CRC calculator to initial values. @@ -115,11 +101,3 @@ uint32_t crc_calculate_block(uint32_t *datap, int size); END_DECLS /**@}*/ - -#endif -/** @cond */ -#else -#warning "crc_common_all.h should not be included explicitly, only via crc.h" -#endif -/** @endcond */ - From e07f23bb701bbb52cab26edbe5045b4bde67d19a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 10 Dec 2020 21:51:48 +0000 Subject: [PATCH 056/206] doxygen: fix many warnings on "end of file while in group" --- .../libopencm3/stm32/common/dac_common_all.h | 2 +- .../libopencm3/stm32/common/iwdg_common_all.h | 2 +- .../stm32/common/rtc_common_l1f024.h | 26 ++++++++++--------- include/libopencm3/stm32/f3/rcc.h | 2 +- include/libopencm3/stm32/g4/crs.h | 2 +- include/libopencm3/stm32/g4/dmamux.h | 6 ++--- include/libopencm3/stm32/g4/rcc.h | 9 ++++--- include/libopencm3/stm32/l1/rcc.h | 6 ++--- lib/stm32/common/flash_common_all.c | 2 +- lib/stm32/common/opamp_common_all.c | 2 +- lib/stm32/common/opamp_common_v1.c | 2 +- lib/stm32/common/opamp_common_v2.c | 2 +- lib/stm32/g4/adc.c | 1 - 13 files changed, 33 insertions(+), 31 deletions(-) diff --git a/include/libopencm3/stm32/common/dac_common_all.h b/include/libopencm3/stm32/common/dac_common_all.h index 258af88b..2f555e34 100644 --- a/include/libopencm3/stm32/common/dac_common_all.h +++ b/include/libopencm3/stm32/common/dac_common_all.h @@ -388,7 +388,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 /** DAC channel 2 DMA underrun flag */ #define DAC_SR_DMAUDR2 (1 << 29) -/*@}*/ +/**@}*/ /** DAC channel identifier */ typedef enum { diff --git a/include/libopencm3/stm32/common/iwdg_common_all.h b/include/libopencm3/stm32/common/iwdg_common_all.h index d7430b53..81c08446 100644 --- a/include/libopencm3/stm32/common/iwdg_common_all.h +++ b/include/libopencm3/stm32/common/iwdg_common_all.h @@ -97,7 +97,7 @@ specific memorymap.h header before including this header file.*/ /** PVU: Watchdog prescaler value update */ #define IWDG_SR_PVU (1 << 0) -/*@}*/ +/**@}*/ /* --- IWDG function prototypes---------------------------------------------- */ diff --git a/include/libopencm3/stm32/common/rtc_common_l1f024.h b/include/libopencm3/stm32/common/rtc_common_l1f024.h index d854320f..66cce5f7 100644 --- a/include/libopencm3/stm32/common/rtc_common_l1f024.h +++ b/include/libopencm3/stm32/common/rtc_common_l1f024.h @@ -40,6 +40,8 @@ specific memorymap.h header before including this header file.*/ #ifndef LIBOPENCM3_RTC2_H #define LIBOPENCM3_RTC2_H +/**@{*/ + /** @defgroup rtc_registers RTC Registers * @ingroup rtc_defines * @brief Real Time Clock registers @@ -100,7 +102,7 @@ specific memorymap.h header before including this header file.*/ /** RTC backup registers (RTC_BKPxR) */ #define RTC_BKPXR(reg) MMIO32(RTC_BKP_BASE + (4 * (reg))) -/*@}*/ +/**@}*/ /** @defgroup rtc_tr_values RTC Time register (RTC_TR) values @@ -133,7 +135,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_TR_SU_SHIFT (0) /** Second units in BCD format mask */ #define RTC_TR_SU_MASK (0xf) -/*@}*/ +/**@}*/ /** @defgroup rtc_dr_values RTC Date register (RTC_DR) values * @ingroup rtc_registers @@ -167,7 +169,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_DR_DU_SHIFT (0) /** Date units in BCD format mask */ #define RTC_DR_DU_MASK (0xf) -/*@}*/ +/**@}*/ /** @defgroup rtc_cr_values RTC control register (RTC_CR) values * @ingroup rtc_registers @@ -191,7 +193,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_CR_OSEL_ALARMA (0x1) #define RTC_CR_OSEL_ALARMB (0x2) #define RTC_CR_OSEL_WAKEUP (0x3) -/*@}*/ +/**@}*/ /** Output polarity */ #define RTC_CR_POL (1<<20) @@ -239,7 +241,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_CR_WUCLKSEL_RTC_DIV2 (0x3) #define RTC_CR_WUCLKSEL_SPRE (0x4) #define RTC_CR_WUCLKSEL_SPRE_216 (0x6) -/*@}*/ +/**@}*/ /** @defgroup rtc_isr_values RTC initialization and status register (RTC_ISR) values * @ingroup rtc_registers @@ -280,7 +282,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_ISR_ALRBWF (1<<1) /** ALRAWF: Alarm A write flag */ #define RTC_ISR_ALRAWF (1<<0) -/*@}*/ +/**@}*/ /** @defgroup rtc_prer_values RTC prescaler register (RTC_PRER) values * @ingroup rtc_registers @@ -293,7 +295,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_PRER_PREDIV_S_SHIFT (0) /** Sync prescaler factor mask */ #define RTC_PRER_PREDIV_S_MASK (0x7fff) -/*@}*/ +/**@}*/ /* RTC calibration register (RTC_CALIBR) ------------------------ */ #define RTC_CALIBR_DCS (1 << 7) @@ -327,7 +329,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_ALRMXR_ST_MASK (0x7) #define RTC_ALRMXR_SU_SHIFT (0) #define RTC_ALRMXR_SU_MASK (0xf) -/*@}*/ +/**@}*/ /* RTC shift control register (RTC_SHIFTR) ---------------------- */ #define RTC_SHIFTR_ADD1S (31) @@ -351,7 +353,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_TSTR_ST_MASK (0x7) #define RTC_TSTR_SU_SHIFT (0) #define RTC_TSTR_SU_MASK (0xf) -/*@}*/ +/**@}*/ /** @defgroup rtc_tsdr_values RTC time stamp date register (RTC_TSDR) values * @ingroup rtc_registers @@ -365,7 +367,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_TSDR_DT_MASK (0x3) #define RTC_TSDR_DU_SHIFT (0) #define RTC_TSDR_DU_MASK (0xf) -/*@}*/ +/**@}*/ /** @defgroup rtc_calr_values RTC calibration register (RTC_CALR) values * @ingroup rtc_registers @@ -375,7 +377,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_CALR_CALW16 (1 << 13) #define RTC_CALR_CALM_SHIFT (0) #define RTC_CALR_CALM_MASK (0x1ff) -/*@}*/ +/**@}*/ /** @defgroup rtc_tafcr_values RTC tamper and alternate function configuration register (RTC_TAFCR) values * @ingroup rtc_registers @@ -416,7 +418,7 @@ specific memorymap.h header before including this header file.*/ #define RTC_TAFCR_TAMPIE (1<<2) #define RTC_TAFCR_TAMP1TRG (1<<1) #define RTC_TAFCR_TAMP1E (1<<0) -/*@}*/ +/**@}*/ /* RTC alarm X sub second register ------------------------------ */ /* Note: Applies to RTC_ALRMASSR and RTC_ALRMBSSR */ diff --git a/include/libopencm3/stm32/f3/rcc.h b/include/libopencm3/stm32/f3/rcc.h index f77df32e..e7839437 100644 --- a/include/libopencm3/stm32/f3/rcc.h +++ b/include/libopencm3/stm32/f3/rcc.h @@ -281,7 +281,7 @@ #define RCC_AHBENR_SRAMEN (1 << 2) #define RCC_AHBENR_DMA2EN (1 << 1) #define RCC_AHBENR_DMA1EN (1 << 0) -/*@}*/ +/**@}*/ /** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values @{*/ diff --git a/include/libopencm3/stm32/g4/crs.h b/include/libopencm3/stm32/g4/crs.h index 4a3ab10d..11d7616a 100644 --- a/include/libopencm3/stm32/g4/crs.h +++ b/include/libopencm3/stm32/g4/crs.h @@ -1,6 +1,6 @@ /** @defgroup crs_defines CRS Defines * - * @brief Defined Constants and Types for the Clock Recovery System. + * @brief Defined Constants and Types for the Clock Recovery System * * @ingroup STM32G4xx_defines * diff --git a/include/libopencm3/stm32/g4/dmamux.h b/include/libopencm3/stm32/g4/dmamux.h index 1a746620..7876c753 100644 --- a/include/libopencm3/stm32/g4/dmamux.h +++ b/include/libopencm3/stm32/g4/dmamux.h @@ -26,8 +26,8 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_DMAMUX_H -#define LIBOPENCM3_DMAMUX_H +#pragma once + /**@{*/ #include @@ -63,6 +63,7 @@ LGPL License Terms @ref lgpl_license #define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH2_EVT 18 #define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH3_EVT 19 #define DMAMUX_CxCR_SYNC_ID_LPTIM1_OUT 20 +/**@}*/ /** @defgroup dmamux_cxcr_dmareq_id DMAREQID DMA request line selected @@ -213,4 +214,3 @@ LGPL License Terms @ref lgpl_license /**@}*/ /**@}*/ -#endif diff --git a/include/libopencm3/stm32/g4/rcc.h b/include/libopencm3/stm32/g4/rcc.h index 51e45c76..dbf1ef04 100644 --- a/include/libopencm3/stm32/g4/rcc.h +++ b/include/libopencm3/stm32/g4/rcc.h @@ -177,7 +177,7 @@ #define RCC_CFGR_HPRE_DIV128 0xd #define RCC_CFGR_HPRE_DIV256 0xe #define RCC_CFGR_HPRE_DIV512 0xf -/*@}*/ +/**@}*/ #define RCC_CFGR_HPRE_MASK 0xf #define RCC_CFGR_HPRE_SHIFT 4 @@ -207,6 +207,7 @@ #define RCC_PLLCFGR_PLLR_DIV4 1 #define RCC_PLLCFGR_PLLR_DIV6 2 #define RCC_PLLCFGR_PLLR_DIV8 3 +/**@}*/ #define RCC_PLLCFGR_PLLR_SHIFT 25 #define RCC_PLLCFGR_PLLR_MASK 0x3 @@ -446,15 +447,15 @@ #define RCC_APB1ENR1_TIM4EN (1 << 2) #define RCC_APB1ENR1_TIM3EN (1 << 1) #define RCC_APB1ENR1_TIM2EN (1 << 0) -/*@}*/ +/**@}*/ /** @defgroup rcc_apb1enr2_en RCC_APB1ENR2 enable values *@{*/ #define RCC_APB1ENR2_UCPD1EN (1 << 8) #define RCC_APB1ENR2_I2C4EN (1 << 1) #define RCC_APB1ENR2_LPUART1EN (1 << 0) -/*@}*/ -/*@}*/ +/**@}*/ +/**@}*/ /** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values *@{*/ diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h index 220d1f88..08b9017b 100644 --- a/include/libopencm3/stm32/l1/rcc.h +++ b/include/libopencm3/stm32/l1/rcc.h @@ -331,7 +331,7 @@ #define RCC_AHBENR_GPIOCEN (1 << 2) #define RCC_AHBENR_GPIOBEN (1 << 1) #define RCC_AHBENR_GPIOAEN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_APB2ENR values -------------------------------------------------- */ @@ -346,7 +346,7 @@ #define RCC_APB2ENR_TIM10EN (1 << 3) #define RCC_APB2ENR_TIM9EN (1 << 2) #define RCC_APB2ENR_SYSCFGEN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_APB1ENR values -------------------------------------------------- */ @@ -370,7 +370,7 @@ #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) diff --git a/lib/stm32/common/flash_common_all.c b/lib/stm32/common/flash_common_all.c index b369d903..53f7990d 100644 --- a/lib/stm32/common/flash_common_all.c +++ b/lib/stm32/common/flash_common_all.c @@ -49,4 +49,4 @@ void flash_unlock_option_bytes(void) FLASH_OPTKEYR = FLASH_OPTKEYR_KEY2; } -/*@}*/ +/**@}*/ diff --git a/lib/stm32/common/opamp_common_all.c b/lib/stm32/common/opamp_common_all.c index 49f24550..acd84596 100644 --- a/lib/stm32/common/opamp_common_all.c +++ b/lib/stm32/common/opamp_common_all.c @@ -109,4 +109,4 @@ void opamp_vm_select(uint32_t base, uint32_t vm) OPAMP_CSR(base) |= vm << OPAMP_CSR_VM_SEL_SHIFT; } -/*@}*/ +/**@}*/ diff --git a/lib/stm32/common/opamp_common_v1.c b/lib/stm32/common/opamp_common_v1.c index 3f665d4c..3000be63 100644 --- a/lib/stm32/common/opamp_common_v1.c +++ b/lib/stm32/common/opamp_common_v1.c @@ -53,4 +53,4 @@ void opamp_vms_select(uint32_t base, uint32_t vms) OPAMP_CSR(base) |= vms << OPAMP_CSR_VMS_SEL_SHIFT; } -/*@}*/ +/**@}*/ diff --git a/lib/stm32/common/opamp_common_v2.c b/lib/stm32/common/opamp_common_v2.c index 3641edf1..fbb6ec3f 100644 --- a/lib/stm32/common/opamp_common_v2.c +++ b/lib/stm32/common/opamp_common_v2.c @@ -49,4 +49,4 @@ void opamp_output_set_external(uint32_t base) OPAMP_CSR(base) &= ~OPAMP_CSR_OPAINTOEN; } -/*@}*/ +/**@}*/ diff --git a/lib/stm32/g4/adc.c b/lib/stm32/g4/adc.c index 4ce7ad72..1b1cd920 100644 --- a/lib/stm32/g4/adc.c +++ b/lib/stm32/g4/adc.c @@ -27,7 +27,6 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ -/**@{*/ #include From 992a4d375315e2f375cce8e6a202a690591d873d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 10 Dec 2020 22:00:03 +0000 Subject: [PATCH 057/206] stm32: rtc: doxygenize existing docs Might as well show the information we have! --- .../stm32/common/rtc_common_l1f024.h | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/include/libopencm3/stm32/common/rtc_common_l1f024.h b/include/libopencm3/stm32/common/rtc_common_l1f024.h index 66cce5f7..4ae116b8 100644 --- a/include/libopencm3/stm32/common/rtc_common_l1f024.h +++ b/include/libopencm3/stm32/common/rtc_common_l1f024.h @@ -1,8 +1,14 @@ /** @addtogroup rtc_defines - -@author @htmlonly © @endhtmlonly 2012 Karl Palsson - -*/ + * @author @htmlonly © @endhtmlonly 2012 Karl Palsson + * + * @brief This covers the "version 2" RTC peripheral. + * + * This is completely different + * to the v1 RTC periph on the F1 series devices. It has BCD counters, with + * automatic leapyear corrections and daylight savings support. + * This peripheral is used on the F0, F2, F3, F4 and L1 devices, though some + * only support a subset. + */ /* * This file is part of the libopencm3 project. * @@ -22,14 +28,6 @@ * along with this library. If not, see . */ -/* - * This covers the "version 2" RTC peripheral. This is completely different - * to the v1 RTC periph on the F1 series devices. It has BCD counters, with - * automatic leapyear corrections and daylight savings support. - * This peripheral is used on the F0, F2, F3, F4 and L1 devices, though some - * only support a subset. - */ - /* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA RTC.H The order of header inclusion is important. rtc.h includes the device specific memorymap.h header before including this header file.*/ From 97d5e9a403a1eeca7b87ac250bb6e1f37db00f25 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 10 Dec 2020 22:25:51 +0000 Subject: [PATCH 058/206] doxygen: fix more broken groupings --- .../stm32/common/flash_common_f24.h | 4 ++-- include/libopencm3/stm32/f0/crs.h | 2 +- include/libopencm3/stm32/f1/bkp.h | 8 +++---- include/libopencm3/stm32/f7/flash.h | 2 +- include/libopencm3/stm32/f7/pwr.h | 10 ++++----- include/libopencm3/stm32/l0/crs.h | 2 +- include/libopencm3/stm32/l0/timer.h | 6 +---- include/libopencm3/stm32/l4/crs.h | 2 +- include/libopencm3/stm32/l4/rcc.h | 22 +++++++++---------- lib/stm32/common/flash_common_l01.c | 4 ---- 10 files changed, 27 insertions(+), 35 deletions(-) diff --git a/include/libopencm3/stm32/common/flash_common_f24.h b/include/libopencm3/stm32/common/flash_common_f24.h index 27b1ee16..138ba6e1 100644 --- a/include/libopencm3/stm32/common/flash_common_f24.h +++ b/include/libopencm3/stm32/common/flash_common_f24.h @@ -59,7 +59,7 @@ #define FLASH_OPTCR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) /** Flash Option Control register 1 (bank 2) */ #define FLASH_OPTCR1 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x18) -/*@}*/ +/**@}*/ /** @defgroup flash_latency FLASH Wait States @ingroup flash_defines @@ -73,7 +73,7 @@ #define FLASH_ACR_LATENCY_5WS 0x05 #define FLASH_ACR_LATENCY_6WS 0x06 #define FLASH_ACR_LATENCY_7WS 0x07 -/*@}*/ +/**@}*/ #define FLASH_ACR_LATENCY_SHIFT 0 #define FLASH_ACR_LATENCY_MASK 0x0f diff --git a/include/libopencm3/stm32/f0/crs.h b/include/libopencm3/stm32/f0/crs.h index 4e6e2592..21e106cd 100644 --- a/include/libopencm3/stm32/f0/crs.h +++ b/include/libopencm3/stm32/f0/crs.h @@ -1,6 +1,6 @@ /** @defgroup crs_defines CRS Defines * - * @brief Defined Constants and Types for the Clock Recovery System. + * @brief Defined Constants and Types for the Clock Recovery System * * @ingroup STM32F0xx_defines * diff --git a/include/libopencm3/stm32/f1/bkp.h b/include/libopencm3/stm32/f1/bkp.h index 577c6c20..fff9c7f7 100644 --- a/include/libopencm3/stm32/f1/bkp.h +++ b/include/libopencm3/stm32/f1/bkp.h @@ -161,7 +161,7 @@ /* Backup data register 42 (BKP_DR42) */ #define BKP_DR42 MMIO32(BACKUP_REGS_BASE + 0xBC) -/*@}*/ +/**@}*/ /** @defgroup BKP_RTCCR_Values BKP_RTCCR Values * @ingroup bkp_defines @@ -177,7 +177,7 @@ /** CAL[6:0]: Calibration value */ #define BKP_RTCCR_CAL_LSB 0 -/*@}*/ +/**@}*/ /** @defgroup BKP_CR_Values BKP_CR Values * @ingroup bkp_defines @@ -187,7 +187,7 @@ /** TPE: TAMPER pin enable */ #define BKP_CR_TPE (1 << 0) -/*@}*/ +/**@}*/ /** @defgroup BKP_CSR_Values BKP_CSR Values * @ingroup bkp_defines @@ -206,6 +206,6 @@ /** CTE: Clear tamper event */ #define BKP_CSR_CTE (1 << 0) -/*@}*/ +/**@}*/ #endif diff --git a/include/libopencm3/stm32/f7/flash.h b/include/libopencm3/stm32/f7/flash.h index 0047da88..79abbbff 100644 --- a/include/libopencm3/stm32/f7/flash.h +++ b/include/libopencm3/stm32/f7/flash.h @@ -59,7 +59,7 @@ #define FLASH_ACR_ARTRST (1 << 11) #define FLASH_ACR_ARTEN (1 << 9) #define FLASH_ACR_PRFTEN (1 << 8) -/*@}*/ +/**@}*/ #define FLASH_SR_ERSERR (1 << 7) diff --git a/include/libopencm3/stm32/f7/pwr.h b/include/libopencm3/stm32/f7/pwr.h index 46055710..1b3ac759 100644 --- a/include/libopencm3/stm32/f7/pwr.h +++ b/include/libopencm3/stm32/f7/pwr.h @@ -50,7 +50,7 @@ LGPL License Terms @ref lgpl_license /** Power control/status register 2 (PWR_CSR2) */ #define PWR_CSR2 MMIO32(POWER_CONTROL_BASE + 0x0c) -/*@}*/ +/**@}*/ /** @defgroup pwr_cr1_defines PWR_CR1 values * @ingroup STM32F_pwr_defines @@ -134,7 +134,7 @@ LGPL License Terms @ref lgpl_license /** LPDS: Low-power deepsleep */ #define PWR_CR1_LPDS (1 << 0) -/*@}*/ +/**@}*/ /** @defgroup pwr_csr1_defines PWR_CSR1 values * @ingroup STM32F_pwr_defines @@ -185,7 +185,7 @@ LGPL License Terms @ref lgpl_license /** WUIF: Wakeup internal flag */ #define PWR_CSR1_WUIF (1 << 0) -/*@}*/ +/**@}*/ /** @defgroup pwr_cr2_defines PWR_CR2 values * @ingroup STM32F_pwr_defines @@ -230,7 +230,7 @@ LGPL License Terms @ref lgpl_license /** CWUPF1: Clear Wakeup Pin flag for PA0 */ #define PWR_CR2_CWUPF1 (1 << 0) -/*@}*/ +/**@}*/ /** @defgroup pwr_csr2_defines PWR_CSR2 values * @ingroup STM32F_pwr_defines @@ -275,7 +275,7 @@ LGPL License Terms @ref lgpl_license /** WUPF1: Wakeup Pin flag for PA0 */ #define PWR_CSR2_WUPF1 (1 << 0) -/*@}*/ +/**@}*/ /* --- Function prototypes ------------------------------------------------- */ enum pwr_vos_scale { diff --git a/include/libopencm3/stm32/l0/crs.h b/include/libopencm3/stm32/l0/crs.h index 5bfc4cfb..76d259c6 100644 --- a/include/libopencm3/stm32/l0/crs.h +++ b/include/libopencm3/stm32/l0/crs.h @@ -1,6 +1,6 @@ /** @defgroup crs_defines CRS Defines * - * @brief Defined Constants and Types for the Clock Recovery System. + * @brief Defined Constants and Types for the Clock Recovery System * * @ingroup STM32L0xx_defines * diff --git a/include/libopencm3/stm32/l0/timer.h b/include/libopencm3/stm32/l0/timer.h index 98772811..1c6eb524 100644 --- a/include/libopencm3/stm32/l0/timer.h +++ b/include/libopencm3/stm32/l0/timer.h @@ -32,8 +32,7 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H +#pragma once #include @@ -98,6 +97,3 @@ LGPL License Terms @ref lgpl_license /**@}*/ -#endif - -/**@}*/ diff --git a/include/libopencm3/stm32/l4/crs.h b/include/libopencm3/stm32/l4/crs.h index 21b120f0..19e5a434 100644 --- a/include/libopencm3/stm32/l4/crs.h +++ b/include/libopencm3/stm32/l4/crs.h @@ -1,6 +1,6 @@ /** @defgroup crs_defines CRS Defines * - * @brief Defined Constants and Types for the Clock Recovery System. + * @brief Defined Constants and Types for the Clock Recovery System * * @ingroup STM32L4xx_defines * diff --git a/include/libopencm3/stm32/l4/rcc.h b/include/libopencm3/stm32/l4/rcc.h index 24f9b391..09edc71e 100644 --- a/include/libopencm3/stm32/l4/rcc.h +++ b/include/libopencm3/stm32/l4/rcc.h @@ -128,7 +128,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CR_MSIRANGE_24MHZ 9 #define RCC_CR_MSIRANGE_32MHZ 10 #define RCC_CR_MSIRANGE_48MHZ 11 -/*@}*/ +/**@}*/ #define RCC_CR_MSIRGSEL (1 << 3) #define RCC_CR_MSIPLLEN (1 << 2) #define RCC_CR_MSIRDY (1 << 1) @@ -255,7 +255,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, @{*/ #define RCC_PLLCFGR_PLLN_SHIFT 0x8 #define RCC_PLLCFGR_PLLN_MASK 0x7f -/*@}*/ +/**@}*/ /** @defgroup rcc_pllcfgr_pllm RCC_PLLCFGR PLLM values @ingroup STM32L4xx_rcc_defines @@ -264,7 +264,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_PLLCFGR_PLLM_SHIFT 0x4 #define RCC_PLLCFGR_PLLM_MASK 0x7 #define RCC_PLLCFGR_PLLM(x) ((x)-1) -/*@}*/ +/**@}*/ #define RCC_PLLCFGR_PLLSRC_SHIFT 0 #define RCC_PLLCFGR_PLLSRC_MASK 0x3 @@ -420,7 +420,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_AHB1ENR_FLASHEN (1 << 8) #define RCC_AHB1ENR_DMA2EN (1 << 1) #define RCC_AHB1ENR_DMA1EN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_AHB2ENR values --------------------------------------------------- */ @@ -440,7 +440,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_AHB2ENR_GPIOCEN (1 << 2) #define RCC_AHB2ENR_GPIOBEN (1 << 1) #define RCC_AHB2ENR_GPIOAEN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_AHB3ENR values --------------------------------------------------- */ @@ -450,7 +450,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, @{*/ #define RCC_AHB3ENR_QSPIEN (1 << 8) #define RCC_AHB3ENR_FMCEN (1 << 0) -/*@}*/ +/**@}*/ /**@}*/ @@ -483,7 +483,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_APB1ENR1_TIM4EN (1 << 2) #define RCC_APB1ENR1_TIM3EN (1 << 1) #define RCC_APB1ENR1_TIM2EN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_APB1ENR2 values -------------------------------------------------- */ @@ -494,8 +494,8 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_APB1ENR2_LPTIM2EN (1 << 5) #define RCC_APB1ENR2_SWPMI1EN (1 << 2) #define RCC_APB1ENR2_LPUART1EN (1 << 0) -/*@}*/ -/*@}*/ +/**@}*/ +/**@}*/ /* --- RCC_APB2ENR values -------------------------------------------------- */ @@ -516,7 +516,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_APB2ENR_SDMMC1EN (1 << 10) #define RCC_APB2ENR_FWEN (1 << 7) #define RCC_APB2ENR_SYSCFGEN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_AHB1SMENR - AHB1 periph clock in sleep mode --------------------- */ @@ -722,7 +722,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CSR_MSIRANGE_2MHZ 5 #define RCC_CSR_MSIRANGE_4MHZ 6 #define RCC_CSR_MSIRANGE_8MHZ 7 -/*@}*/ +/**@}*/ #define RCC_CSR_LSIRDY (1 << 1) #define RCC_CSR_LSION (1 << 0) diff --git a/lib/stm32/common/flash_common_l01.c b/lib/stm32/common/flash_common_l01.c index 6415f728..e7b2b8d4 100644 --- a/lib/stm32/common/flash_common_l01.c +++ b/lib/stm32/common/flash_common_l01.c @@ -97,10 +97,6 @@ void flash_unlock_acr(void) FLASH_PDKEYR = FLASH_PDKEYR_PDKEY2; } -/** - * Erase a page in ram. - * @param page_address must be first word in page for L1, any address in page for L0 - */ void flash_erase_page(uint32_t page_address) { FLASH_PECR |= FLASH_PECR_ERASE | FLASH_PECR_PROG; From 1abb945dcd0102bf88398f5126672ef07b50412a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 10 Dec 2020 22:26:05 +0000 Subject: [PATCH 059/206] stm32f7: flash: doxygenize existing comments. Just putting it in a different place and it all gets included in the output nicely. --- include/libopencm3/stm32/f7/flash.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/include/libopencm3/stm32/f7/flash.h b/include/libopencm3/stm32/f7/flash.h index 79abbbff..031e0d77 100644 --- a/include/libopencm3/stm32/f7/flash.h +++ b/include/libopencm3/stm32/f7/flash.h @@ -9,6 +9,15 @@ * @author @htmlonly © @endhtmlonly 2010 * Mark Butler * + * Differences between F7 and F4: + * 1. icache and dcache are now combined into a unified ART cache. The CPU has + * its own d/i-caches, but those are unrelated to this. They are on the + * AXIM bus. + * 4. FLASH_SR_PGSERR (programming sequence error) is now FLASH_SR_ERSERR ( + * erase sequence error). + * 6. There are now two watchdogs - IWDG (independent watchdog) and WWDG ( + * window watchdog). + * */ /* * This file is part of the libopencm3 project. @@ -38,17 +47,6 @@ #include #include -/* - * Differences between F7 and F4: - * 1. icache and dcache are now combined into a unified ART cache. The CPU has - * its own d/i-caches, but those are unrelated to this. They are on the - * AXIM bus. - * 4. FLASH_SR_PGSERR (programming sequence error) is now FLASH_SR_ERSERR ( - * erase sequence error). - * 6. There are now two watchdogs - IWDG (independent watchdog) and WWDG ( - * window watchdog). - */ - /**@{*/ /* --- FLASH_ACR values ---------------------------------------------------- */ From a499ea34800ad3fe90733445829661b5dbac5215 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 10 Dec 2020 23:00:11 +0000 Subject: [PATCH 060/206] stm32: timer/dmamux: fix broken includes bad Karl, you can't just _start_ using pragma on common files, and expect it to keep working. Just finish, convert them fully to pragma. pros: no more weird @cond boilerplate mess and trailing #endifs. easier to follow cons: no warning for people who deliberately try and include things in bad orders. --- .../libopencm3/stm32/common/dmamux_common_all.h | 13 +------------ .../libopencm3/stm32/common/timer_common_all.h | 13 +------------ .../libopencm3/stm32/common/timer_common_f24.h | 15 +-------------- include/libopencm3/stm32/f0/timer.h | 5 +---- include/libopencm3/stm32/f1/timer.h | 5 +---- include/libopencm3/stm32/f2/timer.h | 6 +----- include/libopencm3/stm32/f3/timer.h | 6 +----- include/libopencm3/stm32/f4/timer.h | 6 +----- include/libopencm3/stm32/f7/timer.h | 10 +--------- include/libopencm3/stm32/g0/dmamux.h | 4 +--- include/libopencm3/stm32/g0/timer.h | 6 +----- include/libopencm3/stm32/g4/timer.h | 6 +----- include/libopencm3/stm32/h7/timer.h | 10 +--------- include/libopencm3/stm32/l0/timer.h | 2 -- include/libopencm3/stm32/l1/timer.h | 6 +----- include/libopencm3/stm32/l4/timer.h | 10 +--------- 16 files changed, 15 insertions(+), 108 deletions(-) diff --git a/include/libopencm3/stm32/common/dmamux_common_all.h b/include/libopencm3/stm32/common/dmamux_common_all.h index c3bd0bf7..f8b1a528 100644 --- a/include/libopencm3/stm32/common/dmamux_common_all.h +++ b/include/libopencm3/stm32/common/dmamux_common_all.h @@ -25,11 +25,7 @@ * along with this library. If not, see . */ -/** @cond */ -#if defined(LIBOPENCM3_DMAMUX_H) -/** @endcond */ -#ifndef LIBOPENCM3_DMAMUX_COMMON_ALL_H -#define LIBOPENCM3_DMAMUX_COMMON_ALL_H +#pragma once /**@{*/ @@ -205,10 +201,3 @@ void dmamux_clear_request_generator_trigger_overrun_interrupt(uint32_t dmamux, u END_DECLS /**@}*/ - -#endif -/** @cond */ -#else -#warning "dmamux_common_all.h should not be included explicitly, only via dmamux.h" -#endif -/** @endcond */ diff --git a/include/libopencm3/stm32/common/timer_common_all.h b/include/libopencm3/stm32/common/timer_common_all.h index c3b8c048..08939d90 100644 --- a/include/libopencm3/stm32/common/timer_common_all.h +++ b/include/libopencm3/stm32/common/timer_common_all.h @@ -28,12 +28,7 @@ The order of header inclusion is important. timer.h includes the device specific memorymap.h header before including this header file.*/ -/** @cond */ -#if defined(LIBOPENCM3_TIMER_H) -/** @endcond */ -#ifndef LIBOPENCM3_TIMER_COMMON_H -#define LIBOPENCM3_TIMER_COMMON_H - +#pragma once /* --- Convenience macros -------------------------------------------------- */ /* Timer register base addresses (for convenience) */ @@ -1241,10 +1236,4 @@ void timer_slave_set_trigger(uint32_t timer, uint8_t trigger); END_DECLS -#endif -/** @cond */ -#else -#warning "timer_common_all.h should not be included directly, only via timer.h" -#endif -/** @endcond */ /**@}*/ diff --git a/include/libopencm3/stm32/common/timer_common_f24.h b/include/libopencm3/stm32/common/timer_common_f24.h index 6f483d86..2d9c98ad 100644 --- a/include/libopencm3/stm32/common/timer_common_f24.h +++ b/include/libopencm3/stm32/common/timer_common_f24.h @@ -27,12 +27,7 @@ The order of header inclusion is important. timer.h includes the device specific memorymap.h header before including this header file.*/ -/** @cond */ -#ifdef LIBOPENCM3_TIMER_H -/** @endcond */ -#ifndef LIBOPENCM3_TIMER_COMMON_F24_H -#define LIBOPENCM3_TIMER_COMMON_F24_H - +#pragma once #include /* @@ -104,11 +99,3 @@ void timer_ic_set_polarity(uint32_t timer, enum tim_ic_id ic, enum tim_ic_pol pol); END_DECLS - -#endif -/** @cond */ -#else -#warning "timer_common_f24.h should not be included directly, only via timer.h" -#endif -/** @endcond */ - diff --git a/include/libopencm3/stm32/f0/timer.h b/include/libopencm3/stm32/f0/timer.h index 5f59816c..2f5aea27 100644 --- a/include/libopencm3/stm32/f0/timer.h +++ b/include/libopencm3/stm32/f0/timer.h @@ -29,9 +29,6 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H +#pragma once #include - -#endif diff --git a/include/libopencm3/stm32/f1/timer.h b/include/libopencm3/stm32/f1/timer.h index 6046d792..018c9c2e 100644 --- a/include/libopencm3/stm32/f1/timer.h +++ b/include/libopencm3/stm32/f1/timer.h @@ -32,8 +32,7 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H +#pragma once #include @@ -52,5 +51,3 @@ void timer_ic_set_polarity(uint32_t timer, enum tim_ic_pol pol); END_DECLS - -#endif diff --git a/include/libopencm3/stm32/f2/timer.h b/include/libopencm3/stm32/f2/timer.h index 7dc6d326..ad88dcff 100644 --- a/include/libopencm3/stm32/f2/timer.h +++ b/include/libopencm3/stm32/f2/timer.h @@ -31,9 +31,5 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include - -#endif diff --git a/include/libopencm3/stm32/f3/timer.h b/include/libopencm3/stm32/f3/timer.h index f9284c7e..1201ec83 100644 --- a/include/libopencm3/stm32/f3/timer.h +++ b/include/libopencm3/stm32/f3/timer.h @@ -31,9 +31,5 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include - -#endif diff --git a/include/libopencm3/stm32/f4/timer.h b/include/libopencm3/stm32/f4/timer.h index 604a83f3..1155e8ed 100644 --- a/include/libopencm3/stm32/f4/timer.h +++ b/include/libopencm3/stm32/f4/timer.h @@ -31,9 +31,5 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include - -#endif diff --git a/include/libopencm3/stm32/f7/timer.h b/include/libopencm3/stm32/f7/timer.h index da890943..0ebd4a4b 100644 --- a/include/libopencm3/stm32/f7/timer.h +++ b/include/libopencm3/stm32/f7/timer.h @@ -30,13 +30,5 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include - -BEGIN_DECLS - -END_DECLS - -#endif diff --git a/include/libopencm3/stm32/g0/dmamux.h b/include/libopencm3/stm32/g0/dmamux.h index 27775344..6306d656 100644 --- a/include/libopencm3/stm32/g0/dmamux.h +++ b/include/libopencm3/stm32/g0/dmamux.h @@ -29,8 +29,7 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_DMAMUX_H -#define LIBOPENCM3_DMAMUX_H +#pragma once /**@{*/ #include @@ -169,4 +168,3 @@ /**@}*/ /**@}*/ -#endif diff --git a/include/libopencm3/stm32/g0/timer.h b/include/libopencm3/stm32/g0/timer.h index 1f102ba8..0b4dd226 100644 --- a/include/libopencm3/stm32/g0/timer.h +++ b/include/libopencm3/stm32/g0/timer.h @@ -27,9 +27,7 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include /**@{*/ @@ -70,5 +68,3 @@ BEGIN_DECLS END_DECLS /**@}*/ - -#endif diff --git a/include/libopencm3/stm32/g4/timer.h b/include/libopencm3/stm32/g4/timer.h index 06a661c7..3cf831f6 100644 --- a/include/libopencm3/stm32/g4/timer.h +++ b/include/libopencm3/stm32/g4/timer.h @@ -27,9 +27,5 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include - -#endif diff --git a/include/libopencm3/stm32/h7/timer.h b/include/libopencm3/stm32/h7/timer.h index 62a636a4..049cb49c 100644 --- a/include/libopencm3/stm32/h7/timer.h +++ b/include/libopencm3/stm32/h7/timer.h @@ -21,13 +21,5 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include - -BEGIN_DECLS - -END_DECLS - -#endif diff --git a/include/libopencm3/stm32/l0/timer.h b/include/libopencm3/stm32/l0/timer.h index 1c6eb524..5e77059d 100644 --- a/include/libopencm3/stm32/l0/timer.h +++ b/include/libopencm3/stm32/l0/timer.h @@ -33,7 +33,6 @@ LGPL License Terms @ref lgpl_license */ #pragma once - #include /**@{*/ @@ -96,4 +95,3 @@ LGPL License Terms @ref lgpl_license #define TIM22_OR_TI1_RMP_COMP1_OUT (2 << TIM22_OR_TI1_RMP_SHIFT) /**@}*/ - diff --git a/include/libopencm3/stm32/l1/timer.h b/include/libopencm3/stm32/l1/timer.h index faef4346..fe1c0893 100644 --- a/include/libopencm3/stm32/l1/timer.h +++ b/include/libopencm3/stm32/l1/timer.h @@ -32,9 +32,7 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include /**@{*/ @@ -84,5 +82,3 @@ void timer_set_option(uint32_t timer_peripheral, uint32_t option); END_DECLS /**@}*/ - -#endif diff --git a/include/libopencm3/stm32/l4/timer.h b/include/libopencm3/stm32/l4/timer.h index 355c1ca1..2486172b 100644 --- a/include/libopencm3/stm32/l4/timer.h +++ b/include/libopencm3/stm32/l4/timer.h @@ -32,13 +32,5 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_TIMER_H -#define LIBOPENCM3_TIMER_H - +#pragma once #include - -BEGIN_DECLS - -END_DECLS - -#endif From 52781dee562cddb5b72ba094ea9a57980bf9a7c0 Mon Sep 17 00:00:00 2001 From: Kejia Hu Date: Tue, 8 Sep 2020 18:56:53 +0100 Subject: [PATCH 061/206] stm32g4: add SPI The SPI peripheral on G4 is identical to F3, this patch copies the header files directly from F3 --- include/libopencm3/stm32/g4/spi.h | 34 +++++++++++++++++++++++++++++++ include/libopencm3/stm32/spi.h | 2 ++ lib/stm32/g4/Makefile | 1 + 3 files changed, 37 insertions(+) create mode 100644 include/libopencm3/stm32/g4/spi.h diff --git a/include/libopencm3/stm32/g4/spi.h b/include/libopencm3/stm32/g4/spi.h new file mode 100644 index 00000000..d7365245 --- /dev/null +++ b/include/libopencm3/stm32/g4/spi.h @@ -0,0 +1,34 @@ +/** @defgroup spi_defines SPI Defines + * + * @brief Defined Constants and Types for the STM32G4xx SPI + * + * @ingroup STM32G4xx_defines + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SPI_H +#define LIBOPENCM3_SPI_H + +#include + +#endif diff --git a/include/libopencm3/stm32/spi.h b/include/libopencm3/stm32/spi.h index c0a27301..b7e8bc0a 100644 --- a/include/libopencm3/stm32/spi.h +++ b/include/libopencm3/stm32/spi.h @@ -40,6 +40,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include #else diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index cfdc585a..c9ac6fd6 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -44,6 +44,7 @@ OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += opamp_common_all.o opamp_common_v2.o OBJS += pwr.o OBJS += rcc.o rcc_common_all.o +OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o timer_common_f0234.o OBJS += usb.o usb_control.o usb_standard.o From 1ebf172bcb7548faf97315d6a1b4013316574ef2 Mon Sep 17 00:00:00 2001 From: Ben Brewer Date: Mon, 3 Aug 2020 16:46:46 +0100 Subject: [PATCH 062/206] stm32/dac: Update API to support multiple DACs and add v2 support --- .../libopencm3/stm32/common/dac_common_all.h | 361 +++-------- .../libopencm3/stm32/common/dac_common_v1.h | 136 +++++ .../libopencm3/stm32/common/dac_common_v2.h | 570 ++++++++++++++++++ include/libopencm3/stm32/dac.h | 2 + include/libopencm3/stm32/f0/dac.h | 61 +- include/libopencm3/stm32/f1/dac.h | 8 +- include/libopencm3/stm32/f2/dac.h | 8 +- include/libopencm3/stm32/f3/dac.h | 9 +- include/libopencm3/stm32/f3/memorymap.h | 3 +- include/libopencm3/stm32/f4/dac.h | 8 +- include/libopencm3/stm32/f7/dac.h | 8 +- include/libopencm3/stm32/g4/dac.h | 46 ++ include/libopencm3/stm32/h7/dac.h | 8 +- include/libopencm3/stm32/l1/dac.h | 8 +- include/libopencm3/stm32/l4/dac.h | 8 +- lib/stm32/common/dac_common_all.c | 348 +++++------ lib/stm32/common/dac_common_v1.c | 85 +++ lib/stm32/common/dac_common_v2.c | 163 +++++ lib/stm32/f0/Makefile | 2 +- lib/stm32/f1/Makefile | 2 +- lib/stm32/f2/Makefile | 2 +- lib/stm32/f3/Makefile | 2 +- lib/stm32/f4/Makefile | 2 +- lib/stm32/f7/Makefile | 2 +- lib/stm32/g4/Makefile | 1 + lib/stm32/h7/Makefile | 2 +- lib/stm32/l1/Makefile | 2 +- lib/stm32/l4/Makefile | 2 +- 28 files changed, 1330 insertions(+), 529 deletions(-) create mode 100644 include/libopencm3/stm32/common/dac_common_v1.h create mode 100644 include/libopencm3/stm32/common/dac_common_v2.h create mode 100644 include/libopencm3/stm32/g4/dac.h create mode 100644 lib/stm32/common/dac_common_v1.c create mode 100644 lib/stm32/common/dac_common_v2.c diff --git a/include/libopencm3/stm32/common/dac_common_all.h b/include/libopencm3/stm32/common/dac_common_all.h index 2f555e34..fc3ca40c 100644 --- a/include/libopencm3/stm32/common/dac_common_all.h +++ b/include/libopencm3/stm32/common/dac_common_all.h @@ -2,6 +2,8 @@ @author @htmlonly © @endhtmlonly 2012 Felix Held +@author @htmlonly © @endhtmlonly 2020 +Ben Brewer */ @@ -9,6 +11,7 @@ Felix Held * This file is part of the libopencm3 project. * * Copyright (C) 2012 Felix Held + * Copyright (C) 2020 Ben Brewer * * 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 @@ -39,48 +42,48 @@ specific memorymap.h header before including this header file.*/ /* --- DAC registers ------------------------------------------------------- */ /* DAC control register (DAC_CR) */ -#define DAC_CR MMIO32(DAC_BASE + 0x00) +#define DAC_CR(dac) MMIO32((dac) + 0x00) /* DAC software trigger register (DAC_SWTRIGR) */ -#define DAC_SWTRIGR MMIO32(DAC_BASE + 0x04) +#define DAC_SWTRIGR(dac) MMIO32((dac) + 0x04) /* DAC channel1 12-bit right-aligned data holding register (DAC_DHR12R1) */ -#define DAC_DHR12R1 MMIO32(DAC_BASE + 0x08) +#define DAC_DHR12R1(dac) MMIO32((dac) + 0x08) /* DAC channel1 12-bit left aligned data holding register (DAC_DHR12L1) */ -#define DAC_DHR12L1 MMIO32(DAC_BASE + 0x0C) +#define DAC_DHR12L1(dac) MMIO32((dac) + 0x0C) /* DAC channel1 8-bit right aligned data holding register (DAC_DHR8R1) */ -#define DAC_DHR8R1 MMIO32(DAC_BASE + 0x10) +#define DAC_DHR8R1(dac) MMIO32((dac) + 0x10) /* DAC channel2 12-bit right aligned data holding register (DAC_DHR12R2) */ -#define DAC_DHR12R2 MMIO32(DAC_BASE + 0x14) +#define DAC_DHR12R2(dac) MMIO32((dac) + 0x14) /* DAC channel2 12-bit left aligned data holding register (DAC_DHR12L2) */ -#define DAC_DHR12L2 MMIO32(DAC_BASE + 0x18) +#define DAC_DHR12L2(dac) MMIO32((dac) + 0x18) /* DAC channel2 8-bit right-aligned data holding register (DAC_DHR8R2) */ -#define DAC_DHR8R2 MMIO32(DAC_BASE + 0x1C) +#define DAC_DHR8R2(dac) MMIO32((dac) + 0x1C) /* Dual DAC 12-bit right-aligned data holding register (DAC_DHR12RD) */ -#define DAC_DHR12RD MMIO32(DAC_BASE + 0x20) +#define DAC_DHR12RD(dac) MMIO32((dac) + 0x20) /* DUAL DAC 12-bit left aligned data holding register (DAC_DHR12LD) */ -#define DAC_DHR12LD MMIO32(DAC_BASE + 0x24) +#define DAC_DHR12LD(dac) MMIO32((dac) + 0x24) /* DUAL DAC 8-bit right aligned data holding register (DAC_DHR8RD) */ -#define DAC_DHR8RD MMIO32(DAC_BASE + 0x28) +#define DAC_DHR8RD(dac) MMIO32((dac) + 0x28) /* DAC channel1 data output register (DAC_DOR1) */ -#define DAC_DOR1 MMIO32(DAC_BASE + 0x2C) +#define DAC_DOR1(dac) MMIO32((dac) + 0x2C) /* DAC channel2 data output register (DAC_DOR2) */ -#define DAC_DOR2 MMIO32(DAC_BASE + 0x30) +#define DAC_DOR2(dac) MMIO32((dac) + 0x30) /** DAC status register. * @note not available on F1 */ -#define DAC_SR MMIO32(DAC_BASE + 0x34) +#define DAC_SR(dac) MMIO32((dac) + 0x34) /* --- DAC_CR values ------------------------------------------------------- */ @@ -92,221 +95,28 @@ specific memorymap.h header before including this header file.*/ #define DAC_CR_DMAEN2 (1 << 28) /* MAMP2[3:0]: DAC channel2 mask/amplitude selector */ -/* DAC_CR_MAMP2_n: - * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 - */ #define DAC_CR_MAMP2_SHIFT 24 -/** @defgroup dac_mamp2 DAC Channel 2 LFSR Mask and Triangle Wave Amplitude -values -@ingroup dac_defines - -Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 -@{*/ -#define DAC_CR_MAMP2_1 (0x0 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_2 (0x1 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_3 (0x2 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_4 (0x3 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_5 (0x4 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_6 (0x5 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_7 (0x6 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_8 (0x7 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_9 (0x8 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_10 (0x9 << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_11 (0xA << DAC_CR_MAMP2_SHIFT) -#define DAC_CR_MAMP2_12 (0xB << DAC_CR_MAMP2_SHIFT) -/**@}*/ /* WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ -/* Legend: - * DIS: wave generation disabled - * NOISE: Noise wave generation enabled - * TRI: Triangle wave generation enabled - * - * Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) - */ #define DAC_CR_WAVE2_SHIFT 22 -#define DAC_CR_WAVE2_DIS (0x3 << DAC_CR_WAVE2_SHIFT) -/** @defgroup dac_wave2_en DAC Channel 2 Waveform Generation Enable -@ingroup dac_defines - -@li NOISE: Noise wave generation enabled -@li TRI: Triangle wave generation enabled - -@note: only used if bit TEN2 is set (DAC channel2 trigger enabled) -@{*/ -#define DAC_CR_WAVE2_NOISE (0x1 << DAC_CR_WAVE2_SHIFT) -#define DAC_CR_WAVE2_TRI (0x2 << DAC_CR_WAVE2_SHIFT) -/**@}*/ - -/* TSEL2[2:0]: DAC channel2 trigger selection */ -/* Legend: - * - * T6: Timer 6 TRGO event - * T3: Timer 3 TRGO event - * T8: Timer 8 TRGO event - * T7: Timer 7 TRGO event - * T5: Timer 5 TRGO event - * T15: Timer 15 TRGO event - * T2: Timer 2 TRGO event - * T4: Timer 4 TRGO event - * E9: External line9 - * SW: Software trigger - * - * Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) - * Note: T3 == T8; T5 == T15; not both present on one device - * Note: this is *not* valid for the STM32L1 family - */ -#define DAC_CR_TSEL2_SHIFT 19 -/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection -@ingroup dac_defines - -@li T6: Timer 6 TRGO event -@li T3: Timer 3 TRGO event -@li T8: Timer 8 TRGO event -@li T7: Timer 7 TRGO event -@li T5: Timer 5 TRGO event -@li T15: Timer 15 TRGO event -@li T2: Timer 2 TRGO event -@li T4: Timer 4 TRGO event -@li E9: External line9 -@li SW: Software trigger - -@note: Refer to the timer documentation for details of the TRGO event. -@note: T3 replaced by T8 and T5 replaced by T15 in some devices. -@note: this is not valid for the STM32L1 family. -@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) -@{*/ -#define DAC_CR_TSEL2_T6 (0x0 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T3 (0x1 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T7 (0x2 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T5 (0x3 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T15 (0x3 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T2 (0x4 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) -#define DAC_CR_TSEL2_SW (0x7 << DAC_CR_TSEL2_SHIFT) -/**@}*/ - -/* TEN2: DAC channel2 trigger enable */ -#define DAC_CR_TEN2 (1 << 18) - -/* BOFF2: DAC channel2 output buffer disable */ -#define DAC_CR_BOFF2 (1 << 17) +#define DAC_CR_WAVE2_MASK 0x3 /* EN2: DAC channel2 enable */ #define DAC_CR_EN2 (1 << 16) /* DMAUDRIE1: DAC channel1 DMA underrun interrupt enable */ /* doesn't exist in most members of the STM32F1 family */ -#define DAC_CR_DMAUDRIE1 (1 << 13) +#define DAC_CR_DMAUDRIE1 (1 << 13) /* DMAEN1: DAC channel1 DMA enable */ #define DAC_CR_DMAEN1 (1 << 12) /* MAMP1[3:0]: DAC channel1 mask/amplitude selector */ -/* DAC_CR_MAMP1_n: - * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 - */ #define DAC_CR_MAMP1_SHIFT 8 -/** @defgroup dac_mamp1 DAC Channel 1 LFSR Mask and Triangle Wave Amplitude -values -@ingroup dac_defines -Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 -@{*/ -#define DAC_CR_MAMP1_1 (0x0 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_2 (0x1 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_3 (0x2 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_4 (0x3 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_5 (0x4 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_6 (0x5 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_7 (0x6 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_8 (0x7 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_9 (0x8 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_10 (0x9 << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_11 (0xA << DAC_CR_MAMP1_SHIFT) -#define DAC_CR_MAMP1_12 (0xB << DAC_CR_MAMP1_SHIFT) -/**@}*/ - -/* WAVE1[1:0]: DAC channel1 noise/triangle wave generation enable */ -/* Legend: - * DIS: wave generation disabled - * NOISE: Noise wave generation enabled - * TRI: Triangle wave generation enabled - * - * Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled) - */ +/* WAVEn[1:0]: DAC channel1 noise/triangle wave generation enable */ #define DAC_CR_WAVE1_SHIFT 6 -#define DAC_CR_WAVE1_DIS (0x3 << DAC_CR_WAVE1_SHIFT) -/** @defgroup dac_wave1_en DAC Channel 1 Waveform Generation Enable -@ingroup dac_defines - -@li DIS: wave generation disabled -@li NOISE: Noise wave generation enabled -@li TRI: Triangle wave generation enabled - -@note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) -@{*/ -#define DAC_CR_WAVE1_NOISE (0x1 << DAC_CR_WAVE1_SHIFT) -#define DAC_CR_WAVE1_TRI (0x2 << DAC_CR_WAVE1_SHIFT) -/**@}*/ - -/* TSEL1[2:0]: DAC channel1 trigger selection */ -/* Legend: - * - * T6: Timer 6 TRGO event - * T3: Timer 3 TRGO event in connectivity line devices - * T8: Timer 8 TRGO event in high-density and XL-density devices - * T7: Timer 7 TRGO event - * T5: Timer 5 TRGO event - * T15: Timer 15 TRGO event - * T2: Timer 2 TRGO event - * T4: Timer 4 TRGO event - * E9: External line9 - * SW: Software trigger - * - * Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled) - * Note: T3 == T8; T5 == T15; not both present on one device - * Note: this is *not* valid for the STM32L1 family - */ -#define DAC_CR_TSEL1_SHIFT 3 -/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection -@ingroup dac_defines - -@li T6: Timer 6 TRGO event -@li T3: Timer 3 TRGO event -@li T8: Timer 8 TRGO event -@li T7: Timer 7 TRGO event -@li T5: Timer 5 TRGO event -@li T15: Timer 15 TRGO event -@li T2: Timer 2 TRGO event -@li T4: Timer 4 TRGO event -@li E9: External line 9 -@li SW: Software trigger - -@note: Refer to the timer documentation for details of the TRGO event. -@note: T3 replaced by T8 and T5 replaced by T15 in some devices. -@note: this is not valid for the STM32L1 family. -@note: only used if bit TEN2 is set (DAC channel 1 trigger enabled). -@{*/ -#define DAC_CR_TSEL1_T6 (0x0 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T3 (0x1 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T7 (0x2 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T5 (0x3 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T15 (0x3 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T2 (0x4 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_SW (0x7 << DAC_CR_TSEL1_SHIFT) -/**@}*/ - -/* TEN1: DAC channel1 trigger enable */ -#define DAC_CR_TEN1 (1 << 2) - -/* BOFF1: DAC channel1 output buffer disable */ -#define DAC_CR_BOFF1 (1 << 1) +#define DAC_CR_WAVE1_MASK 0x3 /* EN1: DAC channel1 enable */ #define DAC_CR_EN1 (1 << 0) @@ -322,105 +132,114 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 /* --- DAC_DHR12R1 values -------------------------------------------------- */ -#define DAC_DHR12R1_DACC1DHR_LSB (1 << 0) -#define DAC_DHR12R1_DACC1DHR_MSK (0x0FFF << 0) +#define DAC_DHR12R1_DACC1DHR_SHIFT 0 +#define DAC_DHR12R1_DACC1DHR_MASK 0xFFF /* --- DAC_DHR12L1 values -------------------------------------------------- */ -#define DAC_DHR12L1_DACC1DHR_LSB (1 << 4) -#define DAC_DHR12L1_DACC1DHR_MSK (0x0FFF << 4) +#define DAC_DHR12L1_DACC1DHR_SHIFT 4 +#define DAC_DHR12L1_DACC1DHR_MASK 0xFFF /* --- DAC_DHR8R1 values --------------------------------------------------- */ -#define DAC_DHR8R1_DACC1DHR_LSB (1 << 0) -#define DAC_DHR8R1_DACC1DHR_MSK (0x00FF << 0) +#define DAC_DHR8R1_DACC1DHR_SHIFT 0 +#define DAC_DHR8R1_DACC1DHR_MASK 0xFF /* --- DAC_DHR12R2 values -------------------------------------------------- */ -#define DAC_DHR12R2_DACC2DHR_LSB (1 << 0) -#define DAC_DHR12R2_DACC2DHR_MSK (0x00FFF << 0) +#define DAC_DHR12R2_DACC2DHR_SHIFT 0 +#define DAC_DHR12R2_DACC2DHR_MASK 0xFFF /* --- DAC_DHR12L2 values -------------------------------------------------- */ -#define DAC_DHR12L2_DACC2DHR_LSB (1 << 4) -#define DAC_DHR12L2_DACC2DHR_MSK (0x0FFF << 4) +#define DAC_DHR12L2_DACC2DHR_SHIFT 4 +#define DAC_DHR12L2_DACC2DHR_MASK 0xFFF /* --- DAC_DHR8R2 values --------------------------------------------------- */ -#define DAC_DHR8R2_DACC2DHR_LSB (1 << 0) -#define DAC_DHR8R2_DACC2DHR_MSK (0x00FF << 0) +#define DAC_DHR8R2_DACC2DHR_SHIFT 0 +#define DAC_DHR8R2_DACC2DHR_MASK 0xFF /* --- DAC_DHR12RD values -------------------------------------------------- */ -#define DAC_DHR12RD_DACC2DHR_LSB (1 << 16) -#define DAC_DHR12RD_DACC2DHR_MSK (0x0FFF << 16) -#define DAC_DHR12RD_DACC1DHR_LSB (1 << 0) -#define DAC_DHR12RD_DACC1DHR_MSK (0x0FFF << 0) +#define DAC_DHR12RD_DACC2DHR_SHIFT 16 +#define DAC_DHR12RD_DACC2DHR_MASK 0xFFF +#define DAC_DHR12RD_DACC1DHR_SHIFT 0 +#define DAC_DHR12RD_DACC1DHR_MSK 0xFFF /* --- DAC_DHR12LD values -------------------------------------------------- */ -#define DAC_DHR12LD_DACC2DHR_LSB (1 << 16) -#define DAC_DHR12LD_DACC2DHR_MSK (0x0FFF << 20) -#define DAC_DHR12LD_DACC1DHR_LSB (1 << 0) -#define DAC_DHR12LD_DACC1DHR_MSK (0x0FFF << 4) +#define DAC_DHR12LD_DACC2DHR_SHIFT 16 +#define DAC_DHR12LD_DACC2DHR_MSK 0xFFF +#define DAC_DHR12LD_DACC1DHR_SHIFT 0 +#define DAC_DHR12LD_DACC1DHR_MSK 0xFFF /* --- DAC_DHR8RD values --------------------------------------------------- */ -#define DAC_DHR8RD_DACC2DHR_LSB (1 << 8) -#define DAC_DHR8RD_DACC2DHR_MSK (0x00FF << 8) -#define DAC_DHR8RD_DACC1DHR_LSB (1 << 0) -#define DAC_DHR8RD_DACC1DHR_MSK (0x00FF << 0) +#define DAC_DHR8RD_DACC2DHR_SHIFT 8 +#define DAC_DHR8RD_DACC2DHR_MSK 0xFF +#define DAC_DHR8RD_DACC1DHR_SHIFT 0 +#define DAC_DHR8RD_DACC1DHR_MSK 0xFF /* --- DAC_DOR1 values ----------------------------------------------------- */ -#define DAC_DOR1_DACC1DOR_LSB (1 << 0) -#define DAC_DOR1_DACC1DOR_MSK (0x0FFF << 0) +#define DAC_DOR1_DACC1DOR_SHIFT 0 +#define DAC_DOR1_DACC1DOR_MSK 0xFFF /* --- DAC_DOR2 values ----------------------------------------------------- */ -#define DAC_DOR2_DACC2DOR_LSB (1 << 0) -#define DAC_DOR2_DACC2DOR_MSK (0x0FFF << 0) +#define DAC_DOR2_DACC2DOR_SHIFT 0 +#define DAC_DOR2_DACC2DOR_MSK 0xFFF + +/* --- DAC_SR values ------------------------------------------------------- */ -/** @defgroup dac_sr_values DAC_SR Values -@{*/ /** DAC channel 1 DMA underrun flag */ -#define DAC_SR_DMAUDR1 (1 << 13) +#define DAC_SR_DMAUDR1 (1 << 13) /** DAC channel 2 DMA underrun flag */ -#define DAC_SR_DMAUDR2 (1 << 29) -/**@}*/ - -/** DAC channel identifier */ -typedef enum { - CHANNEL_1, CHANNEL_2, CHANNEL_D -} data_channel; - -/** DAC data size (8/12 bits), alignment (right/left) */ -typedef enum { - RIGHT8, RIGHT12, LEFT12 -} data_align; +#define DAC_SR_DMAUDR2 (1 << 29) /* --- Function prototypes ------------------------------------------------- */ +/** DAC channel identifier */ +#define DAC_CHANNEL1 (1 << 0) +#define DAC_CHANNEL2 (1 << 1) +#define DAC_CHANNEL_BOTH (DAC_CHANNEL1 | DAC_CHANNEL2) + +/** DAC data size (8/12 bits), alignment (right/left) */ +enum dac_align { + DAC_ALIGN_RIGHT8, + DAC_ALIGN_RIGHT12, + DAC_ALIGN_LEFT12, +}; + +/* DAC waveform generation options. */ +enum dac_wave { + DAC_WAVE_DISABLE = 0, + DAC_WAVE_NOISE = 1, + DAC_WAVE_TRIANGLE = 2, + DAC_WAVE_SAWTOOTH = 3, +}; + BEGIN_DECLS -void dac_enable(data_channel dac_channel); -void dac_disable(data_channel dac_channel); -void dac_buffer_enable(data_channel dac_channel); -void dac_buffer_disable(data_channel dac_channel); -void dac_dma_enable(data_channel dac_channel); -void dac_dma_disable(data_channel dac_channel); -void dac_trigger_enable(data_channel dac_channel); -void dac_trigger_disable(data_channel dac_channel); -void dac_set_trigger_source(uint32_t dac_trig_src); -void dac_set_waveform_generation(uint32_t dac_wave_ens); -void dac_disable_waveform_generation(data_channel dac_channel); -void dac_set_waveform_characteristics(uint32_t dac_mamp); -void dac_load_data_buffer_single(uint16_t dac_data, data_align dac_data_format, - data_channel dac_channel); -void dac_load_data_buffer_dual(uint16_t dac_data1, uint16_t dac_data2, - data_align dac_data_format); -void dac_software_trigger(data_channel dac_channel); +void dac_enable(uint32_t dac, int channel); +void dac_disable(uint32_t dac, int channel); +void dac_buffer_enable(uint32_t dac, int channel); +void dac_buffer_disable(uint32_t dac, int channel); +void dac_dma_enable(uint32_t dac, int channel); +void dac_dma_disable(uint32_t dac, int channel); +void dac_trigger_enable(uint32_t dac, int channel); +void dac_trigger_disable(uint32_t dac, int channel); +void dac_set_trigger_source(uint32_t dac, uint32_t source); +void dac_set_waveform_generation(uint32_t dac, enum dac_wave wave); +void dac_disable_waveform_generation(uint32_t dac, int channel); +void dac_set_waveform_characteristics(uint32_t dac, uint8_t mamp); +void dac_load_data_buffer_single(uint32_t dac, uint16_t data, + enum dac_align align, int channel); +void dac_load_data_buffer_dual(uint32_t dac, uint16_t data1, uint16_t data2, + enum dac_align align); +void dac_software_trigger(uint32_t dac, int channel); END_DECLS diff --git a/include/libopencm3/stm32/common/dac_common_v1.h b/include/libopencm3/stm32/common/dac_common_v1.h new file mode 100644 index 00000000..38101fb0 --- /dev/null +++ b/include/libopencm3/stm32/common/dac_common_v1.h @@ -0,0 +1,136 @@ +/** @addtogroup dac_defines + +@author @htmlonly © @endhtmlonly 2020 +Ben Brewer + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA DAC.H +The order of header inclusion is important. dac.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_DAC_H +/** @endcond */ +#ifndef LIBOPENCM3_DAC_COMMON_V1_H +#define LIBOPENCM3_DAC_COMMON_V1_H + +#include + +/* --- DAC_CR values ------------------------------------------------------- */ + +/* TSEL2[2:0]: DAC channel2 trigger selection */ +#define DAC_CR_TSEL2_SHIFT 19 +/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection +@ingroup dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) +@{*/ +#define DAC_CR_TSEL2_T6 (0x0 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T3 (0x1 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T7 (0x2 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T5 (0x3 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T15 (0x3 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T2 (0x4 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_SW (0x7 << DAC_CR_TSEL2_SHIFT) +/**@}*/ + +/* TEN2: DAC channel2 trigger enable */ +#define DAC_CR_TEN2 (1 << 18) + +/* BOFF2: DAC channel2 output buffer disable */ +#define DAC_CR_BOFF2 (1 << 17) + +/* TSEL1[2:0]: DAC channel1 trigger selection */ +#define DAC_CR_TSEL1_SHIFT 3 +/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection +@ingroup dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line 9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN1 is set (DAC channel 1 trigger enabled). +@{*/ +#define DAC_CR_TSEL1_T6 (0x0 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T3 (0x1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T7 (0x2 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T5 (0x3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T15 (0x3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T2 (0x4 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_SW (0x7 << DAC_CR_TSEL1_SHIFT) +/**@}*/ + +/* TEN1: DAC channel1 trigger enable */ +#define DAC_CR_TEN1 (1 << 2) + +/* BOFF1: DAC channel1 output buffer disable */ +#define DAC_CR_BOFF1 (1 << 1) + + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +END_DECLS + +#endif +/** @cond */ +#else +#warning "dac_common_v1.h should not be included explicitly, only via dac.h" +#endif +/** @endcond */ + +/**@}*/ + diff --git a/include/libopencm3/stm32/common/dac_common_v2.h b/include/libopencm3/stm32/common/dac_common_v2.h new file mode 100644 index 00000000..cc5453eb --- /dev/null +++ b/include/libopencm3/stm32/common/dac_common_v2.h @@ -0,0 +1,570 @@ +/** @addtogroup dac_defines + +@author @htmlonly © @endhtmlonly 2020 +Ben Brewer + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA DAC.H +The order of header inclusion is important. dac.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_DAC_H +/** @endcond */ +#ifndef LIBOPENCM3_DAC_COMMON_V2_H +#define LIBOPENCM3_DAC_COMMON_V2_H + +#include + +/* --- DAC registers ------------------------------------------------------- */ + +/* DAC calibration control register (DAC_CCR) */ +#define DAC_CCR(dac) MMIO32((dac) + 0x38) + +/* DAC mode control register (DAC_MCR) */ +#define DAC_MCR(dac) MMIO32((dac) + 0x3C) + +/* DAC channel1 sample and hold sample time register (DAC_SHSR1) */ +#define DAC_SHSR1(dac) MMIO32((dac) + 0x40) + +/* DAC channel2 sample and hold sample time register (DAC_SHSR2) */ +#define DAC_SHSR2(dac) MMIO32((dac) + 0x44) + +/* DAC sample and hold time register (DAC_SHHR) */ +#define DAC_SHHR(dac) MMIO32((dac) + 0x48) + +/* DAC sample and hold refresh time register (DAC_SHRR) */ +#define DAC_SHRR(dac) MMIO32((dac) + 0x4C) + +/* DAC channel1 sawtooth register (DAC_STR1) */ +#define DAC_STR1(dac) MMIO32((dac) + 0x58) + +/* DAC channel2 sawtooth register (DAC_STR2) */ +#define DAC_STR2(dac) MMIO32((dac) + 0x5C) + +/* DAC sawtooth mode register (DAC_STMODR) */ +#define DAC_STMODR(dac) MMIO32((dac) + 0x60) + +/* --- DAC_CR values ------------------------------------------------------- */ + +/* CEN2: DAC channel2 calibration enable */ +#define DAC_CR_CEN2 (1 << 30) + +/* TSEL2[3:0]: DAC channel2 trigger selection */ +#define DAC_CR_TSEL2_SHIFT 18 +/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection +@ingroup dac_defines + +@li SW: Software trigger +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line 9 +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li HRR1: hrtim_dac_reset_trg1 +@li HRR2: hrtim_dac_reset_trg2 +@li HRR3: hrtim_dac_reset_trg3 +@li HRR4: hrtim_dac_reset_trg4 +@li HRR5: hrtim_dac_reset_trg5 +@li HRR6: hrtim_dac_reset_trg6 +@li HR2: hrtim_dac_trg2 + +@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) +@{*/ +#define DAC_CR_TSEL2_SW (0x0 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T7 (0x2 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T15 (0x3 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T2 (0x4 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T6 (0x7 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_T3 (0x8 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR1 (0x9 << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR2 (0xA << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR3 (0xB << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR4 (0xC << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR5 (0xD << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HRR6 (0xE << DAC_CR_TSEL2_SHIFT) +#define DAC_CR_TSEL2_HR2 (0xF << DAC_CR_TSEL2_SHIFT) +/**@}*/ + +/* TEN2: DAC channel2 trigger enable */ +#define DAC_CR_TEN2 (1 << 17) + +/* CEN1: DAC channel1 calibration enable */ +#define DAC_CR_CEN1 (1 << 14) + +/* TSEL1[3:0]: DAC channel1 trigger selection */ +#define DAC_CR_TSEL1_SHIFT 2 +/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection +@ingroup dac_defines + +@li CK: ck_lsi or ck_lse (selected in the RCC) +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event in connectivity line devices +@li T15: Timer 15 TRGO event in high-density and XL-density devices +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line9 +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li HRR1: hrtim_dac_reset_trg1 +@li HRR2: hrtim_dac_reset_trg2 +@li HRR3: hrtim_dac_reset_trg3 +@li HRR4: hrtim_dac_reset_trg4 +@li HRR5: hrtim_dac_reset_trg5 +@li HRR6: hrtim_dac_reset_trg6 +@li HR2: hrtim_dac_trg2 + +@note: only used if bit TEN1 is set (DAC channel 1 trigger enabled). +@{*/ +#define DAC_CR_TSEL1_CK (0x0 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T7 (0x2 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T15 (0x3 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T2 (0x4 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T6 (0x7 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_T3 (0x8 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR1 (0x9 << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR2 (0xA << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR3 (0xB << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR4 (0xC << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR5 (0xD << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HRR6 (0xE << DAC_CR_TSEL1_SHIFT) +#define DAC_CR_TSEL1_HR3 (0xF << DAC_CR_TSEL1_SHIFT) +/**@}*/ + +/* TEN1: DAC channel1 trigger enable */ +#define DAC_CR_TEN1 (1 << 1) + + +/* --- DAC_SWTRIGR values -------------------------------------------------- */ + +/* SWTRIG2: DAC channel2 software trigger B */ +#define DAC_SWTRIGR_SWTRIGB2 (1 << 17) + +/* SWTRIG1: DAC channel1 software trigger B */ +#define DAC_SWTRIGR_SWTRIGB1 (1 << 16) + + +/* --- DAC_DOR1 values ----------------------------------------------------- */ +#define DAC_DOR1_DACC1DORB_SHIFT 16 +#define DAC_DOR1_DACC1DORB_MASK 0xFFF + + +/* --- DAC_DOR2 values ----------------------------------------------------- */ +#define DAC_DOR2_DACC2DORB_SHIFT 16 +#define DAC_DOR2_DACC2DORB_MASK 0xFFF + +/* --- DAC_SR values ----------------------------------------------------- */ + +/* DAC channel2 busy writing sample time flag */ +#define DAC_SR_BWST2 (1 << 31) + +/* DAC channel2 calibration offset status */ +#define DAC_SR_CAL_FLAG2 (1 << 30) + +/** DAC channel2 DMA underrun flag */ +#define DAC_SR_DMAUDR2 (1 << 29) + +/* DAC channel2 output register status bit */ +#define DAC_SR_DORSTAT2 (1 << 28) + +/* DAC channel2 ready status bit */ +#define DAC_SR_DAC2RDY (1 << 27) + +/* DAC channel1 busy writing sample time flag */ +#define DAC_SR_BWST1 (1 << 15) + +/* DAC channel1 calibration offset status */ +#define DAC_SR_CAL_FLAG1 (1 << 14) + +/** DAC channel1 DMA underrun flag */ +#define DAC_SR_DMAUDR1 (1 << 13) + +/* DAC channel1 output register status bit */ +#define DAC_SR_DORSTAT1 (1 << 12) + +/* DAC channel1 ready status bit */ +#define DAC_SR_DAC1RDY (1 << 11) + +/* --- DAC_CCR values ----------------------------------------------------- */ + +/* DAC channel2 offset trimming value */ +#define DAC_CCR_OTRIM2_SHIFT 16 +#define DAC_CCR_OTRIM2_MASK 0x1F + +/* DAC channel1 offset trimming value */ +#define DAC_CCR_OTRIM1_SHIFT 0 +#define DAC_CCR_OTRIM1_MASK 0x1F + +/* --- DAC_MCR values ----------------------------------------------------- */ + +/* Enable signed format for DAC channel2 */ +#define DAC_MCR_SINFORMAT2 (1 << 25) + +/* DAC channel2 DMA double data mode */ +#define DAC_MCR_DMADOUBLE2 (1 << 24) + +/* MODE2[2:0]: DAC channel2 mode */ +#define DAC_MCR_MODE2_SHIFT 16 +/** @defgroup dac_mode2_sel DAC Channel 2 Mode Selection +@ingroup dac_defines + +@li E_BUFF: External pin with buffer enabled +@li EP_BUFF: External pin and on-chip peripherals with buffer +@li E: External pin without buffer +@li EP: External pin and on-chip peripherals without buffer +@li SH_E_BUFF: Sample & Hold, External pin with buffer enabled +@li SH_EP_BUFF: Sample & Hold, External pin and on-chip peripherals with buffer +@li SH_E: Sample & Hold, External pin without buffer +@li SH_EP: Sample & Hold, External pin and on-chip peripherals without buffer +@{*/ +#define DAC_MCR_MODE2_E_BUFF (0x0 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_EP_BUFF (0x1 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_E (0x2 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_EP (0x3 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SH_E_BUFF (0x4 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SH_EP_BUFF (0x5 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SH_E (0x6 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SH_EP (0x7 << DAC_MCR_MODE2_SHIFT) +/**@}*/ + +#define DAC_MCR_MODE2_PERIPHERAL (0x1 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_UNBUFFERED (0x2 << DAC_MCR_MODE2_SHIFT) +#define DAC_MCR_MODE2_SAMPLEHOLD (0x4 << DAC_MCR_MODE2_SHIFT) + +/* HFSEL[1:0]: High frequency interface mode selection */ +#define DAC_MCR_HFSEL_SHIFT 14 +#define DAC_MCR_HFSEL_MASK 0x3 +/** @defgroup dac_hfsel High frequency interface mode selection +@ingroup dac_defines + +@li DIS: High frequency mode disabled +@li AHB80: High frequency interface mode compatible to AHB>80MHz enabled +@li AHB160: High frequency interface mode compatible to AHB>160MHz enabled +@{*/ +#define DAC_MCR_HFSEL_DIS (0x0 << DAC_MCR_HFSEL_SHIFT) +#define DAC_MCR_HFSEL_AHB80 (0x1 << DAC_MCR_HFSEL_SHIFT) +#define DAC_MCR_HFSEL_AHB160 (0x2 << DAC_MCR_HFSEL_SHIFT) +/**@}*/ + +/* Enable signed format for DAC channel1 */ +#define DAC_MCR_SINFORMAT1 (1 << 9) + +/* DAC channel1 DMA double data mode */ +#define DAC_MCR_DMADOUBLE1 (1 << 8) + +/* MODE1[2:0]: DAC channel1 mode */ +#define DAC_MCR_MODE1_SHIFT 0 +/** @defgroup dac_mode1_sel DAC Channel 1 Mode Selection +@ingroup dac_defines + +@li E_BUFF: External pin with buffer enabled +@li EP_BUFF: External pin and on-chip peripherals with buffer +@li E: External pin without buffer +@li EP: External pin and on-chip peripherals without buffer +@li SH_E_BUFF: Sample & Hold, External pin with buffer enabled +@li SH_EP_BUFF: Sample & Hold, External pin and on-chip peripherals with buffer +@li SH_E: Sample & Hold, External pin without buffer +@li SH_EP: Sample & Hold , External pin and on-chip peripherals without buffer +@{*/ +#define DAC_MCR_MODE1_E_BUFF (0x0 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_EP_BUFF (0x1 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_E (0x2 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_EP (0x3 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SH_E_BUFF (0x4 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SH_EP_BUFF (0x5 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SH_E (0x6 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SH_EP (0x7 << DAC_MCR_MODE1_SHIFT) +/**@}*/ + +#define DAC_MCR_MODE1_PERIPHERAL (0x1 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_UNBUFFERED (0x2 << DAC_MCR_MODE1_SHIFT) +#define DAC_MCR_MODE1_SAMPLEHOLD (0x4 << DAC_MCR_MODE1_SHIFT) + +/* --- DAC_SHSR1 values ----------------------------------------------------- */ + +/* DAC channel1 sample time (only valid in Sample and hold mode) */ +#define DAC_SHSR1_TSAMPLE1_SHIFT 0 +#define DAC_SHSR1_TSAMPLE1_MASK 0x1FF + +/* --- DAC_SHSR2 values ----------------------------------------------------- */ + +/* DAC channel2 sample time (only valid in Sample and hold mode) */ +#define DAC_SHSR2_TSAMPLE2_SHIFT 0 +#define DAC_SHSR2_TSAMPLE2_MASK 0x1FF + +/* --- DAC_SHHR values ----------------------------------------------------- */ + +/* DAC channel2 hold time (only valid in Sample and hold mode) */ +#define DAC_SHHSR_THOLD2_SHIFT 16 +#define DAC_SHHSR_THOLD2_MASK 0x1FF + +/* DAC channel1 hold time (only valid in Sample and hold mode) */ +#define DAC_SHHSR_THOLD1_SHIFT 0 +#define DAC_SHHSR_THOLD1_MASK 0x1FF + +/* --- DAC_STR1 values ----------------------------------------------------- */ + +/* DAC channel1 sawtooth increment value (12.4 bit format) */ +#define DAC_STR1_STINCDATA1_SHIFT 16 +#define DAC_STR1_STINCDATA1_MASK 0xFFFF + +/* STDIR1: DAC channel1 sawtooth direction setting */ +#define DAC_STR1_STDIR1_SHIFT 12 +/** @defgroup dac_stdir1 DAC Channel 1 Sawtooth Direction Setting +@ingroup dac_defines + +@li DEC: Decrement +@li INC: Increment +@{*/ +#define DAC_STR1_STDIR1_DEC (0x0 << DAC_STR_STDIR1_SHIFT) +#define DAC_STR1_STDIR1_INC (0x1 << DAC_STR_STDIR1_SHIFT) +/**@}*/ + +/* DAC channel1 sawtooth reset value */ +#define DAC_STR1_STRSTDATA1_SHIFT 0 +#define DAC_STR1_STRSTDATA1_MASK 0xFFF + +/* --- DAC_STR2 values ----------------------------------------------------- */ + +/* DAC channel2 sawtooth increment value (12.4 bit format) */ +#define DAC_STR2_STINCDATA2_SHIFT 16 +#define DAC_STR2_STINCDATA2_MASK 0xFFFF + +/* STDIR1: DAC channel2 sawtooth direction setting */ +#define DAC_STR2_STDIR2_SHIFT 12 +/** @defgroup dac_stdir2 DAC Channel 2 Sawtooth Direction Setting +@ingroup dac_defines + +@li DEC: Decrement +@li INC: Increment +@{*/ +#define DAC_STR2_STDIR2_DEC (0x0 << DAC_STR_STDIR2_SHIFT) +#define DAC_STR2_STDIR2_INC (0x1 << DAC_STR_STDIR2_SHIFT) +/**@}*/ + +/* DAC channel1 sawtooth reset value */ +#define DAC_STR2_STRSTDATA2_SHIFT 0 +#define DAC_STR2_STRSTDATA2_MASK 0xFFF + +/* --- DAC_STMODR values ----------------------------------------------------- */ + +/* STINCTRIGSEL2[3:0]: DAC channel2 sawtooth increment trigger selection */ +#define DAC_STMODR_STINCTRIGSEL2_SHIFT 24 +/** @defgroup dac_sawtooth2_inc DAC Channel 2 Sawtooth Increment Trigger +@ingroup dac_defines + +@li SW: SWTRIGB2 +@li T1: dac_inc_ch2_trg1 +@li T2: dac_inc_ch2_trg2 +@li T3: dac_inc_ch2_trg3 +@li T4: dac_inc_ch2_trg4 +@li T5: dac_inc_ch2_trg5 +@li T6: dac_inc_ch2_trg6 +@li T7: dac_inc_ch2_trg7 +@li T8: dac_inc_ch2_trg8 +@li T9: dac_inc_ch2_trg9 +@li T10: dac_inc_ch2_trg10 +@li T11: dac_inc_ch2_trg11 +@li T12: dac_inc_ch2_trg12 +@li T13: dac_inc_ch2_trg13 +@li T14: dac_inc_ch2_trg14 +@li T15: dac_inc_ch2_trg15 + +@note: These bits are only available only on dual-channel DACs. +@{*/ +#define DAC_STMODR_STINCTRIGSEL2_SW (0x0 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T1 (0x1 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T2 (0x2 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T3 (0x3 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T4 (0x4 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T5 (0x5 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T6 (0x6 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T7 (0x7 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T8 (0x8 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T9 (0x9 << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T10 (0xA << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T11 (0xB << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T12 (0xC << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T13 (0xD << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T14 (0xE << DAC_STMODR_STINCTRIGSEL2_SHIFT) +#define DAC_STMODR_STINCTRIGSEL2_T15 (0xF << DAC_STMODR_STINCTRIGSEL2_SHIFT) +/**@}*/ + +/* STRSTTRIGSEL2[3:0]: DAC channel2 sawtooth reset trigger selection */ +#define DAC_STMODR_STRSTTRIGSEL2_SHIFT 16 +/** @defgroup dac_sawtooth2_rst DAC Channel 2 Sawtooth Reset Trigger +@ingroup dac_defines + +@li SW: SWTRIGB2 +@li T1: dac_ch2_trg1 +@li T2: dac_ch2_trg2 +@li T3: dac_ch2_trg3 +@li T4: dac_ch2_trg4 +@li T5: dac_ch2_trg5 +@li T6: dac_ch2_trg6 +@li T7: dac_ch2_trg7 +@li T8: dac_ch2_trg8 +@li T9: dac_ch2_trg9 +@li T10: dac_ch2_trg10 +@li T11: dac_ch2_trg11 +@li T12: dac_ch2_trg12 +@li T13: dac_ch2_trg13 +@li T14: dac_ch2_trg14 +@li T15: dac_ch2_trg15 + +@note: These bits are only available only on dual-channel DACs. +@{*/ +#define DAC_STMODR_STRSTTRIGSEL2_SW (0x0 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T1 (0x1 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T2 (0x2 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T3 (0x3 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T4 (0x4 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T5 (0x5 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T6 (0x6 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T7 (0x7 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T8 (0x8 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T9 (0x9 << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T10 (0xA << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T11 (0xB << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T12 (0xC << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T13 (0xD << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T14 (0xE << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL2_T15 (0xF << DAC_STMODR_STRSTTRIGSEL2_SHIFT) +/**@}*/ + + +/* STINCTRIGSEL1[3:0]: DAC channel1 sawtooth increment trigger selection */ +#define DAC_STMODR_STINCTRIGSEL1_SHIFT 8 +/** @defgroup dac_sawtooth2_inc DAC Channel 1 Sawtooth Increment Trigger +@ingroup dac_defines + +@li SW: SWTRIGB2 +@li T1: dac_inc_ch1_trg1 +@li T2: dac_inc_ch1_trg2 +@li T3: dac_inc_ch1_trg3 +@li T4: dac_inc_ch1_trg4 +@li T5: dac_inc_ch1_trg5 +@li T6: dac_inc_ch1_trg6 +@li T7: dac_inc_ch1_trg7 +@li T8: dac_inc_ch1_trg8 +@li T9: dac_inc_ch1_trg9 +@li T10: dac_inc_ch1_trg10 +@li T11: dac_inc_ch1_trg11 +@li T12: dac_inc_ch1_trg12 +@li T13: dac_inc_ch1_trg13 +@li T14: dac_inc_ch1_trg14 +@li T15: dac_inc_ch1_trg15 + +@note: These bits are only available only on dual-channel DACs. +@{*/ +#define DAC_STMODR_STINCTRIGSEL1_SW (0x0 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T1 (0x1 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T2 (0x2 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T3 (0x3 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T4 (0x4 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T5 (0x5 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T6 (0x6 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T7 (0x7 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T8 (0x8 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T9 (0x9 << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T10 (0xA << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T11 (0xB << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T12 (0xC << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T13 (0xD << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T14 (0xE << DAC_STMODR_STINCTRIGSEL1_SHIFT) +#define DAC_STMODR_STINCTRIGSEL1_T15 (0xF << DAC_STMODR_STINCTRIGSEL1_SHIFT) +/**@}*/ + +/* STRSTTRIGSEL1[3:0]: DAC channel1 sawtooth reset trigger selection */ +#define DAC_STMODR_STRSTTRIGSEL1_SHIFT 0 +/** @defgroup dac_sawtooth2_rst DAC Channel 1 Sawtooth Reset Trigger +@ingroup dac_defines + +@li SW: SWTRIGB2 +@li T1: dac_ch1_trg1 +@li T2: dac_ch1_trg2 +@li T3: dac_ch1_trg3 +@li T4: dac_ch1_trg4 +@li T5: dac_ch1_trg5 +@li T6: dac_ch1_trg6 +@li T7: dac_ch1_trg7 +@li T8: dac_ch1_trg8 +@li T9: dac_ch1_trg9 +@li T10: dac_ch1_trg10 +@li T11: dac_ch1_trg11 +@li T12: dac_ch1_trg12 +@li T13: dac_ch1_trg13 +@li T14: dac_ch1_trg14 +@li T15: dac_ch1_trg15 + +@note: These bits are only available only on dual-channel DACs. +@{*/ +#define DAC_STMODR_STRSTTRIGSEL1_SW (0x0 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T1 (0x1 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T2 (0x2 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T3 (0x3 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T4 (0x4 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T5 (0x5 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T6 (0x6 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T7 (0x7 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T8 (0x8 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T9 (0x9 << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T10 (0xA << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T11 (0xB << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T12 (0xC << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T13 (0xD << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T14 (0xE << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +#define DAC_STMODR_STRSTTRIGSEL1_T15 (0xF << DAC_STMODR_STRSTTRIGSEL1_SHIFT) +/**@}*/ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void dac_set_mode(uint32_t dac, uint32_t mode); +bool dac_is_ready(uint32_t dac, int channel); +void dac_wait_on_ready(uint32_t dac, int channel); +void dac_set_high_frequency_mode(uint32_t dac, uint32_t hfsel); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "dac_common_v2.h should not be included explicitly, only via dac.h" +#endif +/** @endcond */ + +/**@}*/ + diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h index 196d2e8e..a3efb12e 100644 --- a/include/libopencm3/stm32/dac.h +++ b/include/libopencm3/stm32/dac.h @@ -36,6 +36,8 @@ # include #elif defined(STM32L4) # include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include #else diff --git a/include/libopencm3/stm32/f0/dac.h b/include/libopencm3/stm32/f0/dac.h index 7f544843..74b334c5 100644 --- a/include/libopencm3/stm32/f0/dac.h +++ b/include/libopencm3/stm32/f0/dac.h @@ -33,26 +33,13 @@ #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include /*****************************************************************************/ /* Module definitions */ /*****************************************************************************/ -#define DAC DAC_BASE - -/*****************************************************************************/ -/* Register definitions */ -/*****************************************************************************/ - -#define DAC_CR MMIO32(DAC_BASE + 0x00) -#define DAC_SWTRIGR MMIO32(DAC_BASE + 0x04) -#define DAC_DHR12R1 MMIO32(DAC_BASE + 0x08) -#define DAC_DHR12L1 MMIO32(DAC_BASE + 0x0C) -#define DAC_DHR8R1 MMIO32(DAC_BASE + 0x10) -#define DAC_DOR1 MMIO32(DAC_BASE + 0x2C) -#define DAC_SR MMIO32(DAC_BASE + 0x34) - +#define DAC1 DAC_BASE /*****************************************************************************/ /* Register values */ @@ -60,10 +47,6 @@ /* DAC_CR Values ------------------------------------------------------------*/ -#define DAC_CR_DMAUDRIE1 (1 << 13) -#define DAC_CR_DMAEN1 (1 << 12) - -#define DAC_CR_TSEL1_SHIFT 3 #define DAC_CR_TSEL1 (7 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_TIM6_TRGO (0 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_TIM8_TRGO (1 << DAC_CR_TSEL1_SHIFT) @@ -74,44 +57,4 @@ #define DAC_CR_TSEL1_EXT_9 (6 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_SWTRG (7 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TEN1 (1 << 2) -#define DAC_CR_BOFF1 (1 << 1) -#define DAC_CR_EN1 (1 << 0) - -/* DAC_SWTRIGR Values -------------------------------------------------------*/ - -#define DAC_SWTRIGR_SWTRIG1 (1 << 0) - -/* DAC_DHR12R1 Values -------------------------------------------------------*/ - -#define DAC_DHR12R1_DACC1DHR 0xFFF - -/* DAC_DHR12L1 Values -------------------------------------------------------*/ - -#define DAC_DHR12L1_DACC1DHR (0xFFF << 4) - -/* DAC_DHR8R1 Values --------------------------------------------------------*/ - -#define DAC_DHR8R1_DACC1DHR 0xFF - -/* DAC_DOR1 Values ----------------------------------------------------------*/ - -#define DAC_DOR1_DACC1DOR 0xFFF - -/* DAC_SR Values ------------------------------------------------------------*/ - -#define DAC_SR_DMAUDR1 (1 << 13) - -/*****************************************************************************/ -/* API definitions */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* API Functions */ -/*****************************************************************************/ - -BEGIN_DECLS - -END_DECLS - #endif diff --git a/include/libopencm3/stm32/f1/dac.h b/include/libopencm3/stm32/f1/dac.h index 145df731..4db221be 100644 --- a/include/libopencm3/stm32/f1/dac.h +++ b/include/libopencm3/stm32/f1/dac.h @@ -31,7 +31,13 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/f2/dac.h b/include/libopencm3/stm32/f2/dac.h index 5d148a6d..60bf6924 100644 --- a/include/libopencm3/stm32/f2/dac.h +++ b/include/libopencm3/stm32/f2/dac.h @@ -31,7 +31,13 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/f3/dac.h b/include/libopencm3/stm32/f3/dac.h index aceea8c5..ab82f494 100644 --- a/include/libopencm3/stm32/f3/dac.h +++ b/include/libopencm3/stm32/f3/dac.h @@ -31,7 +31,14 @@ #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/** @defgroup dac_reg_base DAC register base addresses +@ingroup STM32xx_dac_defines +@{*/ +#define DAC1 DAC1_BASE +#define DAC2 DAC2_BASE +/**@}*/ #endif diff --git a/include/libopencm3/stm32/f3/memorymap.h b/include/libopencm3/stm32/f3/memorymap.h index 369192e3..877cd8dc 100644 --- a/include/libopencm3/stm32/f3/memorymap.h +++ b/include/libopencm3/stm32/f3/memorymap.h @@ -63,8 +63,9 @@ /* PERIPH_BASE_APB1 + 0x6800 (0x4000 6800 - 0x4000 6BFF): Reserved */ /* PERIPH_BASE_APB1 + 0x6C00 (0x4000 6C00 - 0x4000 6FFF): Reserved */ #define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) -#define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define DAC1_BASE (PERIPH_BASE_APB1 + 0x7400) #define I2C3_BASE (PERIPH_BASE_APB1 + 0x7800) +#define DAC2_BASE (PERIPH_BASE_APB1 + 0x9800) /* PERIPH_BASE_APB1 + 0x7800 (0x4000 7800 - 0x4000 7FFF): Reserved */ diff --git a/include/libopencm3/stm32/f4/dac.h b/include/libopencm3/stm32/f4/dac.h index 3a384032..c6279636 100644 --- a/include/libopencm3/stm32/f4/dac.h +++ b/include/libopencm3/stm32/f4/dac.h @@ -31,6 +31,12 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/f7/dac.h b/include/libopencm3/stm32/f7/dac.h index 1e5607e4..5f9df3f5 100644 --- a/include/libopencm3/stm32/f7/dac.h +++ b/include/libopencm3/stm32/f7/dac.h @@ -31,6 +31,12 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/g4/dac.h b/include/libopencm3/stm32/g4/dac.h new file mode 100644 index 00000000..bd1c1ce2 --- /dev/null +++ b/include/libopencm3/stm32/g4/dac.h @@ -0,0 +1,46 @@ +/** @defgroup dac_defines DAC Defines + +@brief Defined Constants and Types for the STM32G4xx DAC + +@ingroup STM32G4xx_defines + +@version 1.0.0 + +@date 3 August 2020 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC1_BASE +#define DAC2 DAC2_BASE +#define DAC3 DAC3_BASE +#define DAC4 DAC4_BASE +#define DAC5 DAC5_BASE + +#endif diff --git a/include/libopencm3/stm32/h7/dac.h b/include/libopencm3/stm32/h7/dac.h index 3106378c..834ecd77 100644 --- a/include/libopencm3/stm32/h7/dac.h +++ b/include/libopencm3/stm32/h7/dac.h @@ -31,6 +31,12 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/l1/dac.h b/include/libopencm3/stm32/l1/dac.h index 207c59d4..267b6184 100644 --- a/include/libopencm3/stm32/l1/dac.h +++ b/include/libopencm3/stm32/l1/dac.h @@ -31,7 +31,13 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/include/libopencm3/stm32/l4/dac.h b/include/libopencm3/stm32/l4/dac.h index 10b275a7..82cddded 100644 --- a/include/libopencm3/stm32/l4/dac.h +++ b/include/libopencm3/stm32/l4/dac.h @@ -31,7 +31,13 @@ LGPL License Terms @ref lgpl_license #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H -#include +#include + +/*****************************************************************************/ +/* Module definitions */ +/*****************************************************************************/ + +#define DAC1 DAC_BASE #endif diff --git a/lib/stm32/common/dac_common_all.c b/lib/stm32/common/dac_common_all.c index 0aa2277b..4e54feb9 100644 --- a/lib/stm32/common/dac_common_all.c +++ b/lib/stm32/common/dac_common_all.c @@ -1,7 +1,8 @@ /** @addtogroup dac_file DAC peripheral API * @ingroup peripheral_apis -@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies +@author @htmlonly © @endhtmlonly 2020 Ben Brewer This library supports the Digital to Analog Conversion System in the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics. @@ -63,15 +64,16 @@ sent out. gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4); rcc_periph_clock_enable(RCC_DAC); - dac_disable(CHANNEL_1); - dac_set_waveform_characteristics(DAC_CR_MAMP1_8); - dac_set_waveform_generation(DAC_CR_WAVE1_NOISE); - dac_enable(CHANNEL_1); - dac_set_trigger_source(DAC_CR_TSEL1_SW); - dac_load_data_buffer_single(0, RIGHT12, CHANNEL_1); + dac_disable(DAC1, DAC_CHANNEL1); + dac_set_waveform_characteristics(DAC1, DAC_CR_MAMP1_8); + dac_set_waveform_generation(DAC1, DAC_CR_WAVE1_NOISE); + dac_enable(DAC1, DAC_CHANNEL1); + dac_set_trigger_source(DAC1, DAC_CR_TSEL1_SW); + dac_load_data_buffer_single(DAC1, 0, DAC_ALIGN_RIGHT12, DAC_CHANNEL1); .... - dac_software_trigger(CHANNEL_1); - dac_load_data_buffer_single(value, RIGHT12, CHANNEL_1); + dac_software_trigger(DAC1, DAC_CHANNEL1); + dac_load_data_buffer_single(DAC1, value, + DAC_ALIGN_RIGHT12, DAC_CHANNEL1); @endcode @section dac_api_dma_ex Simultaneous Dual DAC with DMA. @@ -89,10 +91,10 @@ Both DAC channels are enabled, and both triggers are set to the same timer dma_set_peripheral_address(DMA2,DMA_CHANNEL3,(uint32_t) &DAC_DHR8RD); dma_enable_channel(DMA2,DMA_CHANNEL3); ... - dac_trigger_enable(CHANNEL_D); - dac_set_trigger_source(DAC_CR_TSEL1_T2 | DAC_CR_TSEL2_T2); - dac_dma_enable(CHANNEL_1); - dac_enable(CHANNEL_D); + dac_trigger_enable(DAC1, DAC_CHANNEL_BOTH); + dac_set_trigger_source(DAC1, DAC_CR_TSEL1_T2 | DAC_CR_TSEL2_T2); + dac_dma_enable(DAC1, DAC_CHANNEL1); + dac_enable(DAC1, DAC_CHANNEL_BOTH); @endcode LGPL License Terms @ref lgpl_license @@ -102,6 +104,7 @@ LGPL License Terms @ref lgpl_license * This file is part of the libopencm3 project. * * Copyright (C) 2012 Ken Sarkies + * Copyright (C) 2020 Ben Brewer * * 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 @@ -121,9 +124,6 @@ LGPL License Terms @ref lgpl_license #include -#define MASK8 0xFF -#define MASK12 0xFFF - /*---------------------------------------------------------------------------*/ /** @brief DAC Channel Enable. @@ -131,20 +131,21 @@ Enable a digital to analog converter channel. After setting this enable, the DAC requires a twakeup time typically around 10 microseconds before it actually wakes up. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_enable(data_channel dac_channel) +void dac_enable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR |= DAC_CR_EN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) |= DAC_CR_EN1; break; - case CHANNEL_2: - DAC_CR |= DAC_CR_EN2; + case DAC_CHANNEL2: + DAC_CR(dac) |= DAC_CR_EN2; break; - case CHANNEL_D: - DAC_CR |= (DAC_CR_EN1 | DAC_CR_EN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) |= (DAC_CR_EN1 | DAC_CR_EN2); break; } } @@ -154,73 +155,27 @@ void dac_enable(data_channel dac_channel) Disable a digital to analog converter channel. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_disable(data_channel dac_channel) +void dac_disable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_EN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~DAC_CR_EN1; break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_EN2; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~DAC_CR_EN2; break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_EN1 | DAC_CR_EN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_EN1 | DAC_CR_EN2); + break; + default: break; } } -/*---------------------------------------------------------------------------*/ -/** @brief DAC Channel Output Buffer Enable. - -Enable a digital to analog converter channel output drive buffer. This is an -optional amplifying buffer that provides additional drive for the output -signal. The buffer is enabled by default after a reset and needs to be -explicitly disabled if required. - -@param[in] dac_channel enum ::data_channel. -*/ - -void dac_buffer_enable(data_channel dac_channel) -{ - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_BOFF1; - break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_BOFF2; - break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_BOFF1 | DAC_CR_BOFF2); - break; - } -} -/*---------------------------------------------------------------------------*/ -/** @brief DAC Channel Output Buffer Disable. - -Disable a digital to analog converter channel output drive buffer. Disabling -this will reduce power consumption slightly and will increase the output -impedance of the DAC. The buffers are enabled by default after a reset. - -@param[in] dac_channel enum ::data_channel. -*/ - -void dac_buffer_disable(data_channel dac_channel) -{ - switch (dac_channel) { - case CHANNEL_1: - DAC_CR |= DAC_CR_BOFF1; - break; - case CHANNEL_2: - DAC_CR |= DAC_CR_BOFF2; - break; - case CHANNEL_D: - DAC_CR |= (DAC_CR_BOFF1 | DAC_CR_BOFF2); - break; - } -} /*---------------------------------------------------------------------------*/ /** @brief DAC Channel DMA Enable. @@ -228,20 +183,23 @@ Enable a digital to analog converter channel DMA mode (connected to DMA2 channel 3 for DAC channel 1 and DMA2 channel 4 for DAC channel 2). A DMA request is generated following an external trigger. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_dma_enable(data_channel dac_channel) +void dac_dma_enable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR |= DAC_CR_DMAEN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) |= DAC_CR_DMAEN1; break; - case CHANNEL_2: - DAC_CR |= DAC_CR_DMAEN2; + case DAC_CHANNEL2: + DAC_CR(dac) |= DAC_CR_DMAEN2; break; - case CHANNEL_D: - DAC_CR |= (DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) |= (DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + default: break; } } @@ -251,20 +209,23 @@ void dac_dma_enable(data_channel dac_channel) Disable a digital to analog converter channel DMA mode. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_dma_disable(data_channel dac_channel) +void dac_dma_disable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_DMAEN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~DAC_CR_DMAEN1; break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_DMAEN2; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~DAC_CR_DMAEN2; break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + default: break; } } @@ -277,20 +238,23 @@ an external trigger to initiate register transfers from the buffer register to the DAC output register, followed by a DMA transfer to the buffer register if DMA is enabled. The trigger source must also be selected. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_trigger_enable(data_channel dac_channel) +void dac_trigger_enable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR |= DAC_CR_TEN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) |= DAC_CR_TEN1; break; - case CHANNEL_2: - DAC_CR |= DAC_CR_TEN2; + case DAC_CHANNEL2: + DAC_CR(dac) |= DAC_CR_TEN2; break; - case CHANNEL_D: - DAC_CR |= (DAC_CR_TEN1 | DAC_CR_TEN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) |= (DAC_CR_TEN1 | DAC_CR_TEN2); + break; + default: break; } } @@ -300,20 +264,23 @@ void dac_trigger_enable(data_channel dac_channel) Disable a digital to analog converter channel external trigger. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_trigger_disable(data_channel dac_channel) +void dac_trigger_disable(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_TEN1; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~DAC_CR_TEN1; break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_TEN2; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~DAC_CR_TEN2; break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_TEN1 | DAC_CR_TEN2); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_TEN1 | DAC_CR_TEN2); + break; + default: break; } } @@ -324,14 +291,15 @@ void dac_trigger_disable(data_channel dac_channel) Sets the digital to analog converter trigger source, which can be taken from various timers, an external trigger or a software trigger. -@param[in] dac_trig_src uint32_t. Taken from @ref dac_trig2_sel or @ref +@param[in] dac uint32_t the base address of the DAC. +@param[in] source uint32_t. Taken from @ref dac_trig2_sel or @ref dac_trig1_sel or a logical OR of one of each of these to set both channels simultaneously. */ -void dac_set_trigger_source(uint32_t dac_trig_src) +void dac_set_trigger_source(uint32_t dac, uint32_t source) { - DAC_CR |= dac_trig_src; + DAC_CR(dac) |= source; } /*---------------------------------------------------------------------------*/ @@ -343,14 +311,14 @@ existing output values in the DAC output registers. @note The DAC trigger must be enabled for this to work. -@param[in] dac_wave_ens uint32_t. Taken from @ref dac_wave1_en or @ref +@param[in] wave enum ::dac_wave. Taken from @ref dac_wave1_en or @ref dac_wave2_en or a logical OR of one of each of these to set both channels simultaneously. */ -void dac_set_waveform_generation(uint32_t dac_wave_ens) +void dac_set_waveform_generation(uint32_t dac, enum dac_wave wave) { - DAC_CR |= dac_wave_ens; + DAC_CR(dac) |= wave; } /*---------------------------------------------------------------------------*/ @@ -358,20 +326,24 @@ void dac_set_waveform_generation(uint32_t dac_wave_ens) Disable a digital to analog converter channel superimposed waveform generation. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_disable_waveform_generation(data_channel dac_channel) +void dac_disable_waveform_generation(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_CR &= ~DAC_CR_WAVE1_DIS; + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~(DAC_CR_WAVE1_MASK << DAC_CR_WAVE1_SHIFT); break; - case CHANNEL_2: - DAC_CR &= ~DAC_CR_WAVE2_DIS; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~(DAC_CR_WAVE2_MASK << DAC_CR_WAVE2_SHIFT); break; - case CHANNEL_D: - DAC_CR &= ~(DAC_CR_WAVE1_DIS | DAC_CR_WAVE2_DIS); + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_WAVE1_MASK << DAC_CR_WAVE1_SHIFT) + | ~(DAC_CR_WAVE2_MASK << DAC_CR_WAVE2_SHIFT); + break; + default: break; } } @@ -392,13 +364,14 @@ the signal output. become read-only. @note The DAC trigger must be enabled for this to work. -@param[in] dac_mamp uint32_t. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a +@param[in] dac uint32_t the base address of the DAC. +@param[in] mamp uint8_t. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a logical OR of one of each of these to set both channels simultaneously. */ -void dac_set_waveform_characteristics(uint32_t dac_mamp) +void dac_set_waveform_characteristics(uint32_t dac, uint8_t mamp) { - DAC_CR |= dac_mamp; + DAC_CR(dac) |= mamp; } /*---------------------------------------------------------------------------*/ @@ -410,36 +383,42 @@ data to be converted on a channel. The data can be aligned as follows: @li right-aligned 12 bit data in bits 0-11 @li left aligned 12 bit data in bits 4-15 -@param[in] dac_data uint16_t with appropriate alignment. -@param[in] dac_data_format enum ::data_align. Alignment and size. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] data uint16_t with appropriate alignment. +@param[in] align enum ::dac_align. Alignment and size. +@param[in] channel uint8_t with DAC mask. */ -void dac_load_data_buffer_single(uint16_t dac_data, data_align dac_data_format, - data_channel dac_channel) +void dac_load_data_buffer_single(uint32_t dac, uint16_t data, + enum dac_align align, + int channel) { - if (dac_channel == CHANNEL_1) { - switch (dac_data_format) { - case RIGHT8: - DAC_DHR8R1 = dac_data; + if (channel == DAC_CHANNEL1) { + switch (align) { + case DAC_ALIGN_RIGHT8: + DAC_DHR8R1(dac) = data; break; - case RIGHT12: - DAC_DHR12R1 = dac_data; + case DAC_ALIGN_RIGHT12: + DAC_DHR12R1(dac) = data; break; - case LEFT12: - DAC_DHR12L1 = dac_data; + case DAC_ALIGN_LEFT12: + DAC_DHR12L1(dac) = data; + break; + default: break; } - } else if (dac_channel == CHANNEL_2) { - switch (dac_data_format) { - case RIGHT8: - DAC_DHR8R2 = dac_data; + } else if (channel == DAC_CHANNEL2) { + switch (align) { + case DAC_ALIGN_RIGHT8: + DAC_DHR8R2(dac) = data; break; - case RIGHT12: - DAC_DHR12R2 = dac_data; + case DAC_ALIGN_RIGHT12: + DAC_DHR12R2(dac) = data; break; - case LEFT12: - DAC_DHR12L2 = dac_data; + case DAC_ALIGN_LEFT12: + DAC_DHR12L2(dac) = data; + break; + default: break; } } @@ -453,26 +432,30 @@ Loads the appropriate digital to analog converter dual data register with 12 or simultaneous or independent analog output. The data in both channels are aligned identically. -@param[in] dac_data1 uint16_t for channel 1 with appropriate alignment. -@param[in] dac_data2 uint16_t for channel 2 with appropriate alignment. -@param[in] dac_data_format enum ::data_align. Right or left aligned, and 8 or +@param[in] dac uint32_t the base address of the DAC. +@param[in] data1 uint16_t for channel 1 with appropriate alignment. +@param[in] data2 uint16_t for channel 2 with appropriate alignment. +@param[in] align enum ::dac_align. Right or left aligned, and 8 or 12 bit. */ -void dac_load_data_buffer_dual(uint16_t dac_data1, uint16_t dac_data2, - data_align dac_data_format) +void dac_load_data_buffer_dual(uint32_t dac, + uint16_t data1, uint16_t data2, + enum dac_align align) { - switch (dac_data_format) { - case RIGHT8: - DAC_DHR8RD = ((dac_data1 & MASK8) | ((dac_data2 & MASK8) << 8)); + switch (align) { + case DAC_ALIGN_RIGHT8: + DAC_DHR8RD(dac) = ((data1 & 0xFF) | ((data2 & 0xFF) << 8)); break; - case RIGHT12: - DAC_DHR12RD = ((dac_data1 & MASK12) | - ((dac_data2 & MASK12) << 16)); + case DAC_ALIGN_RIGHT12: + DAC_DHR12RD(dac) = ((data1 & 0xFFF) | + ((data2 & 0xFFF) << 16)); break; - case LEFT12: - DAC_DHR12LD = ((dac_data1 & MASK12) | - ((dac_data2 & MASK12) << 16)); + case DAC_ALIGN_LEFT12: + DAC_DHR12LD(dac) = ((data1 & 0xFFF) | + ((data2 & 0xFFF) << 16)); + break; + default: break; } } @@ -483,20 +466,23 @@ void dac_load_data_buffer_dual(uint16_t dac_data1, uint16_t dac_data2, If the trigger source is set to be a software trigger, cause a trigger to occur. The trigger is cleared by hardware after conversion. -@param[in] dac_channel enum ::data_channel. +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. */ -void dac_software_trigger(data_channel dac_channel) +void dac_software_trigger(uint32_t dac, int channel) { - switch (dac_channel) { - case CHANNEL_1: - DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG1; + switch (channel) { + case DAC_CHANNEL1: + DAC_SWTRIGR(dac) |= DAC_SWTRIGR_SWTRIG1; break; - case CHANNEL_2: - DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG2; + case DAC_CHANNEL2: + DAC_SWTRIGR(dac) |= DAC_SWTRIGR_SWTRIG2; break; - case CHANNEL_D: - DAC_SWTRIGR |= (DAC_SWTRIGR_SWTRIG1 | DAC_SWTRIGR_SWTRIG2); + case DAC_CHANNEL_BOTH: + DAC_SWTRIGR(dac) |= (DAC_SWTRIGR_SWTRIG1 | DAC_SWTRIGR_SWTRIG2); + break; + default: break; } } diff --git a/lib/stm32/common/dac_common_v1.c b/lib/stm32/common/dac_common_v1.c new file mode 100644 index 00000000..13c73f06 --- /dev/null +++ b/lib/stm32/common/dac_common_v1.c @@ -0,0 +1,85 @@ +/** @addtogroup dac_file DAC peripheral API + * @ingroup peripheral_apis + +@author @htmlonly © @endhtmlonly 2020 Ben Brewer + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Enable. + +Enable a digital to analog converter channel output drive buffer. This is an +optional amplifying buffer that provides additional drive for the output +signal. The buffer is enabled by default after a reset and needs to be +explicitly disabled if required. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_buffer_enable(uint32_t dac, int channel) +{ + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) &= ~DAC_CR_BOFF1; + break; + case DAC_CHANNEL2: + DAC_CR(dac) &= ~DAC_CR_BOFF2; + break; + case DAC_CHANNEL_BOTH: + DAC_CR(dac) &= ~(DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Disable. + +Disable a digital to analog converter channel output drive buffer. Disabling +this will reduce power consumption slightly and will increase the output +impedance of the DAC. The buffers are enabled by default after a reset. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_buffer_disable(uint32_t dac, int channel) +{ + switch (channel) { + case DAC_CHANNEL1: + DAC_CR(dac) |= DAC_CR_BOFF1; + break; + case DAC_CHANNEL2: + DAC_CR(dac) |= DAC_CR_BOFF2; + break; + case DAC_CHANNEL_BOTH: + DAC_CR(dac) |= (DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} +/**@}*/ + diff --git a/lib/stm32/common/dac_common_v2.c b/lib/stm32/common/dac_common_v2.c new file mode 100644 index 00000000..c7e4699e --- /dev/null +++ b/lib/stm32/common/dac_common_v2.c @@ -0,0 +1,163 @@ +/** @addtogroup dac_file DAC peripheral API + * @ingroup peripheral_apis + +@author @htmlonly © @endhtmlonly 2020 Ben Brewer + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Ben Brewer + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Enable. + +Enable a digital to analog converter channel output drive buffer. This is an +optional amplifying buffer that provides additional drive for the output +signal. The buffer is enabled by default after a reset and needs to be +explicitly disabled if required. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_buffer_enable(uint32_t dac, int channel) +{ + switch (channel) { + case DAC_CHANNEL1: + DAC_MCR(dac) &= ~DAC_MCR_MODE1_UNBUFFERED; + break; + case DAC_CHANNEL2: + DAC_MCR(dac) &= ~DAC_MCR_MODE2_UNBUFFERED; + break; + case DAC_CHANNEL_BOTH: + DAC_MCR(dac) &= ~(DAC_MCR_MODE1_UNBUFFERED | + DAC_MCR_MODE2_UNBUFFERED); + break; + default: + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Disable. + +Disable a digital to analog converter channel output drive buffer. Disabling +this will reduce power consumption slightly and will increase the output +impedance of the DAC. The buffers are enabled by default after a reset. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_buffer_disable(uint32_t dac, int channel) +{ + switch (channel) { + case DAC_CHANNEL1: + DAC_MCR(dac) |= DAC_MCR_MODE1_UNBUFFERED; + break; + case DAC_CHANNEL2: + DAC_MCR(dac) |= DAC_MCR_MODE2_UNBUFFERED; + break; + case DAC_CHANNEL_BOTH: + DAC_MCR(dac) |= (DAC_MCR_MODE1_UNBUFFERED + | DAC_MCR_MODE2_UNBUFFERED); + break; + default: + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Mode. + +Each DAC channel can be configured in Normal mode or Sample and hold mode. The +output buffer can be enabled to allow a high drive capability. Before enabling +output buffer, the voltage offset needs to be calibrated. This calibration is +performed at the factory (loaded after reset) and can be adjusted by software +during application operation. + +@note This must be called before enabling the DAC as the settings will then +become read-only. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] mamp uint32_t. Taken from @ref dac_mode2_sel or @ref dac_mode1_sel or +a logical OR of one of each of these to set both channels simultaneously. +*/ + +void dac_set_mode(uint32_t dac, uint32_t mode) +{ + DAC_MCR(dac) |= mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Check if DAC channel is ready to receive data. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +bool dac_is_ready(uint32_t dac, int channel) +{ + uint32_t mask = 0; + if (channel & DAC_CHANNEL1) { + mask |= DAC_SR_DAC1RDY; + } + if (channel & DAC_CHANNEL2) { + mask |= DAC_SR_DAC2RDY; + } + + return (DAC_SR(dac) & mask) != 0; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Wait until DAC channel is ready to receive data. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] channel uint8_t with DAC mask. +*/ + +void dac_wait_on_ready(uint32_t dac, int channel) +{ + while (!dac_is_ready(dac, channel)); +} + +/*---------------------------------------------------------------------------*/ +/** @brief High frequency interface mode selection. + +If the AHB frequency of the DAC is above 80MHz then this value needs setting +to an appropriate value. + +@param[in] dac uint32_t the base address of the DAC. +@param[in] hfsel uint32_t with appropriate HFSEL mask. +*/ + +void dac_set_high_frequency_mode(uint32_t dac, uint32_t hfsel) +{ + uint32_t reg32 = DAC_MCR(dac); + reg32 &= ~(DAC_MCR_HFSEL_MASK << DAC_MCR_HFSEL_SHIFT); + reg32 |= hfsel; + DAC_MCR(dac) = reg32; +} +/**@}*/ + diff --git a/lib/stm32/f0/Makefile b/lib/stm32/f0/Makefile index d50f0232..ba7ce654 100644 --- a/lib/stm32/f0/Makefile +++ b/lib/stm32/f0/Makefile @@ -39,7 +39,7 @@ OBJS += can.o OBJS += comparator.o OBJS += crc_common_all.o crc_v2.o OBJS += crs_common_all.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_l1f013.o dma_common_csel.o OBJS += exti_common_all.o diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index 9371f46e..da0419c0 100755 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -37,7 +37,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v1.o OBJS += can.o OBJS += crc_common_all.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_l1f013.o OBJS += exti_common_all.o diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile index 42fb2838..9e3203c2 100644 --- a/lib/stm32/f2/Makefile +++ b/lib/stm32/f2/Makefile @@ -36,7 +36,7 @@ ARFLAGS = rcs OBJS += crc_common_all.o OBJS += crypto_common_f24.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_f24.o OBJS += exti_common_all.o diff --git a/lib/stm32/f3/Makefile b/lib/stm32/f3/Makefile index 6d6df239..f4e471cb 100644 --- a/lib/stm32/f3/Makefile +++ b/lib/stm32/f3/Makefile @@ -38,7 +38,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += can.o OBJS += crc_common_all.o crc_v2.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_l1f013.o OBJS += exti_common_all.o diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 80c88572..2fe12925 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -41,7 +41,7 @@ OBJS += adc_common_v1.o adc_common_v1_multi.o adc_common_f47.o OBJS += can.o OBJS += crc_common_all.o OBJS += crypto_common_f24.o crypto.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += dcmi_common_f47.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_f24.o diff --git a/lib/stm32/f7/Makefile b/lib/stm32/f7/Makefile index 6fc8c1f3..2e41e406 100644 --- a/lib/stm32/f7/Makefile +++ b/lib/stm32/f7/Makefile @@ -43,7 +43,7 @@ ARFLAGS = rcs OBJS += adc_common_v1.o adc_common_v1_multi.o adc_common_f47.o OBJS += can.o OBJS += crc_common_all.o crc_v2.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += dcmi_common_f47.o OBJS += desig_common_all.o desig.o OBJS += dma_common_f24.o diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index c9ac6fd6..ba2f42e9 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -37,6 +37,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += crs_common_all.o +OBJS += dac_common_all.o dac_common_v2.o OBJS += dma_common_l1f013.o OBJS += dmamux.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o diff --git a/lib/stm32/h7/Makefile b/lib/stm32/h7/Makefile index 737c2fc7..5a930d39 100644 --- a/lib/stm32/h7/Makefile +++ b/lib/stm32/h7/Makefile @@ -37,7 +37,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v2.o OBJS += exti_common_all.o OBJS += flash_common_all.o flash_common_f.o flash_common_f24.o OBJS += fmc_common_f47.o diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile index b2bf7381..55c92a89 100644 --- a/lib/stm32/l1/Makefile +++ b/lib/stm32/l1/Makefile @@ -36,7 +36,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v1.o adc_common_v1_multi.o OBJS += flash.o OBJS += crc_common_all.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig.o OBJS += dma_common_l1f013.o OBJS += exti_common_all.o diff --git a/lib/stm32/l4/Makefile b/lib/stm32/l4/Makefile index 31822b75..56a00838 100644 --- a/lib/stm32/l4/Makefile +++ b/lib/stm32/l4/Makefile @@ -39,7 +39,7 @@ OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += can.o OBJS += crc_common_all.o crc_v2.o OBJS += crs_common_all.o -OBJS += dac_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += dma_common_l1f013.o dma_common_csel.o OBJS += exti_common_all.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o From fda0282b43ecc8270017c52c39879f64869f9706 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 24 Jan 2021 21:36:21 +0000 Subject: [PATCH 063/206] stm32f0: dac: drop redundant definitions we're breaking the DAC api already, so don't bother keeping f0 specific aliases for some of the t1 triggers. --- include/libopencm3/stm32/f0/dac.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/include/libopencm3/stm32/f0/dac.h b/include/libopencm3/stm32/f0/dac.h index 74b334c5..24998510 100644 --- a/include/libopencm3/stm32/f0/dac.h +++ b/include/libopencm3/stm32/f0/dac.h @@ -41,20 +41,6 @@ #define DAC1 DAC_BASE -/*****************************************************************************/ -/* Register values */ -/*****************************************************************************/ -/* DAC_CR Values ------------------------------------------------------------*/ - -#define DAC_CR_TSEL1 (7 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_TIM6_TRGO (0 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_TIM8_TRGO (1 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_TIM7_TRGO (2 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_TIM5_TRGO (3 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_TIM2_TRGO (4 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_TIM4_TRGO (5 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_EXT_9 (6 << DAC_CR_TSEL1_SHIFT) -#define DAC_CR_TSEL1_SWTRG (7 << DAC_CR_TSEL1_SHIFT) #endif From 03cfd6b1ac540841e81b9aac01043f5a4555de9b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 24 Jan 2021 21:38:50 +0000 Subject: [PATCH 064/206] stm32: dac: doxygen grouping for register bases --- include/libopencm3/stm32/f0/dac.h | 8 +++++--- include/libopencm3/stm32/f1/dac.h | 10 ++++++---- include/libopencm3/stm32/f2/dac.h | 9 ++++++--- include/libopencm3/stm32/f3/dac.h | 4 ++++ include/libopencm3/stm32/f4/dac.h | 9 ++++++--- include/libopencm3/stm32/f7/dac.h | 9 ++++++--- include/libopencm3/stm32/g4/dac.h | 9 ++++++--- include/libopencm3/stm32/h7/dac.h | 9 ++++++--- include/libopencm3/stm32/l1/dac.h | 9 ++++++--- include/libopencm3/stm32/l4/dac.h | 9 ++++++--- 10 files changed, 57 insertions(+), 28 deletions(-) diff --git a/include/libopencm3/stm32/f0/dac.h b/include/libopencm3/stm32/f0/dac.h index 24998510..0bb2acc9 100644 --- a/include/libopencm3/stm32/f0/dac.h +++ b/include/libopencm3/stm32/f0/dac.h @@ -35,12 +35,14 @@ #include -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ +/**@{*/ +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC_BASE +/**@}*/ +/**@}*/ #endif diff --git a/include/libopencm3/stm32/f1/dac.h b/include/libopencm3/stm32/f1/dac.h index 4db221be..2b62709d 100644 --- a/include/libopencm3/stm32/f1/dac.h +++ b/include/libopencm3/stm32/f1/dac.h @@ -32,12 +32,14 @@ LGPL License Terms @ref lgpl_license #define LIBOPENCM3_DAC_H #include +/**@{*/ -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ - +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC_BASE +/**@}*/ + +/**@}*/ #endif diff --git a/include/libopencm3/stm32/f2/dac.h b/include/libopencm3/stm32/f2/dac.h index 60bf6924..50c71143 100644 --- a/include/libopencm3/stm32/f2/dac.h +++ b/include/libopencm3/stm32/f2/dac.h @@ -33,11 +33,14 @@ LGPL License Terms @ref lgpl_license #include -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ +/**@{*/ +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC_BASE +/**@}*/ + +/**@}*/ #endif diff --git a/include/libopencm3/stm32/f3/dac.h b/include/libopencm3/stm32/f3/dac.h index ab82f494..04dcfc80 100644 --- a/include/libopencm3/stm32/f3/dac.h +++ b/include/libopencm3/stm32/f3/dac.h @@ -33,6 +33,8 @@ #include +/**@{*/ + /** @defgroup dac_reg_base DAC register base addresses @ingroup STM32xx_dac_defines @{*/ @@ -40,5 +42,7 @@ #define DAC2 DAC2_BASE /**@}*/ +/**@}*/ + #endif diff --git a/include/libopencm3/stm32/f4/dac.h b/include/libopencm3/stm32/f4/dac.h index c6279636..291bfbae 100644 --- a/include/libopencm3/stm32/f4/dac.h +++ b/include/libopencm3/stm32/f4/dac.h @@ -33,10 +33,13 @@ LGPL License Terms @ref lgpl_license #include -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ +/**@{*/ +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC_BASE +/**@}*/ + +/**@}*/ #endif diff --git a/include/libopencm3/stm32/f7/dac.h b/include/libopencm3/stm32/f7/dac.h index 5f9df3f5..8628c61e 100644 --- a/include/libopencm3/stm32/f7/dac.h +++ b/include/libopencm3/stm32/f7/dac.h @@ -33,10 +33,13 @@ LGPL License Terms @ref lgpl_license #include -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ +/**@{*/ +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC_BASE +/**@}*/ + +/**@}*/ #endif diff --git a/include/libopencm3/stm32/g4/dac.h b/include/libopencm3/stm32/g4/dac.h index bd1c1ce2..b0a5d4a0 100644 --- a/include/libopencm3/stm32/g4/dac.h +++ b/include/libopencm3/stm32/g4/dac.h @@ -33,14 +33,17 @@ LGPL License Terms @ref lgpl_license #include -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ +/**@{*/ +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC1_BASE #define DAC2 DAC2_BASE #define DAC3 DAC3_BASE #define DAC4 DAC4_BASE #define DAC5 DAC5_BASE +/**@}*/ + +/**@}*/ #endif diff --git a/include/libopencm3/stm32/h7/dac.h b/include/libopencm3/stm32/h7/dac.h index 834ecd77..54ec1f02 100644 --- a/include/libopencm3/stm32/h7/dac.h +++ b/include/libopencm3/stm32/h7/dac.h @@ -33,10 +33,13 @@ LGPL License Terms @ref lgpl_license #include -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ +/**@{*/ +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC_BASE +/**@}*/ + +/**@}*/ #endif diff --git a/include/libopencm3/stm32/l1/dac.h b/include/libopencm3/stm32/l1/dac.h index 267b6184..0601c0f6 100644 --- a/include/libopencm3/stm32/l1/dac.h +++ b/include/libopencm3/stm32/l1/dac.h @@ -33,11 +33,14 @@ LGPL License Terms @ref lgpl_license #include -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ +/**@{*/ +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC_BASE +/**@}*/ + +/**@}*/ #endif diff --git a/include/libopencm3/stm32/l4/dac.h b/include/libopencm3/stm32/l4/dac.h index 82cddded..17f6833f 100644 --- a/include/libopencm3/stm32/l4/dac.h +++ b/include/libopencm3/stm32/l4/dac.h @@ -33,11 +33,14 @@ LGPL License Terms @ref lgpl_license #include -/*****************************************************************************/ -/* Module definitions */ -/*****************************************************************************/ +/**@{*/ +/** @defgroup dac_reg_base DAC register base addresses +@{*/ #define DAC1 DAC_BASE +/**@}*/ + +/**@}*/ #endif From 4fe5103851f2290ea97a8db7de00045d06ccae77 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 24 Jan 2021 22:08:20 +0000 Subject: [PATCH 065/206] stm32: dac: doxygenize the registers and values Not 100% complete, but far closer, mostly just tagging the existing information properly to get it included. --- .../libopencm3/stm32/common/dac_common_all.h | 93 ++++++++++++------- .../libopencm3/stm32/common/dac_common_v1.h | 7 +- .../libopencm3/stm32/common/dac_common_v2.h | 87 ++++++++++------- 3 files changed, 116 insertions(+), 71 deletions(-) diff --git a/include/libopencm3/stm32/common/dac_common_all.h b/include/libopencm3/stm32/common/dac_common_all.h index fc3ca40c..c93b9dbc 100644 --- a/include/libopencm3/stm32/common/dac_common_all.h +++ b/include/libopencm3/stm32/common/dac_common_all.h @@ -39,45 +39,46 @@ specific memorymap.h header before including this header file.*/ #ifndef LIBOPENCM3_DAC_COMMON_ALL_H #define LIBOPENCM3_DAC_COMMON_ALL_H -/* --- DAC registers ------------------------------------------------------- */ +/**@defgroup dac_registers DAC Registers + @{*/ -/* DAC control register (DAC_CR) */ +/** DAC control register (DAC_CR) */ #define DAC_CR(dac) MMIO32((dac) + 0x00) -/* DAC software trigger register (DAC_SWTRIGR) */ +/** DAC software trigger register (DAC_SWTRIGR) */ #define DAC_SWTRIGR(dac) MMIO32((dac) + 0x04) -/* DAC channel1 12-bit right-aligned data holding register (DAC_DHR12R1) */ +/** DAC channel1 12-bit right-aligned data holding register (DAC_DHR12R1) */ #define DAC_DHR12R1(dac) MMIO32((dac) + 0x08) -/* DAC channel1 12-bit left aligned data holding register (DAC_DHR12L1) */ +/** DAC channel1 12-bit left aligned data holding register (DAC_DHR12L1) */ #define DAC_DHR12L1(dac) MMIO32((dac) + 0x0C) -/* DAC channel1 8-bit right aligned data holding register (DAC_DHR8R1) */ +/** DAC channel1 8-bit right aligned data holding register (DAC_DHR8R1) */ #define DAC_DHR8R1(dac) MMIO32((dac) + 0x10) -/* DAC channel2 12-bit right aligned data holding register (DAC_DHR12R2) */ +/** DAC channel2 12-bit right aligned data holding register (DAC_DHR12R2) */ #define DAC_DHR12R2(dac) MMIO32((dac) + 0x14) -/* DAC channel2 12-bit left aligned data holding register (DAC_DHR12L2) */ +/** DAC channel2 12-bit left aligned data holding register (DAC_DHR12L2) */ #define DAC_DHR12L2(dac) MMIO32((dac) + 0x18) -/* DAC channel2 8-bit right-aligned data holding register (DAC_DHR8R2) */ +/** DAC channel2 8-bit right-aligned data holding register (DAC_DHR8R2) */ #define DAC_DHR8R2(dac) MMIO32((dac) + 0x1C) -/* Dual DAC 12-bit right-aligned data holding register (DAC_DHR12RD) */ +/** Dual DAC 12-bit right-aligned data holding register (DAC_DHR12RD) */ #define DAC_DHR12RD(dac) MMIO32((dac) + 0x20) -/* DUAL DAC 12-bit left aligned data holding register (DAC_DHR12LD) */ +/** DUAL DAC 12-bit left aligned data holding register (DAC_DHR12LD) */ #define DAC_DHR12LD(dac) MMIO32((dac) + 0x24) -/* DUAL DAC 8-bit right aligned data holding register (DAC_DHR8RD) */ +/** DUAL DAC 8-bit right aligned data holding register (DAC_DHR8RD) */ #define DAC_DHR8RD(dac) MMIO32((dac) + 0x28) -/* DAC channel1 data output register (DAC_DOR1) */ +/** DAC channel1 data output register (DAC_DOR1) */ #define DAC_DOR1(dac) MMIO32((dac) + 0x2C) -/* DAC channel2 data output register (DAC_DOR2) */ +/** DAC channel2 data output register (DAC_DOR2) */ #define DAC_DOR2(dac) MMIO32((dac) + 0x30) /** DAC status register. @@ -85,52 +86,63 @@ specific memorymap.h header before including this header file.*/ */ #define DAC_SR(dac) MMIO32((dac) + 0x34) -/* --- DAC_CR values ------------------------------------------------------- */ +/**@}*/ -/* DMAUDRIE2: DAC channel2 DMA underrun interrupt enable */ -/* doesn't exist in most members of the STM32F1 family */ +/** @defgroup dac_cr_values DAC_CR values + * @{ + */ + +/** DMAUDRIE2: DAC channel2 DMA underrun interrupt enable + * @note doesn't exist in most members of the STM32F1 family + */ #define DAC_CR_DMAUDRIE2 (1 << 29) -/* DMAEN2: DAC channel2 DMA enable */ +/** DMAEN2: DAC channel2 DMA enable */ #define DAC_CR_DMAEN2 (1 << 28) -/* MAMP2[3:0]: DAC channel2 mask/amplitude selector */ +/** MAMP2[3:0]: DAC channel2 mask/amplitude selector */ #define DAC_CR_MAMP2_SHIFT 24 -/* WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ +/** WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ #define DAC_CR_WAVE2_SHIFT 22 #define DAC_CR_WAVE2_MASK 0x3 -/* EN2: DAC channel2 enable */ +/** EN2: DAC channel2 enable */ #define DAC_CR_EN2 (1 << 16) -/* DMAUDRIE1: DAC channel1 DMA underrun interrupt enable */ -/* doesn't exist in most members of the STM32F1 family */ +/** DMAUDRIE1: DAC channel1 DMA underrun interrupt enable + * @note doesn't exist in most members of the STM32F1 family + */ #define DAC_CR_DMAUDRIE1 (1 << 13) -/* DMAEN1: DAC channel1 DMA enable */ +/** DMAEN1: DAC channel1 DMA enable */ #define DAC_CR_DMAEN1 (1 << 12) -/* MAMP1[3:0]: DAC channel1 mask/amplitude selector */ +/** MAMP1[3:0]: DAC channel1 mask/amplitude selector */ #define DAC_CR_MAMP1_SHIFT 8 -/* WAVEn[1:0]: DAC channel1 noise/triangle wave generation enable */ +/** WAVEn[1:0]: DAC channel1 noise/triangle wave generation enable */ #define DAC_CR_WAVE1_SHIFT 6 #define DAC_CR_WAVE1_MASK 0x3 -/* EN1: DAC channel1 enable */ +/** EN1: DAC channel1 enable */ #define DAC_CR_EN1 (1 << 0) +/**@}*/ - -/* --- DAC_SWTRIGR values -------------------------------------------------- */ - -/* SWTRIG2: DAC channel2 software trigger */ +/**@defgroup dac_swtrigr_values DAC_SWTRIGR Values + * @{ + */ +/** SWTRIG2: DAC channel2 software trigger */ #define DAC_SWTRIGR_SWTRIG2 (1 << 1) -/* SWTRIG1: DAC channel1 software trigger */ +/** SWTRIG1: DAC channel1 software trigger */ #define DAC_SWTRIGR_SWTRIG1 (1 << 0) +/**@}*/ +/**@defgroup dac_dhrxxx_values DAC_DHRxxx Values + * @{ + */ /* --- DAC_DHR12R1 values -------------------------------------------------- */ #define DAC_DHR12R1_DACC1DHR_SHIFT 0 #define DAC_DHR12R1_DACC1DHR_MASK 0xFFF @@ -180,8 +192,12 @@ specific memorymap.h header before including this header file.*/ #define DAC_DHR8RD_DACC2DHR_MSK 0xFF #define DAC_DHR8RD_DACC1DHR_SHIFT 0 #define DAC_DHR8RD_DACC1DHR_MSK 0xFF +/**@}*/ +/**@defgroup dac_dorx_values DAC_DORx Values + * @{ + */ /* --- DAC_DOR1 values ----------------------------------------------------- */ #define DAC_DOR1_DACC1DOR_SHIFT 0 #define DAC_DOR1_DACC1DOR_MSK 0xFFF @@ -191,20 +207,27 @@ specific memorymap.h header before including this header file.*/ #define DAC_DOR2_DACC2DOR_SHIFT 0 #define DAC_DOR2_DACC2DOR_MSK 0xFFF -/* --- DAC_SR values ------------------------------------------------------- */ +/**@}*/ +/**@defgroup dac_sr_values DAC_SR Values + * @{ + */ /** DAC channel 1 DMA underrun flag */ #define DAC_SR_DMAUDR1 (1 << 13) /** DAC channel 2 DMA underrun flag */ #define DAC_SR_DMAUDR2 (1 << 29) +/**@}*/ /* --- Function prototypes ------------------------------------------------- */ -/** DAC channel identifier */ +/** @defgroup dac_channel_id DAC Channel Identifier + * @{ + */ #define DAC_CHANNEL1 (1 << 0) #define DAC_CHANNEL2 (1 << 1) #define DAC_CHANNEL_BOTH (DAC_CHANNEL1 | DAC_CHANNEL2) +/**@}*/ /** DAC data size (8/12 bits), alignment (right/left) */ enum dac_align { @@ -213,7 +236,7 @@ enum dac_align { DAC_ALIGN_LEFT12, }; -/* DAC waveform generation options. */ +/** DAC waveform generation options. */ enum dac_wave { DAC_WAVE_DISABLE = 0, DAC_WAVE_NOISE = 1, diff --git a/include/libopencm3/stm32/common/dac_common_v1.h b/include/libopencm3/stm32/common/dac_common_v1.h index 38101fb0..c915a5c6 100644 --- a/include/libopencm3/stm32/common/dac_common_v1.h +++ b/include/libopencm3/stm32/common/dac_common_v1.h @@ -38,9 +38,11 @@ specific memorymap.h header before including this header file.*/ #include -/* --- DAC_CR values ------------------------------------------------------- */ +/**@addtogroup dac_cr_values + * @{ + */ -/* TSEL2[2:0]: DAC channel2 trigger selection */ +/** TSEL2[2:0]: DAC channel2 trigger selection */ #define DAC_CR_TSEL2_SHIFT 19 /** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection @ingroup dac_defines @@ -118,6 +120,7 @@ specific memorymap.h header before including this header file.*/ /* BOFF1: DAC channel1 output buffer disable */ #define DAC_CR_BOFF1 (1 << 1) +/**@}*/ /* --- Function prototypes ------------------------------------------------- */ diff --git a/include/libopencm3/stm32/common/dac_common_v2.h b/include/libopencm3/stm32/common/dac_common_v2.h index cc5453eb..ff3f95f1 100644 --- a/include/libopencm3/stm32/common/dac_common_v2.h +++ b/include/libopencm3/stm32/common/dac_common_v2.h @@ -38,38 +38,42 @@ specific memorymap.h header before including this header file.*/ #include -/* --- DAC registers ------------------------------------------------------- */ +/**@addtogroup dac_registers + @{*/ -/* DAC calibration control register (DAC_CCR) */ +/** DAC calibration control register (DAC_CCR) */ #define DAC_CCR(dac) MMIO32((dac) + 0x38) -/* DAC mode control register (DAC_MCR) */ +/** DAC mode control register (DAC_MCR) */ #define DAC_MCR(dac) MMIO32((dac) + 0x3C) -/* DAC channel1 sample and hold sample time register (DAC_SHSR1) */ +/** DAC channel1 sample and hold sample time register (DAC_SHSR1) */ #define DAC_SHSR1(dac) MMIO32((dac) + 0x40) -/* DAC channel2 sample and hold sample time register (DAC_SHSR2) */ +/** DAC channel2 sample and hold sample time register (DAC_SHSR2) */ #define DAC_SHSR2(dac) MMIO32((dac) + 0x44) -/* DAC sample and hold time register (DAC_SHHR) */ +/** DAC sample and hold time register (DAC_SHHR) */ #define DAC_SHHR(dac) MMIO32((dac) + 0x48) -/* DAC sample and hold refresh time register (DAC_SHRR) */ +/** DAC sample and hold refresh time register (DAC_SHRR) */ #define DAC_SHRR(dac) MMIO32((dac) + 0x4C) -/* DAC channel1 sawtooth register (DAC_STR1) */ +/** DAC channel1 sawtooth register (DAC_STR1) */ #define DAC_STR1(dac) MMIO32((dac) + 0x58) -/* DAC channel2 sawtooth register (DAC_STR2) */ +/** DAC channel2 sawtooth register (DAC_STR2) */ #define DAC_STR2(dac) MMIO32((dac) + 0x5C) -/* DAC sawtooth mode register (DAC_STMODR) */ +/** DAC sawtooth mode register (DAC_STMODR) */ #define DAC_STMODR(dac) MMIO32((dac) + 0x60) +/**@}*/ -/* --- DAC_CR values ------------------------------------------------------- */ +/**@addtogroup dac_cr_values + * @{ + */ -/* CEN2: DAC channel2 calibration enable */ +/** CEN2: DAC channel2 calibration enable */ #define DAC_CR_CEN2 (1 << 30) /* TSEL2[3:0]: DAC channel2 trigger selection */ @@ -162,19 +166,24 @@ specific memorymap.h header before including this header file.*/ #define DAC_CR_TSEL1_HR3 (0xF << DAC_CR_TSEL1_SHIFT) /**@}*/ -/* TEN1: DAC channel1 trigger enable */ +/** TEN1: DAC channel1 trigger enable */ #define DAC_CR_TEN1 (1 << 1) +/**@}*/ -/* --- DAC_SWTRIGR values -------------------------------------------------- */ - -/* SWTRIG2: DAC channel2 software trigger B */ +/** @addtogroup dac_swtrigr_values + * @{ + */ +/** SWTRIG2: DAC channel2 software trigger B */ #define DAC_SWTRIGR_SWTRIGB2 (1 << 17) -/* SWTRIG1: DAC channel1 software trigger B */ +/** SWTRIG1: DAC channel1 software trigger B */ #define DAC_SWTRIGR_SWTRIGB1 (1 << 16) +/**@}*/ - +/** @addtogroup dac_dorx_values + * @{ + */ /* --- DAC_DOR1 values ----------------------------------------------------- */ #define DAC_DOR1_DACC1DORB_SHIFT 16 #define DAC_DOR1_DACC1DORB_MASK 0xFFF @@ -183,41 +192,46 @@ specific memorymap.h header before including this header file.*/ /* --- DAC_DOR2 values ----------------------------------------------------- */ #define DAC_DOR2_DACC2DORB_SHIFT 16 #define DAC_DOR2_DACC2DORB_MASK 0xFFF +/**@}*/ -/* --- DAC_SR values ----------------------------------------------------- */ - -/* DAC channel2 busy writing sample time flag */ +/** @addtogroup dac_sr_values + * @{ + */ +/** DAC channel2 busy writing sample time flag */ #define DAC_SR_BWST2 (1 << 31) -/* DAC channel2 calibration offset status */ +/** DAC channel2 calibration offset status */ #define DAC_SR_CAL_FLAG2 (1 << 30) /** DAC channel2 DMA underrun flag */ #define DAC_SR_DMAUDR2 (1 << 29) -/* DAC channel2 output register status bit */ +/** DAC channel2 output register status bit */ #define DAC_SR_DORSTAT2 (1 << 28) -/* DAC channel2 ready status bit */ +/** DAC channel2 ready status bit */ #define DAC_SR_DAC2RDY (1 << 27) -/* DAC channel1 busy writing sample time flag */ +/** DAC channel1 busy writing sample time flag */ #define DAC_SR_BWST1 (1 << 15) -/* DAC channel1 calibration offset status */ +/** DAC channel1 calibration offset status */ #define DAC_SR_CAL_FLAG1 (1 << 14) /** DAC channel1 DMA underrun flag */ #define DAC_SR_DMAUDR1 (1 << 13) -/* DAC channel1 output register status bit */ +/** DAC channel1 output register status bit */ #define DAC_SR_DORSTAT1 (1 << 12) -/* DAC channel1 ready status bit */ +/** DAC channel1 ready status bit */ #define DAC_SR_DAC1RDY (1 << 11) +/**@}*/ -/* --- DAC_CCR values ----------------------------------------------------- */ +/**@defgroup dac_ccr_values DAC_CCR values + * @{ + */ /* DAC channel2 offset trimming value */ #define DAC_CCR_OTRIM2_SHIFT 16 #define DAC_CCR_OTRIM2_MASK 0x1F @@ -225,16 +239,20 @@ specific memorymap.h header before including this header file.*/ /* DAC channel1 offset trimming value */ #define DAC_CCR_OTRIM1_SHIFT 0 #define DAC_CCR_OTRIM1_MASK 0x1F +/**@}*/ /* --- DAC_MCR values ----------------------------------------------------- */ -/* Enable signed format for DAC channel2 */ +/**@defgroup dac_mcr_values DAC_MCR values + * @{ + */ +/** Enable signed format for DAC channel2 */ #define DAC_MCR_SINFORMAT2 (1 << 25) -/* DAC channel2 DMA double data mode */ +/** DAC channel2 DMA double data mode */ #define DAC_MCR_DMADOUBLE2 (1 << 24) -/* MODE2[2:0]: DAC channel2 mode */ +/** MODE2[2:0]: DAC channel2 mode */ #define DAC_MCR_MODE2_SHIFT 16 /** @defgroup dac_mode2_sel DAC Channel 2 Mode Selection @ingroup dac_defines @@ -277,10 +295,10 @@ specific memorymap.h header before including this header file.*/ #define DAC_MCR_HFSEL_AHB160 (0x2 << DAC_MCR_HFSEL_SHIFT) /**@}*/ -/* Enable signed format for DAC channel1 */ +/** Enable signed format for DAC channel1 */ #define DAC_MCR_SINFORMAT1 (1 << 9) -/* DAC channel1 DMA double data mode */ +/** DAC channel1 DMA double data mode */ #define DAC_MCR_DMADOUBLE1 (1 << 8) /* MODE1[2:0]: DAC channel1 mode */ @@ -310,6 +328,7 @@ specific memorymap.h header before including this header file.*/ #define DAC_MCR_MODE1_PERIPHERAL (0x1 << DAC_MCR_MODE1_SHIFT) #define DAC_MCR_MODE1_UNBUFFERED (0x2 << DAC_MCR_MODE1_SHIFT) #define DAC_MCR_MODE1_SAMPLEHOLD (0x4 << DAC_MCR_MODE1_SHIFT) +/**@}*/ /* --- DAC_SHSR1 values ----------------------------------------------------- */ From 3eb94bb335e4ee2ad24e2fa77166510d706e8782 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 24 Jan 2021 22:10:05 +0000 Subject: [PATCH 066/206] stm32: dac: document: whitespace for legibility --- lib/stm32/common/dac_common_all.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/stm32/common/dac_common_all.c b/lib/stm32/common/dac_common_all.c index 4e54feb9..c4665fcf 100644 --- a/lib/stm32/common/dac_common_all.c +++ b/lib/stm32/common/dac_common_all.c @@ -85,11 +85,11 @@ Both DAC channels are enabled, and both triggers are set to the same timer 1 only to ensure that only one DMA request is generated. @code - dma_set_memory_size(DMA2,DMA_CHANNEL3,DMA_CCR_MSIZE_16BIT); - dma_set_peripheral_size(DMA2,DMA_CHANNEL3,DMA_CCR_PSIZE_16BIT); - dma_set_read_from_memory(DMA2,DMA_CHANNEL3); - dma_set_peripheral_address(DMA2,DMA_CHANNEL3,(uint32_t) &DAC_DHR8RD); - dma_enable_channel(DMA2,DMA_CHANNEL3); + dma_set_memory_size(DMA2, DMA_CHANNEL3, DMA_CCR_MSIZE_16BIT); + dma_set_peripheral_size(DMA2, DMA_CHANNEL3, DMA_CCR_PSIZE_16BIT); + dma_set_read_from_memory(DMA2, DMA_CHANNEL3); + dma_set_peripheral_address(DMA2, DMA_CHANNEL3,(uint32_t) &DAC_DHR8RD); + dma_enable_channel(DMA2, DMA_CHANNEL3); ... dac_trigger_enable(DAC1, DAC_CHANNEL_BOTH); dac_set_trigger_source(DAC1, DAC_CR_TSEL1_T2 | DAC_CR_TSEL2_T2); From 59fdb61bf22e215684870b6b52914e1f6afb13fd Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 24 Jan 2021 22:23:25 +0000 Subject: [PATCH 067/206] stm32: dac: doc: link data types And also drop pointless whitespace and divider markers --- lib/stm32/common/dac_common_all.c | 71 ++++++++++--------------------- lib/stm32/common/dac_common_v1.c | 12 ++---- lib/stm32/common/dac_common_v2.c | 32 +++++--------- 3 files changed, 37 insertions(+), 78 deletions(-) diff --git a/lib/stm32/common/dac_common_all.c b/lib/stm32/common/dac_common_all.c index c4665fcf..bc26ef74 100644 --- a/lib/stm32/common/dac_common_all.c +++ b/lib/stm32/common/dac_common_all.c @@ -1,5 +1,6 @@ /** @addtogroup dac_file DAC peripheral API * @ingroup peripheral_apis + * @brief Digital to Analog Converter @author @htmlonly © @endhtmlonly 2012 Ken Sarkies @author @htmlonly © @endhtmlonly 2020 Ben Brewer @@ -124,17 +125,15 @@ LGPL License Terms @ref lgpl_license #include -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Enable. Enable a digital to analog converter channel. After setting this enable, the DAC requires a twakeup time typically around 10 microseconds before it actually wakes up. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_enable(uint32_t dac, int channel) { switch (channel) { @@ -150,15 +149,13 @@ void dac_enable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Disable. Disable a digital to analog converter channel. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC @ref dac_reg_base +@param[in] channel with DAC mask @ref dac_channel_id */ - void dac_disable(uint32_t dac, int channel) { switch (channel) { @@ -176,17 +173,15 @@ void dac_disable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel DMA Enable. Enable a digital to analog converter channel DMA mode (connected to DMA2 channel 3 for DAC channel 1 and DMA2 channel 4 for DAC channel 2). A DMA request is generated following an external trigger. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_dma_enable(uint32_t dac, int channel) { switch (channel) { @@ -204,15 +199,13 @@ void dac_dma_enable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel DMA Disable. Disable a digital to analog converter channel DMA mode. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_dma_disable(uint32_t dac, int channel) { switch (channel) { @@ -230,7 +223,6 @@ void dac_dma_disable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Trigger Enable. Enable a digital to analog converter channel external trigger mode. This allows @@ -238,10 +230,9 @@ an external trigger to initiate register transfers from the buffer register to the DAC output register, followed by a DMA transfer to the buffer register if DMA is enabled. The trigger source must also be selected. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_trigger_enable(uint32_t dac, int channel) { switch (channel) { @@ -259,15 +250,13 @@ void dac_trigger_enable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Trigger Disable. Disable a digital to analog converter channel external trigger. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_trigger_disable(uint32_t dac, int channel) { switch (channel) { @@ -285,24 +274,21 @@ void dac_trigger_disable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief Set DAC Channel Trigger Source. Sets the digital to analog converter trigger source, which can be taken from various timers, an external trigger or a software trigger. -@param[in] dac uint32_t the base address of the DAC. -@param[in] source uint32_t. Taken from @ref dac_trig2_sel or @ref +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] source Taken from @ref dac_trig2_sel or @ref dac_trig1_sel or a logical OR of one of each of these to set both channels simultaneously. */ - void dac_set_trigger_source(uint32_t dac, uint32_t source) { DAC_CR(dac) |= source; } -/*---------------------------------------------------------------------------*/ /** @brief Enable and Set DAC Channel Waveform Generation. Enable the digital to analog converter waveform generation as either @@ -310,26 +296,23 @@ pseudo-random noise or triangular wave. These signals are superimposed on existing output values in the DAC output registers. @note The DAC trigger must be enabled for this to work. - +@param[in] dac the base address of the DAC. @ref dac_reg_base @param[in] wave enum ::dac_wave. Taken from @ref dac_wave1_en or @ref dac_wave2_en or a logical OR of one of each of these to set both channels simultaneously. */ - void dac_set_waveform_generation(uint32_t dac, enum dac_wave wave) { DAC_CR(dac) |= wave; } -/*---------------------------------------------------------------------------*/ /** @brief Disable DAC Channel Waveform Generation. Disable a digital to analog converter channel superimposed waveform generation. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_disable_waveform_generation(uint32_t dac, int channel) { switch (channel) { @@ -348,7 +331,6 @@ void dac_disable_waveform_generation(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief Set DAC Channel LFSR Mask or Triangle Wave Amplitude. Sets the digital to analog converter superimposed waveform generation @@ -364,17 +346,15 @@ the signal output. become read-only. @note The DAC trigger must be enabled for this to work. -@param[in] dac uint32_t the base address of the DAC. +@param[in] dac the base address of the DAC. @ref dac_reg_base @param[in] mamp uint8_t. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a logical OR of one of each of these to set both channels simultaneously. */ - void dac_set_waveform_characteristics(uint32_t dac, uint8_t mamp) { DAC_CR(dac) |= mamp; } -/*---------------------------------------------------------------------------*/ /** @brief Load DAC Data Register. Loads the appropriate digital to analog converter data register with 12 or 8 bit @@ -383,12 +363,11 @@ data to be converted on a channel. The data can be aligned as follows: @li right-aligned 12 bit data in bits 0-11 @li left aligned 12 bit data in bits 4-15 -@param[in] dac uint32_t the base address of the DAC. +@param[in] dac the base address of the DAC. @ref dac_reg_base @param[in] data uint16_t with appropriate alignment. @param[in] align enum ::dac_align. Alignment and size. @param[in] channel uint8_t with DAC mask. */ - void dac_load_data_buffer_single(uint32_t dac, uint16_t data, enum dac_align align, int channel) @@ -424,7 +403,6 @@ void dac_load_data_buffer_single(uint32_t dac, uint16_t data, } } -/*---------------------------------------------------------------------------*/ /** @brief Load DAC Dual Data Register. Loads the appropriate digital to analog converter dual data register with 12 or @@ -432,13 +410,12 @@ Loads the appropriate digital to analog converter dual data register with 12 or simultaneous or independent analog output. The data in both channels are aligned identically. -@param[in] dac uint32_t the base address of the DAC. +@param[in] dac the base address of the DAC. @ref dac_reg_base @param[in] data1 uint16_t for channel 1 with appropriate alignment. @param[in] data2 uint16_t for channel 2 with appropriate alignment. @param[in] align enum ::dac_align. Right or left aligned, and 8 or 12 bit. */ - void dac_load_data_buffer_dual(uint32_t dac, uint16_t data1, uint16_t data2, enum dac_align align) @@ -460,16 +437,14 @@ void dac_load_data_buffer_dual(uint32_t dac, } } -/*---------------------------------------------------------------------------*/ /** @brief Trigger the DAC by a Software Trigger. If the trigger source is set to be a software trigger, cause a trigger to occur. The trigger is cleared by hardware after conversion. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_software_trigger(uint32_t dac, int channel) { switch (channel) { diff --git a/lib/stm32/common/dac_common_v1.c b/lib/stm32/common/dac_common_v1.c index 13c73f06..c703d73a 100644 --- a/lib/stm32/common/dac_common_v1.c +++ b/lib/stm32/common/dac_common_v1.c @@ -29,7 +29,6 @@ LGPL License Terms @ref lgpl_license #include -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Output Buffer Enable. Enable a digital to analog converter channel output drive buffer. This is an @@ -37,10 +36,9 @@ optional amplifying buffer that provides additional drive for the output signal. The buffer is enabled by default after a reset and needs to be explicitly disabled if required. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_buffer_enable(uint32_t dac, int channel) { switch (channel) { @@ -56,17 +54,15 @@ void dac_buffer_enable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Output Buffer Disable. Disable a digital to analog converter channel output drive buffer. Disabling this will reduce power consumption slightly and will increase the output impedance of the DAC. The buffers are enabled by default after a reset. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_buffer_disable(uint32_t dac, int channel) { switch (channel) { diff --git a/lib/stm32/common/dac_common_v2.c b/lib/stm32/common/dac_common_v2.c index c7e4699e..75204843 100644 --- a/lib/stm32/common/dac_common_v2.c +++ b/lib/stm32/common/dac_common_v2.c @@ -29,7 +29,6 @@ LGPL License Terms @ref lgpl_license #include -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Output Buffer Enable. Enable a digital to analog converter channel output drive buffer. This is an @@ -37,10 +36,9 @@ optional amplifying buffer that provides additional drive for the output signal. The buffer is enabled by default after a reset and needs to be explicitly disabled if required. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_buffer_enable(uint32_t dac, int channel) { switch (channel) { @@ -59,17 +57,15 @@ void dac_buffer_enable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Output Buffer Disable. Disable a digital to analog converter channel output drive buffer. Disabling this will reduce power consumption slightly and will increase the output impedance of the DAC. The buffers are enabled by default after a reset. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_buffer_disable(uint32_t dac, int channel) { switch (channel) { @@ -88,7 +84,6 @@ void dac_buffer_disable(uint32_t dac, int channel) } } -/*---------------------------------------------------------------------------*/ /** @brief DAC Channel Output Mode. Each DAC channel can be configured in Normal mode or Sample and hold mode. The @@ -100,23 +95,20 @@ during application operation. @note This must be called before enabling the DAC as the settings will then become read-only. -@param[in] dac uint32_t the base address of the DAC. +@param[in] dac the base address of the DAC. @ref dac_reg_base @param[in] mamp uint32_t. Taken from @ref dac_mode2_sel or @ref dac_mode1_sel or a logical OR of one of each of these to set both channels simultaneously. */ - void dac_set_mode(uint32_t dac, uint32_t mode) { DAC_MCR(dac) |= mode; } -/*---------------------------------------------------------------------------*/ /** @brief Check if DAC channel is ready to receive data. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - bool dac_is_ready(uint32_t dac, int channel) { uint32_t mask = 0; @@ -130,28 +122,24 @@ bool dac_is_ready(uint32_t dac, int channel) return (DAC_SR(dac) & mask) != 0; } -/*---------------------------------------------------------------------------*/ /** @brief Wait until DAC channel is ready to receive data. -@param[in] dac uint32_t the base address of the DAC. -@param[in] channel uint8_t with DAC mask. +@param[in] dac the base address of the DAC. @ref dac_reg_base +@param[in] channel with DAC mask. @ref dac_channel_id */ - void dac_wait_on_ready(uint32_t dac, int channel) { while (!dac_is_ready(dac, channel)); } -/*---------------------------------------------------------------------------*/ /** @brief High frequency interface mode selection. If the AHB frequency of the DAC is above 80MHz then this value needs setting to an appropriate value. -@param[in] dac uint32_t the base address of the DAC. +@param[in] dac the base address of the DAC. @ref dac_reg_base @param[in] hfsel uint32_t with appropriate HFSEL mask. */ - void dac_set_high_frequency_mode(uint32_t dac, uint32_t hfsel) { uint32_t reg32 = DAC_MCR(dac); From 4576f290488c005df7327cc83c6b3e000003e9ea Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 24 Jan 2021 22:28:15 +0000 Subject: [PATCH 068/206] stm32g4: adc: fix doxygen grouping avoids stub groups --- lib/stm32/g4/adc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/stm32/g4/adc.c b/lib/stm32/g4/adc.c index 1b1cd920..b859b3bf 100644 --- a/lib/stm32/g4/adc.c +++ b/lib/stm32/g4/adc.c @@ -1,6 +1,5 @@ -/** @defgroup adc_file ADC - * - * @ingroup STM32G4xx +/** @addtogroup adc_file ADC peripheral API + * @ingroup peripheral_apis * * @brief libopencm3 STM32G4xx ADC * From 34a44af4e4cb5f5337e3be7eb2300324b084744e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 24 Jan 2021 22:34:10 +0000 Subject: [PATCH 069/206] stm32: dac: fix doxygen parameter link --- lib/stm32/common/dac_common_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stm32/common/dac_common_v2.c b/lib/stm32/common/dac_common_v2.c index 75204843..2ab57215 100644 --- a/lib/stm32/common/dac_common_v2.c +++ b/lib/stm32/common/dac_common_v2.c @@ -96,7 +96,7 @@ during application operation. become read-only. @param[in] dac the base address of the DAC. @ref dac_reg_base -@param[in] mamp uint32_t. Taken from @ref dac_mode2_sel or @ref dac_mode1_sel or +@param[in] mode Taken from @ref dac_mode2_sel or @ref dac_mode1_sel or a logical OR of one of each of these to set both channels simultaneously. */ void dac_set_mode(uint32_t dac, uint32_t mode) From f9d5fb738e2c1ffd62505d1dbf70e8d380fcc869 Mon Sep 17 00:00:00 2001 From: Stijn Martens Date: Tue, 15 Dec 2020 10:37:22 +0100 Subject: [PATCH 070/206] stm32: usart: add idle interrupt enable/disable --- .../stm32/common/usart_common_all.h | 2 ++ lib/stm32/common/usart_common_all.c | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/libopencm3/stm32/common/usart_common_all.h b/include/libopencm3/stm32/common/usart_common_all.h index 5a41684b..8c310a9c 100644 --- a/include/libopencm3/stm32/common/usart_common_all.h +++ b/include/libopencm3/stm32/common/usart_common_all.h @@ -122,6 +122,8 @@ void usart_enable_tx_interrupt(uint32_t usart); void usart_disable_tx_interrupt(uint32_t usart); void usart_enable_tx_complete_interrupt(uint32_t usart); void usart_disable_tx_complete_interrupt(uint32_t usart); +void usart_enable_idle_interrupt(uint32_t usart); +void usart_disable_idle_interrupt(uint32_t usart); void usart_enable_error_interrupt(uint32_t usart); void usart_disable_error_interrupt(uint32_t usart); bool usart_get_flag(uint32_t usart, uint32_t flag); diff --git a/lib/stm32/common/usart_common_all.c b/lib/stm32/common/usart_common_all.c index 3565e802..e30e2feb 100644 --- a/lib/stm32/common/usart_common_all.c +++ b/lib/stm32/common/usart_common_all.c @@ -376,6 +376,29 @@ void usart_disable_tx_complete_interrupt(uint32_t usart) USART_CR1(usart) &= ~USART_CR1_TCIE; } +/** @brief USART Idle Interrupt Enable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_enable_idle_interrupt(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_IDLEIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Idle Interrupt Disable. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +*/ + +void usart_disable_idle_interrupt(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_IDLEIE; +} + /*---------------------------------------------------------------------------*/ /** @brief USART Error Interrupt Enable. From da9db7f1f58f3765ef25a9fc3b8767e9eebb8b49 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 26 Jan 2021 22:32:53 +0000 Subject: [PATCH 071/206] stm32:dac: fix doxygen tags on v2 Trivial copy paste error. --- include/libopencm3/stm32/common/dac_common_v2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/libopencm3/stm32/common/dac_common_v2.h b/include/libopencm3/stm32/common/dac_common_v2.h index ff3f95f1..84adb31c 100644 --- a/include/libopencm3/stm32/common/dac_common_v2.h +++ b/include/libopencm3/stm32/common/dac_common_v2.h @@ -485,7 +485,7 @@ specific memorymap.h header before including this header file.*/ /* STINCTRIGSEL1[3:0]: DAC channel1 sawtooth increment trigger selection */ #define DAC_STMODR_STINCTRIGSEL1_SHIFT 8 -/** @defgroup dac_sawtooth2_inc DAC Channel 1 Sawtooth Increment Trigger +/** @defgroup dac_sawtooth1_inc DAC Channel 1 Sawtooth Increment Trigger @ingroup dac_defines @li SW: SWTRIGB2 @@ -527,7 +527,7 @@ specific memorymap.h header before including this header file.*/ /* STRSTTRIGSEL1[3:0]: DAC channel1 sawtooth reset trigger selection */ #define DAC_STMODR_STRSTTRIGSEL1_SHIFT 0 -/** @defgroup dac_sawtooth2_rst DAC Channel 1 Sawtooth Reset Trigger +/** @defgroup dac_sawtooth1_rst DAC Channel 1 Sawtooth Reset Trigger @ingroup dac_defines @li SW: SWTRIGB2 From 8295d248e0d17b3462fc0dd6d152dc2094eb67fb Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sun, 24 Jan 2021 22:49:33 +0000 Subject: [PATCH 072/206] stm32:dac: new api for waveform characteristics Old API required users to manually construct bit maps frm opaquely named defines, with little help. It also was a pure OR operation, with no way to ever clear bits. Signed-off-by: Karl Palsson --- .../libopencm3/stm32/common/dac_common_all.h | 8 +++--- lib/stm32/common/dac_common_all.c | 27 ++++++++++++++++--- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/include/libopencm3/stm32/common/dac_common_all.h b/include/libopencm3/stm32/common/dac_common_all.h index c93b9dbc..069d6a65 100644 --- a/include/libopencm3/stm32/common/dac_common_all.h +++ b/include/libopencm3/stm32/common/dac_common_all.h @@ -100,7 +100,7 @@ specific memorymap.h header before including this header file.*/ /** DMAEN2: DAC channel2 DMA enable */ #define DAC_CR_DMAEN2 (1 << 28) -/** MAMP2[3:0]: DAC channel2 mask/amplitude selector */ +/** MAMP2[3:0]: DAC channel2 mask/amplitude selector field position */ #define DAC_CR_MAMP2_SHIFT 24 /** WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ @@ -118,8 +118,10 @@ specific memorymap.h header before including this header file.*/ /** DMAEN1: DAC channel1 DMA enable */ #define DAC_CR_DMAEN1 (1 << 12) -/** MAMP1[3:0]: DAC channel1 mask/amplitude selector */ +/** MAMP1[3:0]: DAC channel1 mask/amplitude selector field position */ #define DAC_CR_MAMP1_SHIFT 8 +/** MAMP Mask/Amplitude selector field size */ +#define DAC_CR_MAMPx_MASK 0xf /** WAVEn[1:0]: DAC channel1 noise/triangle wave generation enable */ #define DAC_CR_WAVE1_SHIFT 6 @@ -257,7 +259,7 @@ void dac_trigger_disable(uint32_t dac, int channel); void dac_set_trigger_source(uint32_t dac, uint32_t source); void dac_set_waveform_generation(uint32_t dac, enum dac_wave wave); void dac_disable_waveform_generation(uint32_t dac, int channel); -void dac_set_waveform_characteristics(uint32_t dac, uint8_t mamp); +void dac_set_waveform_characteristics(uint32_t dac, int channel, int mamp); void dac_load_data_buffer_single(uint32_t dac, uint16_t data, enum dac_align align, int channel); void dac_load_data_buffer_dual(uint32_t dac, uint16_t data1, uint16_t data2, diff --git a/lib/stm32/common/dac_common_all.c b/lib/stm32/common/dac_common_all.c index bc26ef74..6b88d10a 100644 --- a/lib/stm32/common/dac_common_all.c +++ b/lib/stm32/common/dac_common_all.c @@ -347,12 +347,31 @@ become read-only. @note The DAC trigger must be enabled for this to work. @param[in] dac the base address of the DAC. @ref dac_reg_base -@param[in] mamp uint8_t. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a -logical OR of one of each of these to set both channels simultaneously. +@param[in] channel one or both, select from @ref dac_channel_id +@param[in] mamp amplitude of mixed waveform, bit width @ref DAC_CR_MAMPx_MASK */ -void dac_set_waveform_characteristics(uint32_t dac, uint8_t mamp) +void dac_set_waveform_characteristics(uint32_t dac, int channel, int mamp) { - DAC_CR(dac) |= mamp; + uint32_t reg = DAC_CR(dac); + switch(channel) { + case DAC_CHANNEL1: + reg &= ~(DAC_CR_MAMPx_MASK << DAC_CR_MAMP1_SHIFT); + reg |= mamp << DAC_CR_MAMP1_SHIFT; + break; + case DAC_CHANNEL2: + reg &= ~(DAC_CR_MAMPx_MASK << DAC_CR_MAMP2_SHIFT); + reg |= mamp << DAC_CR_MAMP2_SHIFT; + break; + case DAC_CHANNEL_BOTH: + reg &= ~(DAC_CR_MAMPx_MASK << DAC_CR_MAMP1_SHIFT) + | ~(DAC_CR_MAMPx_MASK << DAC_CR_MAMP2_SHIFT); + reg |= mamp << DAC_CR_MAMP1_SHIFT; + reg |= mamp << DAC_CR_MAMP2_SHIFT; + break; + default: + break; + } + DAC_CR(dac) = reg; } /** @brief Load DAC Data Register. From 0f1f1ebd1a3e3f35aa559a463ae321d226f6fb75 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 26 Jan 2021 22:31:06 +0000 Subject: [PATCH 073/206] stm32:dac: Fix waveform generation apis These were broken earlier, with no sane way of passing in correctly shifted values, and didn't match examples. Noticed while merging: https://github.com/libopencm3/libopencm3/pull/1281 --- .../libopencm3/stm32/common/dac_common_all.h | 15 +++-- lib/stm32/common/dac_common_all.c | 67 ++++++++++--------- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/include/libopencm3/stm32/common/dac_common_all.h b/include/libopencm3/stm32/common/dac_common_all.h index 069d6a65..6508d899 100644 --- a/include/libopencm3/stm32/common/dac_common_all.h +++ b/include/libopencm3/stm32/common/dac_common_all.h @@ -103,9 +103,11 @@ specific memorymap.h header before including this header file.*/ /** MAMP2[3:0]: DAC channel2 mask/amplitude selector field position */ #define DAC_CR_MAMP2_SHIFT 24 -/** WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ +/** Wave generation mode mask size */ +#define DAC_CR_WAVEx_MASK 0x3 + +/** WAVE2[1:0]: DAC channel2 wave generation mode*/ #define DAC_CR_WAVE2_SHIFT 22 -#define DAC_CR_WAVE2_MASK 0x3 /** EN2: DAC channel2 enable */ #define DAC_CR_EN2 (1 << 16) @@ -123,9 +125,8 @@ specific memorymap.h header before including this header file.*/ /** MAMP Mask/Amplitude selector field size */ #define DAC_CR_MAMPx_MASK 0xf -/** WAVEn[1:0]: DAC channel1 noise/triangle wave generation enable */ +/** WAVE1[1:0]: DAC channel1 wave generation mode */ #define DAC_CR_WAVE1_SHIFT 6 -#define DAC_CR_WAVE1_MASK 0x3 /** EN1: DAC channel1 enable */ #define DAC_CR_EN1 (1 << 0) @@ -238,7 +239,9 @@ enum dac_align { DAC_ALIGN_LEFT12, }; -/** DAC waveform generation options. */ +/** DAC waveform generation options. + * Not all wave shapes are available on all parts. + */ enum dac_wave { DAC_WAVE_DISABLE = 0, DAC_WAVE_NOISE = 1, @@ -257,7 +260,7 @@ void dac_dma_disable(uint32_t dac, int channel); void dac_trigger_enable(uint32_t dac, int channel); void dac_trigger_disable(uint32_t dac, int channel); void dac_set_trigger_source(uint32_t dac, uint32_t source); -void dac_set_waveform_generation(uint32_t dac, enum dac_wave wave); +void dac_set_waveform_generation(uint32_t dac, int channel, enum dac_wave wave); void dac_disable_waveform_generation(uint32_t dac, int channel); void dac_set_waveform_characteristics(uint32_t dac, int channel, int mamp); void dac_load_data_buffer_single(uint32_t dac, uint16_t data, diff --git a/lib/stm32/common/dac_common_all.c b/lib/stm32/common/dac_common_all.c index 6b88d10a..ba0d77ad 100644 --- a/lib/stm32/common/dac_common_all.c +++ b/lib/stm32/common/dac_common_all.c @@ -66,8 +66,8 @@ sent out. GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4); rcc_periph_clock_enable(RCC_DAC); dac_disable(DAC1, DAC_CHANNEL1); - dac_set_waveform_characteristics(DAC1, DAC_CR_MAMP1_8); - dac_set_waveform_generation(DAC1, DAC_CR_WAVE1_NOISE); + dac_set_waveform_characteristics(DAC1, DAC_CHANNEL1, DAC_CR_MAMP1_8); + dac_set_waveform_generation(DAC1, DAC_CHANNEL1, DAC_CR_WAVE1_NOISE); dac_enable(DAC1, DAC_CHANNEL1); dac_set_trigger_source(DAC1, DAC_CR_TSEL1_SW); dac_load_data_buffer_single(DAC1, 0, DAC_ALIGN_RIGHT12, DAC_CHANNEL1); @@ -289,46 +289,49 @@ void dac_set_trigger_source(uint32_t dac, uint32_t source) DAC_CR(dac) |= source; } -/** @brief Enable and Set DAC Channel Waveform Generation. - -Enable the digital to analog converter waveform generation as either -pseudo-random noise or triangular wave. These signals are superimposed on -existing output values in the DAC output registers. - -@note The DAC trigger must be enabled for this to work. -@param[in] dac the base address of the DAC. @ref dac_reg_base -@param[in] wave enum ::dac_wave. Taken from @ref dac_wave1_en or @ref -dac_wave2_en or a logical OR of one of each of these to set both channels -simultaneously. -*/ -void dac_set_waveform_generation(uint32_t dac, enum dac_wave wave) +/** + * Set DAC Channel Waveform Generation mode for one or both channels. + * These signals are superimposed on existing output values in the + * DAC output registers. Waveform can be disabled, noise, triangular, + * or sawtooth, depending on family. + * @note The DAC trigger must be enabled for this to work. + * @param[in] dac the base address of the DAC. @ref dac_reg_base + * @param[in] channel one or both, @ref dac_channel_id + * @param[in] wave enum ::dac_wave. mode for channel + */ +void dac_set_waveform_generation(uint32_t dac, int channel, enum dac_wave wave) { - DAC_CR(dac) |= wave; -} - -/** @brief Disable DAC Channel Waveform Generation. - -Disable a digital to analog converter channel superimposed waveform generation. - -@param[in] dac the base address of the DAC. @ref dac_reg_base -@param[in] channel with DAC mask. @ref dac_channel_id -*/ -void dac_disable_waveform_generation(uint32_t dac, int channel) -{ - switch (channel) { + uint32_t reg = DAC_CR(dac); + switch(channel) { case DAC_CHANNEL1: - DAC_CR(dac) &= ~(DAC_CR_WAVE1_MASK << DAC_CR_WAVE1_SHIFT); + reg &= ~(DAC_CR_WAVEx_MASK << DAC_CR_WAVE1_SHIFT); + reg |= wave << DAC_CR_WAVE1_SHIFT; break; case DAC_CHANNEL2: - DAC_CR(dac) &= ~(DAC_CR_WAVE2_MASK << DAC_CR_WAVE2_SHIFT); + reg &= ~(DAC_CR_WAVEx_MASK << DAC_CR_WAVE2_SHIFT); + reg |= wave << DAC_CR_WAVE2_SHIFT; break; case DAC_CHANNEL_BOTH: - DAC_CR(dac) &= ~(DAC_CR_WAVE1_MASK << DAC_CR_WAVE1_SHIFT) - | ~(DAC_CR_WAVE2_MASK << DAC_CR_WAVE2_SHIFT); + reg &= ~(DAC_CR_WAVEx_MASK << DAC_CR_WAVE1_SHIFT) + | ~(DAC_CR_WAVEx_MASK << DAC_CR_WAVE2_SHIFT); + reg |= wave << DAC_CR_WAVE1_SHIFT; + reg |= wave << DAC_CR_WAVE2_SHIFT; break; default: break; } + DAC_CR(dac) = reg; +} + +/** + * Disable DAC Channel Waveform Generation. + * @note this is equivalent to @ref dac_set_waveform_generation (dac, channel, DAC_WAVE_DISABLE) + * @param[in] dac the base address of the DAC. @ref dac_reg_base + * @param[in] channel with DAC mask. @ref dac_channel_id + */ +void dac_disable_waveform_generation(uint32_t dac, int channel) +{ + dac_set_waveform_generation(dac, channel, DAC_WAVE_DISABLE); } /** @brief Set DAC Channel LFSR Mask or Triangle Wave Amplitude. From 7f74d92e3426fe755512b16614f2ba99ea220e41 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 27 Jan 2021 23:41:25 +0000 Subject: [PATCH 074/206] stm32:dac:doc: clarify availability on part families --- include/libopencm3/stm32/common/dac_common_all.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/libopencm3/stm32/common/dac_common_all.h b/include/libopencm3/stm32/common/dac_common_all.h index 6508d899..093566cc 100644 --- a/include/libopencm3/stm32/common/dac_common_all.h +++ b/include/libopencm3/stm32/common/dac_common_all.h @@ -225,6 +225,7 @@ specific memorymap.h header before including this header file.*/ /* --- Function prototypes ------------------------------------------------- */ /** @defgroup dac_channel_id DAC Channel Identifier + * @note Not all parts have two channels, notably, some of the smaller F0's * @{ */ #define DAC_CHANNEL1 (1 << 0) From bcccfc4a6378d278fefc2e04f8033a1e8cf681b8 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 28 Jan 2021 00:32:47 +0000 Subject: [PATCH 075/206] stm32h7:doc: eliminate some doxygen warnings. --- include/libopencm3/stm32/h7/flash.h | 5 +++-- include/libopencm3/stm32/h7/pwr.h | 8 ++------ include/libopencm3/stm32/h7/rcc.h | 1 - 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/include/libopencm3/stm32/h7/flash.h b/include/libopencm3/stm32/h7/flash.h index 5fb258c2..1da9d1c6 100644 --- a/include/libopencm3/stm32/h7/flash.h +++ b/include/libopencm3/stm32/h7/flash.h @@ -34,7 +34,8 @@ /** @addtogroup flash_acr_values FLASH_ACR values * @ingroup flash_registers -@{*/ + * @{ + */ #define FLASH_ACR_WRHF_VOS1_70MHZ (0 << FLASH_ACR_WRHIGHFREQ_SHIFT) #define FLASH_ACR_WRHF_VOS1_185MHZ (1 << FLASH_ACR_WRHIGHFREQ_SHIFT) #define FLASH_ACR_WRHF_VOS1_225MHZ (2 << FLASH_ACR_WRHIGHFREQ_SHIFT) @@ -44,7 +45,7 @@ #define FLASH_ACR_WRHF_VOS3_45MHZ (0 << FLASH_ACR_WRHIGHFREQ_SHIFT) #define FLASH_ACR_WRHF_VOS3_135MHZ (1 << FLASH_ACR_WRHIGHFREQ_SHIFT) #define FLASH_ACR_WRHF_VOS3_225MHZ (2 << FLASH_ACR_WRHIGHFREQ_SHIFT) -/*@}*/ +/**@}*/ #define FLASH_ACR_WRHIGHFREQ_MASK (0x3) #define FLASH_ACR_WRHIGHFREQ_SHIFT (0x4) diff --git a/include/libopencm3/stm32/h7/pwr.h b/include/libopencm3/stm32/h7/pwr.h index e0ef4db6..714d6436 100644 --- a/include/libopencm3/stm32/h7/pwr.h +++ b/include/libopencm3/stm32/h7/pwr.h @@ -27,9 +27,7 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -#ifndef LIBOPENCM3_PWR_H -#define LIBOPENCM3_PWR_H - +#pragma once /**@{*/ /** @defgroup pwr_registers PWR Registers @@ -55,7 +53,7 @@ LGPL License Terms @ref lgpl_license /** Wakeup Domain Power Control register. */ #define PWR_WKUPCR MMIO32(POWER_CONTROL_BASE + 0x20) -/*@}*/ +/**@}*/ /** VOS[15:14]: Regulator voltage scaling output selection */ #define PWR_CR1_SVOS_SHIFT 14 @@ -130,5 +128,3 @@ void pwr_set_vos_scale(enum pwr_vos_scale scale); END_DECLS /**@}*/ - -#endif diff --git a/include/libopencm3/stm32/h7/rcc.h b/include/libopencm3/stm32/h7/rcc.h index ebef3935..32a1058e 100644 --- a/include/libopencm3/stm32/h7/rcc.h +++ b/include/libopencm3/stm32/h7/rcc.h @@ -810,6 +810,5 @@ void rcc_set_rng_clksel(uint8_t clksel); END_DECLS /**@}*/ -/**@}*/ #endif From 5f4e2b37589254b48424c98dabc55e2958a1ecf4 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 28 Jan 2021 00:33:07 +0000 Subject: [PATCH 076/206] stm32:i2c-v1: eliminate doxygen warnings We deprecated the defines in favour of just using the value itself, so there's no longer a defined group to reference. --- lib/stm32/common/i2c_common_v1.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/stm32/common/i2c_common_v1.c b/lib/stm32/common/i2c_common_v1.c index c87ef96f..caab1485 100644 --- a/lib/stm32/common/i2c_common_v1.c +++ b/lib/stm32/common/i2c_common_v1.c @@ -225,8 +225,9 @@ that this is not the I2C bus clock. This is set in conjunction with the Clock Control register to generate the Master bus clock, see @ref i2c_set_ccr -@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base. -@param[in] freq Unsigned int8. Clock Frequency Setting @ref i2c_clock. +@param[in] i2c I2C register base address @ref i2c_reg_base +@param[in] freq Clock Frequency Setting in MHz, valid range depends on part,+ + normally 2Mhz->Max APB speed. */ void i2c_set_clock_frequency(uint32_t i2c, uint8_t freq) From 7df670b6aad223a056e341c391c99d8cee07d840 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 29 Jan 2021 12:26:03 +0000 Subject: [PATCH 077/206] stm32: usart: fix doxygen for h7 at least The usart_common_fifos uses a very nice style of docs in the headers, so inline help works in some editors, without having to have the source of the library available as well. However, it means that the group definition with the name doesn't appear until later, and then the title is ignored. Move the description to the header definition instead. --- include/libopencm3/stm32/common/usart_common_fifos.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/libopencm3/stm32/common/usart_common_fifos.h b/include/libopencm3/stm32/common/usart_common_fifos.h index 5eb5d376..1124bd64 100644 --- a/include/libopencm3/stm32/common/usart_common_fifos.h +++ b/include/libopencm3/stm32/common/usart_common_fifos.h @@ -92,8 +92,10 @@ typedef enum { BEGIN_DECLS -/** @addtogroup usart_file -@{*/ +/** @defgroup usart_file USART peripheral API + * @ingroup peripheral_apis + * @{ + */ /** * Enable FIFOs on the specified USART. * @param[in] usart Base address of USART to configure FIFOs. From 0cf8a47d8832a76f6f6fe7999c205dffc18fe579 Mon Sep 17 00:00:00 2001 From: Matt Walker Date: Tue, 18 Aug 2020 20:20:45 -0400 Subject: [PATCH 078/206] STM32H7: Add QSPI Defines Move the STM32F4 QuadSPI peripheral defines to the common folder as the F4 and H7 variants of the IP share almost all the same bits. For those bits that are separate put them into their own headers. --- .../stm32/common/quadspi_common_v1.h | 169 ++++++++++++++++++ include/libopencm3/stm32/f4/quadspi.h | 140 +-------------- include/libopencm3/stm32/h7/quadspi.h | 27 +++ 3 files changed, 202 insertions(+), 134 deletions(-) create mode 100644 include/libopencm3/stm32/common/quadspi_common_v1.h create mode 100644 include/libopencm3/stm32/h7/quadspi.h diff --git a/include/libopencm3/stm32/common/quadspi_common_v1.h b/include/libopencm3/stm32/common/quadspi_common_v1.h new file mode 100644 index 00000000..4ea23f92 --- /dev/null +++ b/include/libopencm3/stm32/common/quadspi_common_v1.h @@ -0,0 +1,169 @@ +/* + * This file is part of the libopencm3 project. + * + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA quadspi.h +The order of header inclusion is important. quadspi.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_QUADSPI_H +/** @endcond */ +#ifndef LIBOPENCM3_QUADSPI_COMMON_V1_H +#define LIBOPENCM3_QUADSPI_COMMON_V1_H + +/* QUADSPI Control register */ +#define QUADSPI_CR MMIO32(QUADSPI_BASE + 0x0U) + +#define QUADSPI_CR_PRESCALE_MASK 0xff +#define QUADSPI_CR_PRESCALE_SHIFT 24 +#define QUADSPI_CR_PMM (1 << 23) +#define QUADSPI_CR_APMS (1 << 22) +/* bit 21 is reserved */ +#define QUADSPI_CR_TOIE (1 << 20) +#define QUADSPI_CR_SMIE (1 << 19) +#define QUADSPI_CR_FTIE (1 << 18) +#define QUADSPI_CR_TCIE (1 << 17) +#define QUADSPI_CR_TEIE (1 << 16) + +/* bits 15:13 reserved */ +#define QUADSPI_CR_FTHRES_MASK 0x1f +#define QUADSPI_CR_FTHRES_SHIFT 8 +#define QUADSPI_CR_FSEL (1 << 7) +#define QUADSPI_CR_DFM (1 << 6) +/* bit 5 reserved */ +#define QUADSPI_CR_SSHIFT (1 << 4) +#define QUADSPI_CR_TCEN (1 << 3) +/* bit 2 reserved on h7, DMAEN on f4 */ +#define QUADSPI_CR_ABORT (1 << 1) +#define QUADSPI_CR_EN (1 << 0) + +/* QUADSPI Device Configuration */ +#define QUADSPI_DCR MMIO32(QUADSPI_BASE + 0x4U) + +/* bits 31:21 reserved */ +#define QUADSPI_DCR_FSIZE_MASK 0x1f +#define QUADSPI_DCR_FSIZE_SHIFT 16 +/* bits 15:11 reserved */ +#define QUADSPI_DCR_CSHT_MASK 0x7 +#define QUADSPI_DCR_CSHT_SHIFT 8 +/* bits 7:1 reserved */ +#define QUADSPI_DCR_CKMODE (1 << 0) + +/* QUADSPI Status Register */ +#define QUADSPI_SR MMIO32(QUADSPI_BASE + 0x8U) + +/* bits 31:14 reserved */ +#define QUADSPI_SR_FLEVEL_MASK 0x3f +#define QUADSPI_SR_FLEVEL_SHIFT 8 + +/* bits 7:6 reserved */ +#define QUADSPI_SR_BUSY (1 << 5) +#define QUADSPI_SR_TOF (1 << 4) +#define QUADSPI_SR_SMF (1 << 3) +#define QUADSPI_SR_FTF (1 << 2) +#define QUADSPI_SR_TCF (1 << 1) +#define QUADSPI_SR_TEF (1 << 0) + +/* QUADSPI Flag Clear Register */ +#define QUADSPI_FCR MMIO32(QUADSPI_BASE + 0xCU) + +/* bits 31:5 reserved */ +#define QUADSPI_FCR_CTOF (1 << 4) +#define QUADSPI_FCR_CSMF (1 << 3) +/* bit 2 reserved */ +#define QUADSPI_FCR_CTCF (1 << 1) +#define QUADSPI_FCR_CTEF (1 << 0) + +/* QUADSPI Data Length Register */ +#define QUADSPI_DLR MMIO32(QUADSPI_BASE + 0x10U) + +/* QUADSPI Communication Configuration Register */ +#define QUADSPI_CCR MMIO32(QUADSPI_BASE + 0x14U) + +#define QUADSPI_CCR_DDRM (1 << 31) +#define QUADSPI_CCR_DHHC (1 << 30) +/* bit 29 reserved on F4, FRCM on H7 */ +#define QUADSPI_CCR_SIOO (1 << 28) +#define QUADSPI_CCR_FMODE_MASK 0x3 +#define QUADSPI_CCR_FMODE_SHIFT 26 +#define QUADSPI_CCR_DMODE_MASK 0x3 +#define QUADSPI_CCR_DMODE_SHIFT 24 +/* bit 23 reserved */ +#define QUADSPI_CCR_DCYC_MASK 0x1f +#define QUADSPI_CCR_DCYC_SHIFT 18 + +#define QUADSPI_CCR_ABSIZE_MASK 0x3 +#define QUADSPI_CCR_ABSIZE_SHIFT 16 + +#define QUADSPI_CCR_ABMODE_MASK 0x3 +#define QUADSPI_CCR_ABMODE_SHIFT 14 + +#define QUADSPI_CCR_ADSIZE_MASK 0x3 +#define QUADSPI_CCR_ADSIZE_SHIFT 12 + +#define QUADSPI_CCR_ADMODE_MASK 0x3 +#define QUADSPI_CCR_ADMODE_SHIFT 10 + +#define QUADSPI_CCR_IMODE_MASK 0x3 +#define QUADSPI_CCR_IMODE_SHIFT 8 + +#define QUADSPI_CCR_INST_MASK 0xff +#define QUADSPI_CCR_INST_SHIFT 0 + +/* MODE values */ +#define QUADSPI_CCR_MODE_NONE 0 +#define QUADSPI_CCR_MODE_1LINE 1 +#define QUADSPI_CCR_MODE_2LINE 2 +#define QUADSPI_CCR_MODE_4LINE 3 + +/* FMODE values */ +#define QUADSPI_CCR_FMODE_IWRITE 0 +#define QUADSPI_CCR_FMODE_IREAD 1 +#define QUADSPI_CCR_FMODE_APOLL 2 +#define QUADSPI_CCR_FMODE_MEMMAP 3 + + +/* QUADSPI address register */ +#define QUADSPI_AR MMIO32(QUADSPI_BASE + 0x18U) + +/* QUADSPI alternate bytes register */ +#define QUADSPI_ABR MMIO32(QUADSPI_BASE + 0x1CU) + +/* QUADSPI data register */ +#define QUADSPI_DR MMIO32(QUADSPI_BASE + 0x20U) +/* BYTE addressable version for fetching bytes from the interface */ +#define QUADSPI_BYTE_DR MMIO8(QUADSPI_BASE + 0x20U) + +/* QUADSPI polling status */ +#define QUADSPI_PSMKR MMIO32(QUADSPI_BASE + 0x24U) + +/* QUADSPI polling status match */ +#define QUADSPI_PSMAR MMIO32(QUADSPI_BASE + 0x28U) + +/* QUADSPI polling interval register */ +#define QUADSPI_PIR MMIO32(QUADSPI_BASE + 0x2CU) + +/* QUADSPI low power timeout */ +#define QUADSPI_LPTR MMIO32(QUADSPI_BASE + 0x30U + +#endif +/** @cond */ +#else +#warning "quadspi_common_v1.h should not be included directly, only via quadspi.h" +#endif +/** @endcond */ diff --git a/include/libopencm3/stm32/f4/quadspi.h b/include/libopencm3/stm32/f4/quadspi.h index 2808f02b..101c5284 100644 --- a/include/libopencm3/stm32/f4/quadspi.h +++ b/include/libopencm3/stm32/f4/quadspi.h @@ -20,140 +20,12 @@ * */ +#ifndef LIBOPENCM3_QUADSPI_H +#define LIBOPENCM3_QUADSPI_H + #include +#include -/* QUADSPI Control register */ -#define QUADSPI_CR MMIO32(QUADSPI_BASE + 0x0U) - -#define QUADSPI_CR_PRESCALE_MASK 0xff -#define QUADSPI_CR_PRESCALE_SHIFT 24 -#define QUADSPI_CR_PMM (1 << 23) -#define QUADSPI_CR_APMS (1 << 22) -/* bit 21 is reserved */ -#define QUADSPI_CR_TOIE (1 << 20) -#define QUADSPI_CR_SMIE (1 << 19) -#define QUADSPI_CR_FTIE (1 << 18) -#define QUADSPI_CR_TCIE (1 << 17) -#define QUADSPI_CR_TEIE (1 << 16) - -/* bits 15:13 reserved */ -#define QUADSPI_CR_FTHRES_MASK 0x1f -#define QUADSPI_CR_FTHRES_SHIFT 8 -#define QUADSPI_CR_FSEL (1 << 7) -#define QUADSPI_CR_DFM (1 << 6) -/* bit 5 reserved */ -#define QUADSPI_CR_SSHIFT (1 << 4) -#define QUADSPI_CR_TCEN (1 << 3) -#define QUADSPI_CR_DMAEN (1 << 2) -#define QUADSPI_CR_ABORT (1 << 1) -#define QUADSPI_CR_EN (1 << 0) - -/* QUADSPI Device Configuration */ -#define QUADSPI_DCR MMIO32(QUADSPI_BASE + 0x4U) - -/* bits 31:21 reserved */ -#define QUADSPI_DCR_FSIZE_MASK 0x1f -#define QUADSPI_DCR_FSIZE_SHIFT 16 -/* bits 15:11 reserved */ -#define QUADSPI_DCR_CSHT_MASK 0x7 -#define QUADSPI_DCR_CSHT_SHIFT 8 -/* bits 7:1 reserved */ -#define QUADSPI_DCR_CKMODE (1 << 0) - -/* QUADSPI Status Register */ -#define QUADSPI_SR MMIO32(QUADSPI_BASE + 0x8U) - -/* bits 31:14 reserved */ -#define QUADSPI_SR_FLEVEL_MASK 0x3f -#define QUADSPI_SR_FLEVEL_SHIFT 8 - -/* bits 7:6 reserved */ -#define QUADSPI_SR_BUSY (1 << 5) -#define QUADSPI_SR_TOF (1 << 4) -#define QUADSPI_SR_SMF (1 << 3) -#define QUADSPI_SR_FTF (1 << 2) -#define QUADSPI_SR_TCF (1 << 1) -#define QUADSPI_SR_TEF (1 << 0) - -/* QUADSPI Flag Clear Register */ -#define QUADSPI_FCR MMIO32(QUADSPI_BASE + 0xCU) - -/* bits 31:5 reserved */ -#define QUADSPI_FCR_CTOF (1 << 4) -#define QUADSPI_FCR_CSMF (1 << 3) -/* bit 2 reserved */ -#define QUADSPI_FCR_CTCF (1 << 1) -#define QUADSPI_FCR_CTEF (1 << 0) - -/* QUADSPI Data Length Register */ -#define QUADSPI_DLR MMIO32(QUADSPI_BASE + 0x10U) - -/* QUADSPI Communication Configuration Register */ -#define QUADSPI_CCR MMIO32(QUADSPI_BASE + 0x14U) - -#define QUADSPI_CCR_DDRM (1 << 31) -#define QUADSPI_CCR_DHHC (1 << 30) -/* bit 29 reserved */ -#define QUADSPI_CCR_SIOO (1 << 28) -#define QUADSPI_CCR_FMODE_MASK 0x3 -#define QUADSPI_CCR_FMODE_SHIFT 26 -#define QUADSPI_CCR_DMODE_MASK 0x3 -#define QUADSPI_CCR_DMODE_SHIFT 24 -/* bit 23 reserved */ -#define QUADSPI_CCR_DCYC_MASK 0x1f -#define QUADSPI_CCR_DCYC_SHIFT 18 - -#define QUADSPI_CCR_ABSIZE_MASK 0x3 -#define QUADSPI_CCR_ABSIZE_SHIFT 16 - -#define QUADSPI_CCR_ABMODE_MASK 0x3 -#define QUADSPI_CCR_ABMODE_SHIFT 14 - -#define QUADSPI_CCR_ADSIZE_MASK 0x3 -#define QUADSPI_CCR_ADSIZE_SHIFT 12 - -#define QUADSPI_CCR_ADMODE_MASK 0x3 -#define QUADSPI_CCR_ADMODE_SHIFT 10 - -#define QUADSPI_CCR_IMODE_MASK 0x3 -#define QUADSPI_CCR_IMODE_SHIFT 8 - -#define QUADSPI_CCR_INST_MASK 0xff -#define QUADSPI_CCR_INST_SHIFT 0 - -/* MODE values */ -#define QUADSPI_CCR_MODE_NONE 0 -#define QUADSPI_CCR_MODE_1LINE 1 -#define QUADSPI_CCR_MODE_2LINE 2 -#define QUADSPI_CCR_MODE_4LINE 3 - -/* FMODE values */ -#define QUADSPI_CCR_FMODE_IWRITE 0 -#define QUADSPI_CCR_FMODE_IREAD 1 -#define QUADSPI_CCR_FMODE_APOLL 2 -#define QUADSPI_CCR_FMODE_MEMMAP 3 - - -/* QUADSPI address register */ -#define QUADSPI_AR MMIO32(QUADSPI_BASE + 0x18U) - -/* QUADSPI alternate bytes register */ -#define QUADSPI_ABR MMIO32(QUADSPI_BASE + 0x1CU) - -/* QUADSPI data register */ -#define QUADSPI_DR MMIO32(QUADSPI_BASE + 0x20U) -/* BYTE addressable version for fetching bytes from the interface */ -#define QUADSPI_BYTE_DR MMIO8(QUADSPI_BASE + 0x20U) - -/* QUADSPI polling status */ -#define QUADSPI_PSMKR MMIO32(QUADSPI_BASE + 0x24U) - -/* QUADSPI polling status match */ -#define QUADSPI_PSMAR MMIO32(QUADSPI_BASE + 0x28U) - -/* QUADSPI polling interval register */ -#define QUADSPI_PIR MMIO32(QUADSPI_BASE + 0x2CU) - -/* QUADSPI low power timeout */ -#define QUADSPI_LPTR MMIO32(QUADSPI_BASE + 0x30U) +#define QUADSPI_CR_DMAEN (1 << 2) +#endif /* LIBOPENCM3_QUADSPI_H */ diff --git a/include/libopencm3/stm32/h7/quadspi.h b/include/libopencm3/stm32/h7/quadspi.h new file mode 100644 index 00000000..14a2e361 --- /dev/null +++ b/include/libopencm3/stm32/h7/quadspi.h @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_QUADSPI_H +#define LIBOPENCM3_QUADSPI_H + +#include +#include + +/** Enable free running clock mode, for testing */ +#define QUADSPI_CCR_FRCM (1 << 29) + +#endif /* LIBOPENCM3_QUADSPI_H */ From c02ccfe47e881a4d3015c59da4c8b993f057e234 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 29 Jan 2021 11:41:09 +0000 Subject: [PATCH 079/206] stm32: quadspi: restore copyright after file move The f4 quadspi implementation was moved to the -v1 file, so the copyright should have moved with it. --- include/libopencm3/stm32/common/quadspi_common_v1.h | 1 + include/libopencm3/stm32/f4/quadspi.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/libopencm3/stm32/common/quadspi_common_v1.h b/include/libopencm3/stm32/common/quadspi_common_v1.h index 4ea23f92..d0af76e0 100644 --- a/include/libopencm3/stm32/common/quadspi_common_v1.h +++ b/include/libopencm3/stm32/common/quadspi_common_v1.h @@ -1,6 +1,7 @@ /* * This file is part of the libopencm3 project. * + * Copyright (C) 2016, Chuck McManis * * 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 diff --git a/include/libopencm3/stm32/f4/quadspi.h b/include/libopencm3/stm32/f4/quadspi.h index 101c5284..f4aff561 100644 --- a/include/libopencm3/stm32/f4/quadspi.h +++ b/include/libopencm3/stm32/f4/quadspi.h @@ -1,8 +1,6 @@ /* * STM32F4 Quad SPI defines * - * Copyright (C) 2016, Chuck McManis - * * This file is part of the libopencm3 project. * * This library is free software: you can redistribute it and/or modify From 2daef7c3ec2e9a2bca929276ff0ae86f76233932 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 29 Jan 2021 11:42:00 +0000 Subject: [PATCH 080/206] stm32h7: enable quadspi includes Fixes: fcb030cc883ca14 which left off the include header. --- include/libopencm3/stm32/quadspi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/libopencm3/stm32/quadspi.h b/include/libopencm3/stm32/quadspi.h index 99d74d9a..ef43b38c 100644 --- a/include/libopencm3/stm32/quadspi.h +++ b/include/libopencm3/stm32/quadspi.h @@ -22,6 +22,8 @@ #if defined(STM32F4) # include +#elif defined(STM32H7) +# include #else # error "quadspi.h not available for this family." #endif From ca479ad7d27daaf957d6674a779ecf2ddd02347c Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 29 Jan 2021 12:59:55 +0000 Subject: [PATCH 081/206] stm32: quadspi overhaul documentation Provide all doxygen framework boilerplate. Provide a very initial stub .c file to ensure that heirarchical headers are pulled in properly. --- .../stm32/common/quadspi_common_v1.h | 135 +++++++++--------- include/libopencm3/stm32/f4/quadspi.h | 28 +--- include/libopencm3/stm32/h7/quadspi.h | 25 +--- lib/stm32/common/quadspi_common_v1.c | 12 ++ lib/stm32/f4/Makefile | 1 + lib/stm32/h7/Makefile | 1 + 6 files changed, 98 insertions(+), 104 deletions(-) create mode 100644 lib/stm32/common/quadspi_common_v1.c diff --git a/include/libopencm3/stm32/common/quadspi_common_v1.h b/include/libopencm3/stm32/common/quadspi_common_v1.h index d0af76e0..e6af0af3 100644 --- a/include/libopencm3/stm32/common/quadspi_common_v1.h +++ b/include/libopencm3/stm32/common/quadspi_common_v1.h @@ -1,35 +1,56 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2016, Chuck McManis - * - * 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 . +/** @addtogroup quadspi_defines + * @author Chuck McManis 2016 + * @copyright SPDX: LGPL-3.0-or-later + * @{ */ -/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA quadspi.h -The order of header inclusion is important. quadspi.h includes the device -specific memorymap.h header before including this header file.*/ +#pragma once -/** @cond */ -#ifdef LIBOPENCM3_QUADSPI_H -/** @endcond */ -#ifndef LIBOPENCM3_QUADSPI_COMMON_V1_H -#define LIBOPENCM3_QUADSPI_COMMON_V1_H - -/* QUADSPI Control register */ +/** @addtogroup quadspi_registers QuadSPI Registers + * @{ + */ +/** QUADSPI Control register */ #define QUADSPI_CR MMIO32(QUADSPI_BASE + 0x0U) +/** QUADSPI Device Configuration */ +#define QUADSPI_DCR MMIO32(QUADSPI_BASE + 0x4U) + +/** QUADSPI Status Register */ +#define QUADSPI_SR MMIO32(QUADSPI_BASE + 0x8U) + +/** QUADSPI Flag Clear Register */ +#define QUADSPI_FCR MMIO32(QUADSPI_BASE + 0xCU) + +/** QUADSPI Data Length Register */ +#define QUADSPI_DLR MMIO32(QUADSPI_BASE + 0x10U) + +/** QUADSPI Communication Configuration Register */ +#define QUADSPI_CCR MMIO32(QUADSPI_BASE + 0x14U) + +/** QUADSPI address register */ +#define QUADSPI_AR MMIO32(QUADSPI_BASE + 0x18U) + +/** QUADSPI alternate bytes register */ +#define QUADSPI_ABR MMIO32(QUADSPI_BASE + 0x1CU) + +/** QUADSPI data register */ +#define QUADSPI_DR MMIO32(QUADSPI_BASE + 0x20U) +/** BYTE addressable version for fetching bytes from the interface */ +#define QUADSPI_BYTE_DR MMIO8(QUADSPI_BASE + 0x20U) + +/** QUADSPI polling status */ +#define QUADSPI_PSMKR MMIO32(QUADSPI_BASE + 0x24U) + +/** QUADSPI polling status match */ +#define QUADSPI_PSMAR MMIO32(QUADSPI_BASE + 0x28U) + +/** QUADSPI polling interval register */ +#define QUADSPI_PIR MMIO32(QUADSPI_BASE + 0x2CU) + +/** QUADSPI low power timeout */ +#define QUADSPI_LPTR MMIO32(QUADSPI_BASE + 0x30U +/**@}*/ + #define QUADSPI_CR_PRESCALE_MASK 0xff #define QUADSPI_CR_PRESCALE_SHIFT 24 #define QUADSPI_CR_PMM (1 << 23) @@ -53,9 +74,6 @@ specific memorymap.h header before including this header file.*/ #define QUADSPI_CR_ABORT (1 << 1) #define QUADSPI_CR_EN (1 << 0) -/* QUADSPI Device Configuration */ -#define QUADSPI_DCR MMIO32(QUADSPI_BASE + 0x4U) - /* bits 31:21 reserved */ #define QUADSPI_DCR_FSIZE_MASK 0x1f #define QUADSPI_DCR_FSIZE_SHIFT 16 @@ -65,9 +83,6 @@ specific memorymap.h header before including this header file.*/ /* bits 7:1 reserved */ #define QUADSPI_DCR_CKMODE (1 << 0) -/* QUADSPI Status Register */ -#define QUADSPI_SR MMIO32(QUADSPI_BASE + 0x8U) - /* bits 31:14 reserved */ #define QUADSPI_SR_FLEVEL_MASK 0x3f #define QUADSPI_SR_FLEVEL_SHIFT 8 @@ -80,9 +95,6 @@ specific memorymap.h header before including this header file.*/ #define QUADSPI_SR_TCF (1 << 1) #define QUADSPI_SR_TEF (1 << 0) -/* QUADSPI Flag Clear Register */ -#define QUADSPI_FCR MMIO32(QUADSPI_BASE + 0xCU) - /* bits 31:5 reserved */ #define QUADSPI_FCR_CTOF (1 << 4) #define QUADSPI_FCR_CSMF (1 << 3) @@ -90,12 +102,6 @@ specific memorymap.h header before including this header file.*/ #define QUADSPI_FCR_CTCF (1 << 1) #define QUADSPI_FCR_CTEF (1 << 0) -/* QUADSPI Data Length Register */ -#define QUADSPI_DLR MMIO32(QUADSPI_BASE + 0x10U) - -/* QUADSPI Communication Configuration Register */ -#define QUADSPI_CCR MMIO32(QUADSPI_BASE + 0x14U) - #define QUADSPI_CCR_DDRM (1 << 31) #define QUADSPI_CCR_DHHC (1 << 30) /* bit 29 reserved on F4, FRCM on H7 */ @@ -138,33 +144,32 @@ specific memorymap.h header before including this header file.*/ #define QUADSPI_CCR_FMODE_APOLL 2 #define QUADSPI_CCR_FMODE_MEMMAP 3 +/**@}*/ -/* QUADSPI address register */ -#define QUADSPI_AR MMIO32(QUADSPI_BASE + 0x18U) -/* QUADSPI alternate bytes register */ -#define QUADSPI_ABR MMIO32(QUADSPI_BASE + 0x1CU) +/** + * @defgroup quadspi_file QuadSPI peripheral API + * @brief APIs for the specialized SPI Flash peripheral + * @ingroup peripheral_apis + * @copyright SPDX: LGPL-3.0-or-later + * + * The QUADSPI is a specialized communication interface targeting single, + * dual or quad SPI Flash memories + * @{ + */ -/* QUADSPI data register */ -#define QUADSPI_DR MMIO32(QUADSPI_BASE + 0x20U) -/* BYTE addressable version for fetching bytes from the interface */ -#define QUADSPI_BYTE_DR MMIO8(QUADSPI_BASE + 0x20U) +BEGIN_DECLS -/* QUADSPI polling status */ -#define QUADSPI_PSMKR MMIO32(QUADSPI_BASE + 0x24U) +/** + * Enable the quadspi peripheral. + */ +void quadspi_enable(void); -/* QUADSPI polling status match */ -#define QUADSPI_PSMAR MMIO32(QUADSPI_BASE + 0x28U) +/** + * Disable the quadspi peripheral. + */ +void quadspi_disable(void); -/* QUADSPI polling interval register */ -#define QUADSPI_PIR MMIO32(QUADSPI_BASE + 0x2CU) +END_DECLS -/* QUADSPI low power timeout */ -#define QUADSPI_LPTR MMIO32(QUADSPI_BASE + 0x30U - -#endif -/** @cond */ -#else -#warning "quadspi_common_v1.h should not be included directly, only via quadspi.h" -#endif -/** @endcond */ +/**@}*/ diff --git a/include/libopencm3/stm32/f4/quadspi.h b/include/libopencm3/stm32/f4/quadspi.h index f4aff561..c5105fef 100644 --- a/include/libopencm3/stm32/f4/quadspi.h +++ b/include/libopencm3/stm32/f4/quadspi.h @@ -1,29 +1,15 @@ -/* - * STM32F4 Quad SPI defines - * - * This file is part of the libopencm3 project. - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * +/** @defgroup quadspi_defines QuadSPI Defines + * @brief Defined constants and types for the STM32F4 QuadSPI peripheral + * @ingroup STM32F4xx_defines + * @copyright SPDX: LGPL-3.0-or-later + * @{ */ -#ifndef LIBOPENCM3_QUADSPI_H -#define LIBOPENCM3_QUADSPI_H +#pragma once #include #include #define QUADSPI_CR_DMAEN (1 << 2) -#endif /* LIBOPENCM3_QUADSPI_H */ +/**@}*/ \ No newline at end of file diff --git a/include/libopencm3/stm32/h7/quadspi.h b/include/libopencm3/stm32/h7/quadspi.h index 14a2e361..eade372f 100644 --- a/include/libopencm3/stm32/h7/quadspi.h +++ b/include/libopencm3/stm32/h7/quadspi.h @@ -1,22 +1,11 @@ -/* - * This file is part of the libopencm3 project. - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . +/** @defgroup quadspi_defines QuadSPI Defines + * @brief Defined constants and types for the STM32H7 QuadSPI peripheral + * @ingroup STM32H7xx_defines + * @copyright SPDX: LGPL-3.0-or-later + * @{ */ -#ifndef LIBOPENCM3_QUADSPI_H -#define LIBOPENCM3_QUADSPI_H +#pragma once #include #include @@ -24,4 +13,4 @@ /** Enable free running clock mode, for testing */ #define QUADSPI_CCR_FRCM (1 << 29) -#endif /* LIBOPENCM3_QUADSPI_H */ +/**@}*/ \ No newline at end of file diff --git a/lib/stm32/common/quadspi_common_v1.c b/lib/stm32/common/quadspi_common_v1.c new file mode 100644 index 00000000..96e773cc --- /dev/null +++ b/lib/stm32/common/quadspi_common_v1.c @@ -0,0 +1,12 @@ + +#include + +void quadspi_enable(void) +{ + QUADSPI_CR |= QUADSPI_CR_EN; +} + +void quadspi_disable(void) +{ + QUADSPI_CR &= ~QUADSPI_CR_EN; +} \ No newline at end of file diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 2fe12925..3f59a1eb 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -64,6 +64,7 @@ OBJS += rtc_common_l1f024.o rtc.o OBJS += spi_common_all.o spi_common_v1.o spi_common_v1_frf.o OBJS += timer_common_all.o timer_common_f0234.o timer_common_f24.o OBJS += usart_common_all.o usart_common_f124.o +OBJS += quadspi_common_v1.o OBJS += usb.o usb_standard.o usb_control.o usb_msc.o OBJS += usb_hid.o diff --git a/lib/stm32/h7/Makefile b/lib/stm32/h7/Makefile index 5a930d39..5a133ec7 100644 --- a/lib/stm32/h7/Makefile +++ b/lib/stm32/h7/Makefile @@ -48,6 +48,7 @@ OBJS += rng_common_v1.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o OBJS += usart_common_v2.o usart_common_fifos.o +OBJS += quadspi_common_v1.o VPATH += ../../usb:../:../../cm3:../common From 8722a03e2fae57b1ae39fdb5ad54e2caac9f8b1d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 29 Jan 2021 14:03:46 +0000 Subject: [PATCH 082/206] stm32: enable quadspi for f7/g4/l4 Seeing as we'd started it, might as well finish enabling all the common platforms. --- include/libopencm3/stm32/f7/memorymap.h | 3 ++- include/libopencm3/stm32/f7/quadspi.h | 15 +++++++++++++++ include/libopencm3/stm32/g4/quadspi.h | 15 +++++++++++++++ include/libopencm3/stm32/l4/memorymap.h | 3 +++ include/libopencm3/stm32/l4/quadspi.h | 15 +++++++++++++++ include/libopencm3/stm32/quadspi.h | 6 ++++++ lib/stm32/f7/Makefile | 1 + lib/stm32/g4/Makefile | 1 + lib/stm32/l4/Makefile | 1 + 9 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 include/libopencm3/stm32/f7/quadspi.h create mode 100644 include/libopencm3/stm32/g4/quadspi.h create mode 100644 include/libopencm3/stm32/l4/quadspi.h diff --git a/include/libopencm3/stm32/f7/memorymap.h b/include/libopencm3/stm32/f7/memorymap.h index 5cb42128..b7bd1be4 100644 --- a/include/libopencm3/stm32/f7/memorymap.h +++ b/include/libopencm3/stm32/f7/memorymap.h @@ -146,7 +146,8 @@ #define FMC3_BASE (PERIPH_BASE_AHB3 + 0x20000000U) #define QSPI_BASE (PERIPH_BASE_AHB3 + 0x30000000U) #define FMCC_BASE (PERIPH_BASE_AHB3 + 0x40000000U) -#define QSPIC_BASE (PERIPH_BASE_AHB3 + 0x40001000U) +#define QUADSPI_BASE (PERIPH_BASE_AHB3 + 0x40001000U) +#define QSPIC_BASE QUADSPI_BASE /* Deprecated compat */ #define FMC5_BASE (PERIPH_BASE_AHB3 + 0x60000000U) #define FMC6_BASE (PERIPH_BASE_AHB3 + 0x70000000U) diff --git a/include/libopencm3/stm32/f7/quadspi.h b/include/libopencm3/stm32/f7/quadspi.h new file mode 100644 index 00000000..315c871b --- /dev/null +++ b/include/libopencm3/stm32/f7/quadspi.h @@ -0,0 +1,15 @@ +/** @defgroup quadspi_defines QuadSPI Defines + * @brief Defined constants and types for the STM32F7 QuadSPI peripheral + * @ingroup STM32F7xx_defines + * @copyright SPDX: LGPL-3.0-or-later + * @{ + */ + +#pragma once + +#include +#include + +#define QUADSPI_CR_DMAEN (1 << 2) + +/**@}*/ \ No newline at end of file diff --git a/include/libopencm3/stm32/g4/quadspi.h b/include/libopencm3/stm32/g4/quadspi.h new file mode 100644 index 00000000..eb73fced --- /dev/null +++ b/include/libopencm3/stm32/g4/quadspi.h @@ -0,0 +1,15 @@ +/** @defgroup quadspi_defines QuadSPI Defines + * @brief Defined constants and types for the STM32G4 QuadSPI peripheral + * @ingroup STM32G4xx_defines + * @copyright SPDX: LGPL-3.0-or-later + * @{ + */ + +#pragma once + +#include +#include + +#define QUADSPI_CR_DMAEN (1 << 2) + +/**@}*/ \ No newline at end of file diff --git a/include/libopencm3/stm32/l4/memorymap.h b/include/libopencm3/stm32/l4/memorymap.h index 2510466c..5cd17ffd 100644 --- a/include/libopencm3/stm32/l4/memorymap.h +++ b/include/libopencm3/stm32/l4/memorymap.h @@ -110,6 +110,9 @@ #define AES_BASE (0x50000000U + 0x60000) #define RNG_BASE (0x50000000U + 0x60800) +#define FMC_BASE (0xa0000000U) +#define QUADSPI_BASE (0xa0001000U) + /* Private peripherals */ #define DBGMCU_BASE (PPBI_BASE + 0x00042000) diff --git a/include/libopencm3/stm32/l4/quadspi.h b/include/libopencm3/stm32/l4/quadspi.h new file mode 100644 index 00000000..067c8315 --- /dev/null +++ b/include/libopencm3/stm32/l4/quadspi.h @@ -0,0 +1,15 @@ +/** @defgroup quadspi_defines QuadSPI Defines + * @brief Defined constants and types for the STM32L4 QuadSPI peripheral + * @ingroup STM32L4xx_defines + * @copyright SPDX: LGPL-3.0-or-later + * @{ + */ + +#pragma once + +#include +#include + +#define QUADSPI_CR_DMAEN (1 << 2) + +/**@}*/ \ No newline at end of file diff --git a/include/libopencm3/stm32/quadspi.h b/include/libopencm3/stm32/quadspi.h index ef43b38c..5ddcbba2 100644 --- a/include/libopencm3/stm32/quadspi.h +++ b/include/libopencm3/stm32/quadspi.h @@ -22,8 +22,14 @@ #if defined(STM32F4) # include +#elif defined(STM32F7) +# include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include +#elif defined(STM32L4) +# include #else # error "quadspi.h not available for this family." #endif diff --git a/lib/stm32/f7/Makefile b/lib/stm32/f7/Makefile index 2e41e406..33195130 100644 --- a/lib/stm32/f7/Makefile +++ b/lib/stm32/f7/Makefile @@ -63,6 +63,7 @@ OBJS += rng_common_v1.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o OBJS += usart_common_all.o usart_common_v2.o +OBJS += quadspi_common_v1.o # Ethernet OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz80x1.o diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index ba2f42e9..ddaddb73 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -47,6 +47,7 @@ OBJS += pwr.o OBJS += rcc.o rcc_common_all.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o timer_common_f0234.o +OBJS += quadspi_common_v1.o OBJS += usb.o usb_control.o usb_standard.o OBJS += usb_audio.o diff --git a/lib/stm32/l4/Makefile b/lib/stm32/l4/Makefile index 56a00838..54853ba3 100644 --- a/lib/stm32/l4/Makefile +++ b/lib/stm32/l4/Makefile @@ -54,6 +54,7 @@ OBJS += rtc_common_l1f024.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o OBJS += usart_common_all.o usart_common_v2.o +OBJS += quadspi_common_v1.o OBJS += usb.o usb_control.o usb_standard.o usb_msc.o OBJS += usb_hid.o From 5b9b784b30cebb8c28f8322496752c319710340b Mon Sep 17 00:00:00 2001 From: Jacob Potter Date: Sat, 19 Dec 2020 12:41:54 -0700 Subject: [PATCH 083/206] cm3: scb: add Cortex-M7 cache registers and bits Cortex-M7 supports a D-cache and I-cache on the AXI bus, controlled by these bits in SCB. --- include/libopencm3/cm3/scb.h | 76 ++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/include/libopencm3/cm3/scb.h b/include/libopencm3/cm3/scb.h index 4b3e4f77..aafe70c6 100644 --- a/include/libopencm3/cm3/scb.h +++ b/include/libopencm3/cm3/scb.h @@ -149,6 +149,51 @@ #define SCB_MVFR1 MMIO32(SCB_BASE + 0x244) #endif +/* Those defined only on ARMv7EM and above */ +#if defined(__ARM_ARCH_7EM__) +/** CLIDR: Cache Level ID Register */ +#define SCB_CLIDR MMIO32(SCB_BASE + 0x78) + +/** CTR: Cache Type Register */ +#define SCB_CTR MMIO32(SCB_BASE + 0x7C) + +/** CCSIDR: Cache Size ID Registers */ +#define SCB_CCSIDR MMIO32(SCB_BASE + 0x80) + +/** CSSELR: Cache Size Selection Register */ +#define SCB_CCSELR MMIO32(SCB_BASE + 0x84) + +/** ICIALLU: I-cache invalidate all to Point of Unification */ +#define SCB_ICIALLU MMIO32(SCB_BASE + 0x250) + +/** ICIMVAU: I-cache invalidate by MVA to Point of Unification */ +#define SCB_ICIMVAU MMIO32(SCB_BASE + 0x258) + +/** DCIMVAC: D-cache invalidate by MVA to Point of Coherency */ +#define SCB_DCIMVAC MMIO32(SCB_BASE + 0x25C) + +/** DCISW: D-cache invalidate by set-way */ +#define SCB_DCISW MMIO32(SCB_BASE + 0x260) + +/** DCCMVAU: D-cache clean by MVA to Point of Unification */ +#define SCB_DCCMVAU MMIO32(SCB_BASE + 0x264) + +/** DCCMVAC: D-cache clean by MVA to Point of Coherency */ +#define SCB_DCCMVAC MMIO32(SCB_BASE + 0x268) + +/** DCISW: D-cache clean by set-way */ +#define SCB_DCCSW MMIO32(SCB_BASE + 0x26C) + +/** DCCIMVAC: D-cache clean and invalidate by MVA to Point of Coherency */ +#define SCB_DCCIMVAC MMIO32(SCB_BASE + 0x270) + +/** DCCISW: D-cache clean and invalidate by set-way */ +#define SCB_DCCISW MMIO32(SCB_BASE + 0x274) + +/** BPIALL: Branch predictor invalidate all */ +#define SCB_BPIALL MMIO32(SCB_BASE + 0x278) +#endif + /**@}*/ /* --- SCB values ---------------------------------------------------------- */ @@ -320,6 +365,17 @@ /** NONBASETHRDENA set to allow non base priority threads */ #define SCB_CCR_NONBASETHRDENA (1 << 0) #endif + +/* Those defined only on ARMv7EM and above */ +#if defined(__ARM_ARCH_7EM__) +/** BP set to enable branch predictor */ +#define SCB_CCR_BP (1 << 18) +/** IC set to enable instruction cache */ +#define SCB_CCR_IC (1 << 17) +/** DC set to enable data cache */ +#define SCB_CCR_DC (1 << 16) +#endif + /**@}*/ /* These numbers are designed to be used with the SCB_SHPR() macro */ @@ -443,6 +499,26 @@ /* BFAR [31:0]: Bus fault address */ +#if defined(__ARM_ARCH_7EM__) +/* --- SCB_CTR values ------------------------------------------------------ */ +/* FORMAT: implemented CTR format */ +#define SCB_CTR_FORMAT_SHIFT 29 +#define SCB_CTR_FORMAT_MASK 0x7 +/* CWG: Cache Write-back Granule */ +#define SCB_CTR_CWG_SHIFT 24 +#define SCB_CTR_CWG_MASK 0xf +/* ERG: Exclusives Reservation Granule */ +#define SCB_CTR_ERG_SHIFT 20 +#define SCB_CTR_ERG_MASK 0xf +/* DMINLINE: log2 of number of words in smallest cache line of all data caches */ +#define SCB_CTR_DMINLINE_SHIFT 16 +#define SCB_CTR_DMINLINE_MASK 0x1f +/* IMINLINE: log2 of number of words in smallest cache line of all instruction caches */ +#define SCB_CTR_IMINLINE_SHIFT 0 +#define SCB_CTR_IMINLINE_MASK 0xf + +#endif + /* --- SCB_CPACR values ---------------------------------------------------- */ /* CPACR CPn: Access privileges values */ From d11680638bdbe4f618003b524ff65c472bbfb97d Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sun, 26 Apr 2020 07:49:06 +0200 Subject: [PATCH 084/206] sam:d: port: complete port (define, configuration and access) --- include/libopencm3/sam/d/port.h | 219 ++++++++++++++++++++++++++++++++ lib/sam/d/port.c | 184 +++++++++++++++++++++++++++ 2 files changed, 403 insertions(+) create mode 100644 lib/sam/d/port.c diff --git a/include/libopencm3/sam/d/port.h b/include/libopencm3/sam/d/port.h index 92ba7f17..759f9e6e 100644 --- a/include/libopencm3/sam/d/port.h +++ b/include/libopencm3/sam/d/port.h @@ -1,7 +1,16 @@ +/** @defgroup gpio_defines + * + * #ingroup SAMD_defines + * + * @brief Defined Constants and Types for the SAMD Port controler + * + * LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * * Copyright (C) 2016 Karl Palsson + * Copyright (C) 2020 Gwenhael Goavec-Merou * * 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 @@ -19,13 +28,72 @@ #pragma once +/**@{*/ + #include +#include /* --- Convenience macros ------------------------------------------------ */ #define PORTA (PORT_BASE + 0) #define PORTB (PORT_BASE + 0x80) +/* GPIO number definitions (for convenience) */ +/** @defgroup gpio_pin_id GPIO Pin Identifiers +@ingroup gpio_defines +@{*/ +#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 GPIO16 (1 << 16) +#define GPIO17 (1 << 17) +#define GPIO18 (1 << 18) +#define GPIO19 (1 << 19) +#define GPIO20 (1 << 20) +#define GPIO21 (1 << 21) +#define GPIO22 (1 << 22) +#define GPIO23 (1 << 23) +#define GPIO24 (1 << 24) +#define GPIO25 (1 << 25) +#define GPIO26 (1 << 26) +#define GPIO27 (1 << 27) +#define GPIO28 (1 << 28) +#define GPIO29 (1 << 29) +#define GPIO30 (1 << 30) +#define GPIO31 (1 << 31) +#define GPIO_ALL 0xffff +/**@}*/ + +/* GPIO mux definitions (for convenience) */ +/** @defgroup gpio_mux GPIO mux configuration +@ingroup gpio_mux +@{*/ +enum port_mux { + PORT_PMUX_FUN_A = 0, + PORT_PMUX_FUN_B, + PORT_PMUX_FUN_C, + PORT_PMUX_FUN_D, + PORT_PMUX_FUN_E, + PORT_PMUX_FUN_F, + PORT_PMUX_FUN_G, + PORT_PMUX_FUN_H, + PORT_PMUX_FUN_I +}; +/**@}*/ + /* --- PORT registers ----------------------------------------------------- */ /* Direction register */ @@ -66,3 +134,154 @@ /* Pin configuration registers */ #define PORT_PINCFG(port, n) MMIO8((port) + 0x0040 + (n)) + +/* --- PORTx_DIR values ---------------------------------------------------- */ + +/* PORTx_DIR[31:0]: DIRy[31:0]: Port x set bit y direction [y=0..31] */ + +/* --- PORTx_DIRCLR values ------------------------------------------------- */ + +/* PORTx_DIRCLR[31:0]: DIRCLRy[31:0]: Port x set bit y as input [y=0..31] */ + +/* --- PORTx_DIRSET values ------------------------------------------------- */ + +/* PORTx_DIRSET[31:0]: DIRSETy[31:0]: Port x set bit y as output [y=0..31] */ + +/* --- PORTx_DIRTGL values ------------------------------------------------- */ + +/* PORTx_DIRTGL[31:0]: DIRTGLy[31:0]: Port x toggle bit y direction [y=0..31] */ + +/* --- PORTx_OUT values ---------------------------------------------------- */ + +/* PORTx_OUT[31:0]: OUTy[31:0]: Port output data [y=0..31] */ + +/* --- PORTx_OUTCLR values ------------------------------------------------- */ + +/* PORTx_OUTCLR[31:0]: OUTCLRy[31:0]: Port x reset bit y [y=0..31] */ + +/* --- PORTx_OUTSET values ------------------------------------------------- */ + +/* PORTx_OUTSET[31:0]: OUTSETy[31:0]: Port x set bit y [y=0..31] */ + +/* --- PORTx_OUTTGL values ------------------------------------------------- */ + +/* PORTx_OUTTGL[31:0]: OUTTGLy[31:0]: Port x toggle bit y [y=0..31] */ + +/* --- PORTx_IN values ----------------------------------------------------- */ + +/* PORTx_IN[31:0]: INy[31:0]: Port input data [y=0..31] */ + +/* --- PORTx_CTRL values --------------------------------------------------- */ + +/* PORTx_CTRL[31:0]: CTRLy[31:0]: Port input sampling mode [y=0..31] */ + +/* --- PORTx_WRCONFIG values ----------------------------------------------- */ + +/* HWSEL: Half word select: 0 [15:0], 1 [31:16] */ +#define PORT_WRCONFIG_HWSEL (1 << 31) + +/* WRPINCFG: Write PINCFG: 1 to update pins for selected by PINMASK */ +#define PORT_WRCONFIG_WRPINCFG (1 << 30) + +/* Bit 29: Reserved */ + +/* WRPMUX: Write PMUX: 1 to update pins pmux for selected by PINMASK */ +#define PORT_WRCONFIG_WRPMUX (1 << 28) + +/* PMUX: Peripheral Multiplexing: determine pmux for pins selected by PINMASK */ +#define PORT_WRCONFIG_PMUX(mux) ((0xf & (mux)) << 24) + +/* Bit 23: Reserved */ + +/* DRVSTR: Output Driver Strength Selection: determine strength for pins in PINMASK */ +#define PORT_WRCONFIG_DRVSTR (1 << 22) + +/* Bit [21:19]: Reserved */ + +/* PULLEN: Pull Enable: enable PINCFGy.PULLEN for pins in PINMASK */ +#define PORT_WRCONFIG_PULLEN (1 << 18) + +/* INEN: Input Enable: enable PINCFGy.INEN for pins in PINMASK */ +#define PORT_WRCONFIG_INEN (1 << 17) + +/* PMUXEN: Peripheral Multiplexer Enable: enable PINCFGy.PMUXEN for pins in PINMASK */ +#define PORT_WRCONFIG_PMUXEN (1 << 16) + +/* PINMASK: Pin Mask for Multiple Pin Configuration: select pins to be configured + * [31:16] if HWSET=1, [15:0] if HWSET=0 + */ +#define PORT_WRCONFIG_PINMASK(pins) ((0xffff & (pins)) << 0) + +/* --- PORTx_PMUX values --------------------------------------------------- */ + +/* PMUXO: Peripheral Multiplexing for Odd-Numbered Pin: 2*x+1 pin multiplexing */ +#define PORT_PMUX_PMUXO(mux) ((0xf & (mux)) << 4) + +/* PMUXE: Peripheral Multiplexing for Even-Numbered Pin: 2*x pin multiplexing */ +#define PORT_PMUX_PMUXE(mux) ((0xf & (mux)) << 0) + +/* --- PORTx_PINCFGy values ------------------------------------------------ */ + +/* Bit 7: Reserved */ + +/* DRVSTR: Output Driver Strength Selection */ +#define PORT_PINCFG_DRVSTR (1 << 6) + +/* Bit [5:3]: Reserved */ + +/* PULLEN: Pull Enable */ +#define PORT_PINCFG_PULLEN (1 << 2) + +/* INEN: Input Enable */ +#define PORT_PINCFG_INEN (1 << 1) + +/* PMUXEN: Peripheral Multiplexer Enable */ +#define PORT_PINCFG_PMUXEN (1 << 0) + +/* --- Convenience enums --------------------------------------------------- */ + +/* GPIO mode definitions (for convenience) */ +/** @defgroup gpio_direction GPIO Pin direction +@ingroup gpio_defines +@li Input +@li Output +@li InOut +@{*/ +#define GPIO_MODE_INPUT 0x00 +#define GPIO_MODE_OUTPUT 0x01 +#define GPIO_MODE_INOUT 0x02 +/**@}*/ + +/** @defgroup gpio_cnf GPIO mode configuration +@ingroup gpio_defines +@li Float +@li PullDown +@li PullUp +@li Alternate Function +@{*/ +#define GPIO_CNF_FLOAT 0x00 +#define GPIO_CNF_PULLDOWN 0x01 +#define GPIO_CNF_PULLUP 0x02 +#define GPIO_CNF_AF 0x03 +/**@}*/ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint32_t gpios); +void gpio_set_af(uint32_t gpioport, uint8_t af, uint32_t gpios); + +/** @ingroup gpio_control + * @{ */ + +void gpio_set(uint32_t gpioport, uint32_t gpios); +void gpio_clear(uint32_t gpioport, uint32_t gpios); +uint32_t gpio_get(uint32_t gpioport, uint32_t gpios); +void gpio_toggle(uint32_t gpioport, uint32_t gpios); +uint32_t port_read(uint32_t port); +void port_write(uint32_t port, uint32_t data); + +END_DECLS + +/**@}*/ diff --git a/lib/sam/d/port.c b/lib/sam/d/port.c new file mode 100644 index 00000000..ac3a8faf --- /dev/null +++ b/lib/sam/d/port.c @@ -0,0 +1,184 @@ +/** @defgroup gpio_defines + * + * @ingroup SAMD + * + * @brief Access functions for the SAMD I/O Controller + * + * @date 10 April 2020 + * + * LGPL License Terms @ref lgpl_license + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2020 Gwenhael Goavec-Merou + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/** @brief Initialize GPIO pins + * + * Configure a group of Pins for the given port. + * + * @param[in] gpioport port register address base @ref port_reg_base + * @param[in] mode direction @ref gpio_direction + * @param[in] cnf configuration mode @ref gpio_cnf + * @param[in] gpios Any combinaison of pins may be + * specified by OR'ing then together. + */ + +void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint32_t gpios) +{ + uint32_t reg = PORT_WRCONFIG_WRPINCFG; + /* enable pull */ + if (cnf == GPIO_CNF_PULLDOWN || cnf == GPIO_CNF_PULLUP) + reg |= PORT_WRCONFIG_PULLEN; + /* enable input buffer */ + if (mode != GPIO_MODE_OUTPUT) + reg |= PORT_WRCONFIG_INEN; + /* set pmuxen */ + if (cnf == GPIO_CNF_AF) + reg |= PORT_WRCONFIG_PMUXEN; + + /* PORTx_WRCONFIG allows to configure pins [31:16] or [15:0] */ + /* write low pins */ + PORT_WRCONFIG(gpioport) = reg | PORT_WRCONFIG_PINMASK(gpios); + /* write high pins */ + PORT_WRCONFIG(gpioport) = reg | PORT_WRCONFIG_HWSEL | + PORT_WRCONFIG_PINMASK(gpios >> 16); + + /* configure port direction for selected gpios */ + /* DIR is always 0 when PULL */ + if (cnf == GPIO_CNF_PULLDOWN || cnf == GPIO_CNF_PULLUP) + PORT_DIRCLR(gpioport) = gpios; + else if (mode == GPIO_MODE_INPUT) + PORT_DIRCLR(gpioport) = gpios; + else + PORT_DIRSET(gpioport) = gpios; + + /* PULL UP/DOWN is configured through OUT */ + if (cnf == GPIO_CNF_PULLDOWN) + PORT_OUTCLR(gpioport) = gpios; + else if (cnf == GPIO_CNF_PULLUP) + PORT_OUTSET(gpioport) = gpios; +} + +/** @brief Alternate function GPIO pins + * + * Configure a group of Pins in alternate function. + * + * @param[in] gpioport port register address base @ref port_reg_base + * @param[in] af pmux configuration @ref gpio_mux + * @param[in] gpios Any combinaison of pins may be + * specified by OR'ing then together. + */ +void gpio_set_af(uint32_t gpioport, uint8_t af, uint32_t gpios) +{ + uint32_t reg = PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_PMUX(af) | + PORT_WRCONFIG_PMUXEN; + + /* write gpios[15:0] */ + PORT_WRCONFIG(gpioport) = reg | PORT_WRCONFIG_PINMASK(gpios); + + /* write gpios[31:16] */ + PORT_WRCONFIG(gpioport) = reg | PORT_WRCONFIG_HWSEL | + PORT_WRCONFIG_PINMASK(gpios >> 16); +} + +/** @brief Set a group of Pins + * + * Set a group of Pins for the given port. + * + * @param[in] gpioport port register address base @ref port_reg_base + * @param[in] gpios @ref gpio_defines. Any combinaison of pins may be + * specified by OR'ing then together. + */ +void gpio_set(uint32_t gpioport, uint32_t gpios) +{ + PORT_OUTSET(gpioport) = gpios; +} + +/** @brief Clear a group of Pins + * + * Clear a group of Pins for the given port. + * + * @param[in] gpioport port register address base @ref port_reg_base + * @param[in] gpios @ref gpio_defines. Any combinaison of pins may be + * specified by OR'ing then together. + */ +void gpio_clear(uint32_t gpioport, uint32_t gpios) +{ + PORT_OUTCLR(gpioport) = gpios; +} + +/** @brief Read level of a group of Pins + * + * Read the level of a group of Pins for the given port. + * + * @param[in] gpioport port register address base @ref port_reg_base + * @param[in] gpios @ref gpio_defines. Any combinaison of pins may be + * specified by OR'ing then together. + */ +uint32_t gpio_get(uint32_t gpioport, uint32_t gpios) +{ + return PORT_IN(gpioport) & gpios; +} + +/** @brief Toggle level of a group of Pins + * + * Toggle one or more pins of the givent port. + * + * @param[in] gpioport port register address base @ref port_reg_base + * @param[in] gpios @ref gpio_defines. Any combinaison of pins may be + * specified by OR'ing then together. + */ +void gpio_toggle(uint32_t gpioport, uint32_t gpios) +{ + PORT_OUTTGL(gpioport) = gpios; +} + +/** @brief Read level for all pins from a port + * + * Read the level of all pins of the given port. + * + * @param[in] port register address base @ref port_reg_base + * + * @return The level of all pins on the port. + */ +uint32_t port_read(uint32_t port) +{ + return PORT_IN(port); +} + +/** @brief Set level for all pins from a port + * + * Set the level of all pins of the given port. + * + * @param[in] port register address base @ref port_reg_base + * @param[in] data @ref gpio_defines. Any combinaison of pins + * may be specified by OR'ing then together. + */ +void port_write(uint32_t port, uint32_t data) +{ + PORT_OUT(port) = data; +} + +/**@}*/ From b57dbc54291543e817dcb41c2873260875ca86b9 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 3 Feb 2021 22:40:06 +0000 Subject: [PATCH 085/206] samd: enable new port file --- lib/sam/d/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/sam/d/Makefile b/lib/sam/d/Makefile index 380ade30..e184cc28 100644 --- a/lib/sam/d/Makefile +++ b/lib/sam/d/Makefile @@ -31,6 +31,8 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs OBJS = +OBJS += port.o + VPATH += ../../cm3:../common include ../../Makefile.include From 458a0553a86c4f843ad9252c8a07c7566aaef7be Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 3 Feb 2021 23:06:49 +0000 Subject: [PATCH 086/206] samd: overhaul doxygen --- include/libopencm3/sam/d/doc-samd.h | 8 ++ include/libopencm3/sam/d/port.h | 119 ++++++++++------------------ lib/sam/d/port.c | 32 +------- 3 files changed, 54 insertions(+), 105 deletions(-) create mode 100644 include/libopencm3/sam/d/doc-samd.h diff --git a/include/libopencm3/sam/d/doc-samd.h b/include/libopencm3/sam/d/doc-samd.h new file mode 100644 index 00000000..224f5bd7 --- /dev/null +++ b/include/libopencm3/sam/d/doc-samd.h @@ -0,0 +1,8 @@ +/** @defgroup peripheral_apis Peripheral APIs + * APIs for device peripherals + */ + +/** @defgroup SAMD_defines SAMD Defines + * Defined Constants and Types for the SAMD series. + * @copyright SPDX: LGPL-3.0-or-later + */ diff --git a/include/libopencm3/sam/d/port.h b/include/libopencm3/sam/d/port.h index 759f9e6e..860c63ee 100644 --- a/include/libopencm3/sam/d/port.h +++ b/include/libopencm3/sam/d/port.h @@ -1,29 +1,12 @@ -/** @defgroup gpio_defines +/** @defgroup port_defines IO Port Definitions * - * #ingroup SAMD_defines + * @ingroup SAMD_defines * - * @brief Defined Constants and Types for the SAMD Port controler + * @brief Defined Constants and Types for the SAMD Port controller * - * LGPL License Terms @ref lgpl_license - */ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2016 Karl Palsson - * Copyright (C) 2020 Gwenhael Goavec-Merou - * - * 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 . + * @copyright SPDX: LGPL-3.0-or-later + * @author 2016 Karl Palsson + * @author 2020 Gwenhael Goavec-Merou */ #pragma once @@ -40,7 +23,6 @@ /* GPIO number definitions (for convenience) */ /** @defgroup gpio_pin_id GPIO Pin Identifiers -@ingroup gpio_defines @{*/ #define GPIO0 (1 << 0) #define GPIO1 (1 << 1) @@ -79,7 +61,6 @@ /* GPIO mux definitions (for convenience) */ /** @defgroup gpio_mux GPIO mux configuration -@ingroup gpio_mux @{*/ enum port_mux { PORT_PMUX_FUN_A = 0, @@ -94,46 +75,48 @@ enum port_mux { }; /**@}*/ -/* --- PORT registers ----------------------------------------------------- */ - -/* Direction register */ +/** @defgroup port_registers PORT Registers + * @{ + */ +/** Direction register */ #define PORT_DIR(port) MMIO32((port) + 0x0000) -/* Direction clear register */ +/** Direction clear register */ #define PORT_DIRCLR(port) MMIO32((port) + 0x0004) -/* Direction set register */ +/** Direction set register */ #define PORT_DIRSET(port) MMIO32((port) + 0x0008) -/* Direction toggle register */ +/** Direction toggle register */ #define PORT_DIRTGL(port) MMIO32((port) + 0x000c) -/* output register */ +/** output register */ #define PORT_OUT(port) MMIO32((port) + 0x0010) -/* output clear register */ +/** output clear register */ #define PORT_OUTCLR(port) MMIO32((port) + 0x0014) -/* output set register */ +/** output set register */ #define PORT_OUTSET(port) MMIO32((port) + 0x0018) -/* output toggle register */ +/** output toggle register */ #define PORT_OUTTGL(port) MMIO32((port) + 0x001c) -/* input register */ +/** input register */ #define PORT_IN(port) MMIO32((port) + 0x0020) -/* Control register */ +/** Control register */ #define PORT_CTRL(port) MMIO32((port) + 0x0024) -/* Write configuration register */ +/** Write configuration register */ #define PORT_WRCONFIG(port) MMIO32((port) + 0x0028) -/* Peripheral multiplexing registers */ +/** Peripheral multiplexing registers */ #define PORT_PMUX(port, n) MMIO8((port) + 0x0030 + (n)) -/* Pin configuration registers */ +/** Pin configuration registers */ #define PORT_PINCFG(port, n) MMIO8((port) + 0x0040 + (n)) +/**@}*/ /* --- PORTx_DIR values ---------------------------------------------------- */ @@ -175,77 +158,66 @@ enum port_mux { /* PORTx_CTRL[31:0]: CTRLy[31:0]: Port input sampling mode [y=0..31] */ -/* --- PORTx_WRCONFIG values ----------------------------------------------- */ - -/* HWSEL: Half word select: 0 [15:0], 1 [31:16] */ +/**@defgroup port_wrconfig_values PortX WRCONFIG Values + * @{ + */ +/** HWSEL: Half word select: 0 [15:0], 1 [31:16] */ #define PORT_WRCONFIG_HWSEL (1 << 31) -/* WRPINCFG: Write PINCFG: 1 to update pins for selected by PINMASK */ +/** WRPINCFG: Write PINCFG: 1 to update pins for selected by PINMASK */ #define PORT_WRCONFIG_WRPINCFG (1 << 30) -/* Bit 29: Reserved */ - -/* WRPMUX: Write PMUX: 1 to update pins pmux for selected by PINMASK */ +/** WRPMUX: Write PMUX: 1 to update pins pmux for selected by PINMASK */ #define PORT_WRCONFIG_WRPMUX (1 << 28) -/* PMUX: Peripheral Multiplexing: determine pmux for pins selected by PINMASK */ +/** PMUX: Peripheral Multiplexing: determine pmux for pins selected by PINMASK */ #define PORT_WRCONFIG_PMUX(mux) ((0xf & (mux)) << 24) -/* Bit 23: Reserved */ - -/* DRVSTR: Output Driver Strength Selection: determine strength for pins in PINMASK */ +/** DRVSTR: Output Driver Strength Selection: determine strength for pins in PINMASK */ #define PORT_WRCONFIG_DRVSTR (1 << 22) -/* Bit [21:19]: Reserved */ - -/* PULLEN: Pull Enable: enable PINCFGy.PULLEN for pins in PINMASK */ +/** PULLEN: Pull Enable: enable PINCFGy.PULLEN for pins in PINMASK */ #define PORT_WRCONFIG_PULLEN (1 << 18) -/* INEN: Input Enable: enable PINCFGy.INEN for pins in PINMASK */ +/** INEN: Input Enable: enable PINCFGy.INEN for pins in PINMASK */ #define PORT_WRCONFIG_INEN (1 << 17) -/* PMUXEN: Peripheral Multiplexer Enable: enable PINCFGy.PMUXEN for pins in PINMASK */ +/** PMUXEN: Peripheral Multiplexer Enable: enable PINCFGy.PMUXEN for pins in PINMASK */ #define PORT_WRCONFIG_PMUXEN (1 << 16) -/* PINMASK: Pin Mask for Multiple Pin Configuration: select pins to be configured +/** PINMASK: Pin Mask for Multiple Pin Configuration: select pins to be configured * [31:16] if HWSET=1, [15:0] if HWSET=0 */ #define PORT_WRCONFIG_PINMASK(pins) ((0xffff & (pins)) << 0) +/**@}*/ /* --- PORTx_PMUX values --------------------------------------------------- */ -/* PMUXO: Peripheral Multiplexing for Odd-Numbered Pin: 2*x+1 pin multiplexing */ +/** PMUXO: Peripheral Multiplexing for Odd-Numbered Pin: 2*x+1 pin multiplexing */ #define PORT_PMUX_PMUXO(mux) ((0xf & (mux)) << 4) -/* PMUXE: Peripheral Multiplexing for Even-Numbered Pin: 2*x pin multiplexing */ +/** PMUXE: Peripheral Multiplexing for Even-Numbered Pin: 2*x pin multiplexing */ #define PORT_PMUX_PMUXE(mux) ((0xf & (mux)) << 0) /* --- PORTx_PINCFGy values ------------------------------------------------ */ /* Bit 7: Reserved */ -/* DRVSTR: Output Driver Strength Selection */ +/** DRVSTR: Output Driver Strength Selection */ #define PORT_PINCFG_DRVSTR (1 << 6) -/* Bit [5:3]: Reserved */ - -/* PULLEN: Pull Enable */ +/** PULLEN: Pull Enable */ #define PORT_PINCFG_PULLEN (1 << 2) -/* INEN: Input Enable */ +/** INEN: Input Enable */ #define PORT_PINCFG_INEN (1 << 1) -/* PMUXEN: Peripheral Multiplexer Enable */ +/** PMUXEN: Peripheral Multiplexer Enable */ #define PORT_PINCFG_PMUXEN (1 << 0) /* --- Convenience enums --------------------------------------------------- */ -/* GPIO mode definitions (for convenience) */ /** @defgroup gpio_direction GPIO Pin direction -@ingroup gpio_defines -@li Input -@li Output -@li InOut @{*/ #define GPIO_MODE_INPUT 0x00 #define GPIO_MODE_OUTPUT 0x01 @@ -253,7 +225,6 @@ enum port_mux { /**@}*/ /** @defgroup gpio_cnf GPIO mode configuration -@ingroup gpio_defines @li Float @li PullDown @li PullUp @@ -265,16 +236,10 @@ enum port_mux { #define GPIO_CNF_AF 0x03 /**@}*/ -/* --- Function prototypes ------------------------------------------------- */ - BEGIN_DECLS void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint32_t gpios); void gpio_set_af(uint32_t gpioport, uint8_t af, uint32_t gpios); - -/** @ingroup gpio_control - * @{ */ - void gpio_set(uint32_t gpioport, uint32_t gpios); void gpio_clear(uint32_t gpioport, uint32_t gpios); uint32_t gpio_get(uint32_t gpioport, uint32_t gpios); diff --git a/lib/sam/d/port.c b/lib/sam/d/port.c index ac3a8faf..5a1ed449 100644 --- a/lib/sam/d/port.c +++ b/lib/sam/d/port.c @@ -1,32 +1,9 @@ -/** @defgroup gpio_defines - * - * @ingroup SAMD - * +/** @addtogroup port_file IO Port API + * @ingroup peripheral_apis * @brief Access functions for the SAMD I/O Controller - * * @date 10 April 2020 - * - * LGPL License Terms @ref lgpl_license - * - */ - -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2020 Gwenhael Goavec-Merou - * - * 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 . + * @copyright SPDX: LGPL-3.0-or-later + * @author 2020 Gwenhael Goavec-Merou */ /**@{*/ @@ -43,7 +20,6 @@ * @param[in] gpios Any combinaison of pins may be * specified by OR'ing then together. */ - void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint32_t gpios) { uint32_t reg = PORT_WRCONFIG_WRPINCFG; From 49327dcdc4854af86370742b5c746d7eecad26f3 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 3 Feb 2021 23:13:00 +0000 Subject: [PATCH 087/206] samd: port: fix coding style We always use braces. --- lib/sam/d/port.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/sam/d/port.c b/lib/sam/d/port.c index 5a1ed449..a42c3585 100644 --- a/lib/sam/d/port.c +++ b/lib/sam/d/port.c @@ -24,14 +24,17 @@ void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint32_t gpio { uint32_t reg = PORT_WRCONFIG_WRPINCFG; /* enable pull */ - if (cnf == GPIO_CNF_PULLDOWN || cnf == GPIO_CNF_PULLUP) + if (cnf == GPIO_CNF_PULLDOWN || cnf == GPIO_CNF_PULLUP) { reg |= PORT_WRCONFIG_PULLEN; + } /* enable input buffer */ - if (mode != GPIO_MODE_OUTPUT) + if (mode != GPIO_MODE_OUTPUT) { reg |= PORT_WRCONFIG_INEN; + } /* set pmuxen */ - if (cnf == GPIO_CNF_AF) + if (cnf == GPIO_CNF_AF) { reg |= PORT_WRCONFIG_PMUXEN; + } /* PORTx_WRCONFIG allows to configure pins [31:16] or [15:0] */ /* write low pins */ @@ -42,18 +45,20 @@ void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint32_t gpio /* configure port direction for selected gpios */ /* DIR is always 0 when PULL */ - if (cnf == GPIO_CNF_PULLDOWN || cnf == GPIO_CNF_PULLUP) + if (cnf == GPIO_CNF_PULLDOWN || cnf == GPIO_CNF_PULLUP) { PORT_DIRCLR(gpioport) = gpios; - else if (mode == GPIO_MODE_INPUT) + } else if (mode == GPIO_MODE_INPUT) { PORT_DIRCLR(gpioport) = gpios; - else + } else { PORT_DIRSET(gpioport) = gpios; + } /* PULL UP/DOWN is configured through OUT */ - if (cnf == GPIO_CNF_PULLDOWN) + if (cnf == GPIO_CNF_PULLDOWN) { PORT_OUTCLR(gpioport) = gpios; - else if (cnf == GPIO_CNF_PULLUP) + } else if (cnf == GPIO_CNF_PULLUP) { PORT_OUTSET(gpioport) = gpios; + } } /** @brief Alternate function GPIO pins From 7b88c2d9d295ef3a65497b2de344b14fa056d0b6 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 3 Feb 2021 23:22:52 +0000 Subject: [PATCH 088/206] samd: doc: links and spelling Fixes all doxygen warnings for samd. yay --- include/libopencm3/sam/d/port.h | 4 ++++ lib/sam/d/port.c | 18 +++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/include/libopencm3/sam/d/port.h b/include/libopencm3/sam/d/port.h index 860c63ee..5c4a2f20 100644 --- a/include/libopencm3/sam/d/port.h +++ b/include/libopencm3/sam/d/port.h @@ -18,8 +18,12 @@ /* --- Convenience macros ------------------------------------------------ */ +/**@defgroup port_reg_base Port Base registers + * @{ + */ #define PORTA (PORT_BASE + 0) #define PORTB (PORT_BASE + 0x80) +/**@}*/ /* GPIO number definitions (for convenience) */ /** @defgroup gpio_pin_id GPIO Pin Identifiers diff --git a/lib/sam/d/port.c b/lib/sam/d/port.c index a42c3585..632ea195 100644 --- a/lib/sam/d/port.c +++ b/lib/sam/d/port.c @@ -17,8 +17,8 @@ * @param[in] gpioport port register address base @ref port_reg_base * @param[in] mode direction @ref gpio_direction * @param[in] cnf configuration mode @ref gpio_cnf - * @param[in] gpios Any combinaison of pins may be - * specified by OR'ing then together. + * @param[in] gpios @ref gpio_pin_id. Any combination of pins + * may be specified by OR'ing then together. */ void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint32_t gpios) { @@ -67,8 +67,8 @@ void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t cnf, uint32_t gpio * * @param[in] gpioport port register address base @ref port_reg_base * @param[in] af pmux configuration @ref gpio_mux - * @param[in] gpios Any combinaison of pins may be - * specified by OR'ing then together. + * @param[in] gpios @ref gpio_pin_id. Any combination of pins + * may be specified by OR'ing then together. */ void gpio_set_af(uint32_t gpioport, uint8_t af, uint32_t gpios) { @@ -89,7 +89,7 @@ void gpio_set_af(uint32_t gpioport, uint8_t af, uint32_t gpios) * Set a group of Pins for the given port. * * @param[in] gpioport port register address base @ref port_reg_base - * @param[in] gpios @ref gpio_defines. Any combinaison of pins may be + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be * specified by OR'ing then together. */ void gpio_set(uint32_t gpioport, uint32_t gpios) @@ -102,7 +102,7 @@ void gpio_set(uint32_t gpioport, uint32_t gpios) * Clear a group of Pins for the given port. * * @param[in] gpioport port register address base @ref port_reg_base - * @param[in] gpios @ref gpio_defines. Any combinaison of pins may be + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be * specified by OR'ing then together. */ void gpio_clear(uint32_t gpioport, uint32_t gpios) @@ -115,7 +115,7 @@ void gpio_clear(uint32_t gpioport, uint32_t gpios) * Read the level of a group of Pins for the given port. * * @param[in] gpioport port register address base @ref port_reg_base - * @param[in] gpios @ref gpio_defines. Any combinaison of pins may be + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be * specified by OR'ing then together. */ uint32_t gpio_get(uint32_t gpioport, uint32_t gpios) @@ -128,7 +128,7 @@ uint32_t gpio_get(uint32_t gpioport, uint32_t gpios) * Toggle one or more pins of the givent port. * * @param[in] gpioport port register address base @ref port_reg_base - * @param[in] gpios @ref gpio_defines. Any combinaison of pins may be + * @param[in] gpios @ref gpio_pin_id. Any combination of pins may be * specified by OR'ing then together. */ void gpio_toggle(uint32_t gpioport, uint32_t gpios) @@ -154,7 +154,7 @@ uint32_t port_read(uint32_t port) * Set the level of all pins of the given port. * * @param[in] port register address base @ref port_reg_base - * @param[in] data @ref gpio_defines. Any combinaison of pins + * @param[in] data @ref gpio_pin_id. Any combination of pins * may be specified by OR'ing then together. */ void port_write(uint32_t port, uint32_t data) From c2dbea012bb8be917f6cd4158892919cd98cadda Mon Sep 17 00:00:00 2001 From: Brian Viele Date: Wed, 3 Feb 2021 17:21:09 -0500 Subject: [PATCH 089/206] stm32h7: Updated pwr and rcc configs to support devices with SMPS. Worked in nuances for differences between versions of STM32H7 devices, such as handling of ODEN, explicit SCUEN bit, and different VOS mappings. This has been validated on the STM32H7A3 and STM32H743 MCUs. --- include/libopencm3/stm32/h7/memorymap.h | 3 + include/libopencm3/stm32/h7/pwr.h | 148 +++++++++++++++++++++--- include/libopencm3/stm32/h7/rcc.h | 4 +- lib/stm32/h7/pwr.c | 122 +++++++++++++++++-- lib/stm32/h7/rcc.c | 4 +- 5 files changed, 252 insertions(+), 29 deletions(-) diff --git a/include/libopencm3/stm32/h7/memorymap.h b/include/libopencm3/stm32/h7/memorymap.h index ec892d21..875b28e3 100644 --- a/include/libopencm3/stm32/h7/memorymap.h +++ b/include/libopencm3/stm32/h7/memorymap.h @@ -154,4 +154,7 @@ #define TIM3_BASE 0x40000400U #define TIM2_BASE 0x40000000U +/* Debug/Trace Peripherals */ +#define DBGMCU_BASE 0x5C001000U + #endif diff --git a/include/libopencm3/stm32/h7/pwr.h b/include/libopencm3/stm32/h7/pwr.h index 714d6436..70c6d8fa 100644 --- a/include/libopencm3/stm32/h7/pwr.h +++ b/include/libopencm3/stm32/h7/pwr.h @@ -47,8 +47,12 @@ LGPL License Terms @ref lgpl_license /** CPU Power control register 3. */ #define PWR_CPUCR MMIO32(POWER_CONTROL_BASE + 0x10) -/** D3 Domain Power Control register. */ +/** D3 Domain Power Control register. + * Note: Referred to as PWR_SRDCR (SmartRun Domain Control) on LP devices. + * The VOS bitfield differs between the two implementations (unfortunately). + */ #define PWR_D3CR MMIO32(POWER_CONTROL_BASE + 0x18) +#define PWR_SRDCR MMIO32(POWER_CONTROL_BASE + 0x18) /** Wakeup Domain Power Control register. */ #define PWR_WKUPCR MMIO32(POWER_CONTROL_BASE + 0x20) @@ -57,39 +61,133 @@ LGPL License Terms @ref lgpl_license /** VOS[15:14]: Regulator voltage scaling output selection */ #define PWR_CR1_SVOS_SHIFT 14 +#define PWR_CR1_SVOS_MASK (0x3) #define PWR_CR1_SVOS_SCALE_3 (0x3) #define PWR_CR1_SVOS_SCALE_4 (0x2) #define PWR_CR1_SVOS_SCALE_5 (0x1) -#define PWR_CR1_SVOS_MASK (0x3) - +/** SmartRun domain AHB memory shut-off in DStop/DStop2 low-power mode */ +#define PWR_CR1_SRDRAMSO BIT27 +/** high-speed interfaces USB and FDCAN memory shut-off in DStop/DStop2 mode */ +#define PWR_CR1_HSITFSO BIT26 +/** GFXMMU and JPEG memory shut-off in DStop/DStop2 mode */ +#define PWR_CR1_GFXSO BIT25 +/** instruction TCM and ETM memory shut-off in DStop/DStop2 mode */ +#define PWR_CR1_ITCMSO BIT24 +/** AHB SRAM2 shut-off in DStop/DStop2 mode */ +#define PWR_CR1_AHBRAM2SO BIT23 +/** AHB SRAM1 shut-off in DStop/DStop2 mode */ +#define PWR_CR1_AHBRAM1SO BIT22 +/** AXI SRAM3 shut-off in DStop/DStop2 mode */ +#define PWR_CR1_AXIRAM3SO BIT21 +/** AXI SRAM2 shut-off in DStop/DStop2 mode */ +#define PWR_CR1_AXIRAM2SO BIT20 +/** AXI SRAM1 shut-off in DStop/DStop2 mode */ +#define PWR_CR1_AXIRAM1SO BIT19 +/** voltage threshold detected by the AVD. */ +#define PWR_CR1_ALS_SHIFT 17 +#define PWR_CR1_ALS_MASK 0x3 +#define PWR_CR1_ALS_1P7V 0x0 +#define PWR_CR1_ALS_2P1V 0x1 +#define PWR_CR1_ALS_2P5V 0x2 +#define PWR_CR1_ALS_2P8V 0x3 +/** peripheral voltage monitor on V DDA enable */ +#define PWR_CR1_AVDEN BIT16 +/** analog voltage ready + * This bit is only used when the analog switch boost needs to be enabled (see BOOSTE bit). + * It must be set by software when the expected V DDA analog supply level is available. + * The correct analog supply level is indicated by the AVDO bit (PWR_CSR1 register) after + * setting the AVDEN bit and selecting the supply level to be monitored (ALS bits). + */ +#define PWR_CR1_AVD_READY BIT13 +/** analog switch VBoost control + * This bit enables the booster to guarantee the analog switch AC performance when the V DD + * supply voltage is below 2.7 V (reduction of the total harmonic distortion to have the same + * switch performance over the full supply voltage range) + * The V DD supply voltage can be monitored through the PVD and the PLS bits. + */ +#define PWR_CR1_BOOSTE BIT12 /** DBP[8]: Disable backup domain write protection. */ -#define PWR_CR1_DBP (1 << 8) +#define PWR_CR1_DBP BIT8 /** CSR1 Register Bits */ +#define PWR_CSR1_MMCVDO BIT17 #define PWR_CSR1_AVDO BIT16 #define PWR_CSR1_ACTVOS_SHIFT 14 #define PWR_CSR1_ACTVOSRDY BIT13 #define PWR_CSR1_PVDO BIT4 +/** CR2 Register Bits */ +/** temperature level monitoring versus high threshold */ +#define PWR_CR2_TEMPH BIT23 +/** temperature level monitoring versus low threshold */ +#define PWR_CR2_TEMPL BIT22 +/** backup regulator ready */ +#define PWR_CR2_BRRDY BIT16 +/** V BAT and temperature monitoring enable */ +#define PWR_CR2_MONEN BIT4 +/** backup regulator enable */ +#define PWR_CR2_BREN BIT0 + /** CR3 Register Bits */ #define PWR_CR3_USB33RDY BIT26 #define PWR_CR3_USBREGEN BIT25 #define PWR_CR3_USB33DEN BIT24 +/** SMPS step-down converter external supply ready */ +#define PWR_CR3_SMPSEXTRDY BIT16 +/** V BAT charging resistor selection */ #define PWR_CR3_VBRS BIT9 +/** V BAT charging enable */ #define PWR_CR3_VBE BIT8 + +/** SMPS step-down converter voltage output level selection + * This setting is used when both the LDO and SMPS step-down converter are enabled with SMPSEN and + * LDOEN enabled or when SMPSEXTHP is enabled. In this case SMPSLEVEL must be written with + * a value different than 00 to reach the appropriate voltage, based on VOS or external supply. + */ +#define PWR_CR3_SMPSLEVEL_SHIFT 4 +#define PWR_CR3_SMPSLEVEL_MASK 0x3 +#define PWR_CR3_SMPSLEVEL_VOS 0x0 +#define PWR_CR3_SMPSLEVEL_1P8V 0x1 +#define PWR_CR3_SMPSLEVEL_2P5V 0x2 + +/** SMPS step-down converter external power delivery selection */ +#define PWR_CR3_SMPSEXTHP BIT3 #define PWR_CR3_SCUEN BIT2 +/* BIT2 Is overloaded on devices with SMPS as the SMPSEN bit. */ +#define PWR_CR3_SMPSEN BIT2 #define PWR_CR3_LDOEN BIT1 #define PWR_CR3_BYPASS BIT0 /** D3CR Register Bits */ -#define PWR_D3CR_VOS_SHIFT 14 #define PWR_D3CR_VOSRDY BIT13 - +#define PWR_D3CR_VOS_SHIFT 14 +#define PWR_D3CR_VOS_MASK (0x03) +/** VOS0 is implemented on STM32H72x/3x with simple VOS setting. + * STM32H742/43/45/47/50/53/55/57 SCALE0 this as SCALE1 + SYSCFG.ODEN */ +#define PWR_D3CR_VOS_SCALE_0 (0x0) #define PWR_D3CR_VOS_SCALE_3 (0x1) #define PWR_D3CR_VOS_SCALE_2 (0x2) #define PWR_D3CR_VOS_SCALE_1 (0x3) -#define PWR_D3CR_VOS_MASK (0x03) +/** SRDCR Register Bits */ +#define PWR_SRDCR_VOSRDY BIT13 +#define PWR_SRDCR_VOS_SHIFT 14 +#define PWR_SRDCR_VOS_MASK (0x03) +#define PWR_SRDCR_VOS_SCALE_3 (0x0) +#define PWR_SRDCR_VOS_SCALE_2 (0x1) +#define PWR_SRDCR_VOS_SCALE_1 (0x2) +#define PWR_SRDCR_VOS_SCALE_0 (0x3) + +enum pwr_sys_mode { + PWR_SYS_SCU_LDO = 0, /**< STM32H742/43/50/53 has special SCUEN handling, use for LDO. */ + PWR_SYS_SCU_BYPASS, /**< STM32H742/43/50/53 has special SCUEN handling, use for bypass. */ + PWR_SYS_LDO, /**< Devices with SMPS use this to run from LDO only. */ + PWR_SYS_SMPS_DIRECT, /**< Disable LDO, apply SMPS direct to CPU using VOS. */ + PWR_SYS_SMPS_LDO, /**< SMPS supplies internal LDO. */ + PWR_SYS_EXT_SMPS_LDO, /**< SMPS supplies external power, and CPU through LDO. */ + PWR_SYS_EXT_SMPS_LDO_BYP, /**< SMPS supplies external power, bypasses LDO (e.g. external LDO) */ + PWR_SYS_BYPASS /**< Disable all internal power supplies. */ +}; enum pwr_svos_scale { PWR_SVOS_SCALE3 = PWR_CR1_SVOS_SCALE_3 << PWR_CR1_SVOS_SHIFT, @@ -98,10 +196,11 @@ enum pwr_svos_scale { }; enum pwr_vos_scale { - PWR_VOS_SCALE_0 = 0, /* Note: This state requires SYSCFG ODEN set. */ - PWR_VOS_SCALE_1 = (PWR_D3CR_VOS_SCALE_1 << PWR_D3CR_VOS_SHIFT), - PWR_VOS_SCALE_2 = (PWR_D3CR_VOS_SCALE_2 << PWR_D3CR_VOS_SHIFT), - PWR_VOS_SCALE_3 = (PWR_D3CR_VOS_SCALE_3 << PWR_D3CR_VOS_SHIFT) + PWR_VOS_SCALE_UNDEFINED = 0, + PWR_VOS_SCALE_0, + PWR_VOS_SCALE_1, + PWR_VOS_SCALE_2, + PWR_VOS_SCALE_3, }; BEGIN_DECLS @@ -109,16 +208,37 @@ BEGIN_DECLS /** @defgroup pwr_peripheral_api PWR Peripheral API * @ingroup peripheral_apis @{*/ - /** Set power subsystem to utilize the LDO for CPU. */ void pwr_set_mode_ldo(void); -/** Set the voltage scaling/strength for the internal LDO when in Stop mode. +/** Specific STM32H742/43/50/53 LDO mode setting.. */ +void pwr_set_mode_scu_ldo(void); + +/** Set power subsystem to utilize the SMPS run through the LDO for CPU. + * @param[in] supply_external Supply is powering external circuits, enable high power mode. + * @param[in] smps_level Voltage level from available PWR_CR3_SMPSLEVEL_XXX settings (1.8V/2.5V) + * @param[in] use_ldo Set this value to true if the internal LDO should be enabled. + */ +void pwr_set_mode_smps_ldo(bool supply_external, uint32_t smps_level, bool use_ldo); + +/** Set power system based on "System Supply Configurations" table in reference manual. + * @param[in] mode Mode mapping to a mode in the system configuration. Note special SCU modes. + * @param[in] smps_level Optional, only needed if using an EXT_SMPS or SMPS_LDO mode. + */ +void pwr_set_mode(enum pwr_sys_mode mode, uint8_t smps_level); + +/** Set power subsystem to bypass all internal supplies. */ +void pwr_set_mode_bypass(void); + +/** Specific STM32H742/43/50/53 Bypsass mode setting.. */ +void pwr_set_mode_scu_bypass(void); + +/** Set the voltage scaling/strength for the internal SMPS/LDO when in Stop mode. * @param[in] scale Voltage scale value to set. */ void pwr_set_svos_scale(enum pwr_svos_scale scale); -/** Set the voltage scaling/strength for the internal LDO while running. +/** Set the voltage scaling/strength for the internal SMPS/LDO while running. * @param[in] scale Voltage scale value to set. */ void pwr_set_vos_scale(enum pwr_vos_scale scale); diff --git a/include/libopencm3/stm32/h7/rcc.h b/include/libopencm3/stm32/h7/rcc.h index 32a1058e..e9ca5be2 100644 --- a/include/libopencm3/stm32/h7/rcc.h +++ b/include/libopencm3/stm32/h7/rcc.h @@ -462,7 +462,9 @@ struct rcc_pll_config { uint8_t ppre3; /**< APB3 Peripheral prescaler note: domain 1. */ uint8_t ppre4; /**< APB4 Peripheral prescaler note: domain 3. */ uint8_t flash_waitstates; /**< Latency Value to set for flahs. */ - enum pwr_vos_scale voltage_scale; /**< LDO Voltage scale used for this frequency. */ + enum pwr_vos_scale voltage_scale; /**< LDO/SMPS Voltage scale used for this frequency. */ + enum pwr_sys_mode power_mode; /**< LDO/SMPS configuration for device. */ + uint8_t smps_level; /**< If using SMPS, voltage level to set. */ }; #define _REG_BIT(base, bit) (((base) << 5) + (bit)) diff --git a/lib/stm32/h7/pwr.c b/lib/stm32/h7/pwr.c index 8fd1da64..ce6e4baf 100644 --- a/lib/stm32/h7/pwr.c +++ b/lib/stm32/h7/pwr.c @@ -30,15 +30,80 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ - +#include +#include #include #include #include +/* DBGMCU_IDC DEV ID values needed to account for variations between part types. */ +#define DBGMCU_IDCODE_DEV_ID_STM32H74X_5X 0x450 +#define DBGMCU_IDCODE_DEV_ID_STM32H7A3_B3_B0 0x480 void pwr_set_mode_ldo(void) { - const uint32_t ldo_mask = (PWR_CR3_SCUEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); - PWR_CR3 = (PWR_CR3 & ~ldo_mask) | (PWR_CR3_SCUEN | PWR_CR3_LDOEN); + /* Per table in manual for SMPS, mask and set SMPSEN=0 : LDOEN=1 : BYPASS=0. */ + const uint32_t cr3_mask = (PWR_CR3_SMPSEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); + PWR_CR3 = (PWR_CR3 & ~cr3_mask) | (PWR_CR3_LDOEN); +} + +void pwr_set_mode_scu_ldo(void) { + const uint32_t cr3_mask = (PWR_CR3_SCUEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); + PWR_CR3 = (PWR_CR3 & ~cr3_mask) | (PWR_CR3_SCUEN | PWR_CR3_LDOEN); +} + +void pwr_set_mode_smps_ldo(bool supply_external, uint32_t smps_level, bool use_ldo) { + uint32_t cr3_mask, cr3_set; + cr3_mask = (PWR_CR3_SMPSEXTHP | PWR_CR3_SMPSEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); + cr3_mask |= PWR_CR3_SMPSLEVEL_MASK << PWR_CR3_SMPSLEVEL_SHIFT; + + /* Default, take in unconditional settings, will OR in the rest. */ + cr3_set = PWR_CR3_SMPSEN | (smps_level << PWR_CR3_SMPSLEVEL_SHIFT); + if (supply_external) { + cm3_assert(smps_level != PWR_CR3_SMPSLEVEL_VOS); /* Unsupported setting! */ + cr3_set |= PWR_CR3_SMPSEXTHP; + } + + if (use_ldo) { + cr3_set |= PWR_CR3_LDOEN; + } + PWR_CR3 = (PWR_CR3 & ~cr3_mask) | cr3_set; +} + +void pwr_set_mode_bypass(void) { + const uint32_t cr3_mask = (PWR_CR3_SMPSEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); + PWR_CR3 = (PWR_CR3 & ~cr3_mask) | PWR_CR3_BYPASS; +} + +void pwr_set_mode_scu_bypass(void) { + const uint32_t cr3_mask = (PWR_CR3_SCUEN | PWR_CR3_LDOEN | PWR_CR3_BYPASS); + PWR_CR3 = (PWR_CR3 & ~cr3_mask) | (PWR_CR3_SCUEN | PWR_CR3_BYPASS); +} + + +void pwr_set_mode(enum pwr_sys_mode mode, uint8_t smps_level) { + switch (mode) { + case PWR_SYS_SCU_LDO: + pwr_set_mode_scu_ldo(); + break; + case PWR_SYS_SCU_BYPASS: + pwr_set_mode_scu_bypass(); + break; + case PWR_SYS_LDO: + pwr_set_mode_ldo(); + break; + case PWR_SYS_SMPS_DIRECT: + case PWR_SYS_SMPS_LDO: + pwr_set_mode_smps_ldo(false, PWR_CR3_SMPSLEVEL_VOS, mode == PWR_SYS_SMPS_LDO); + break; + case PWR_SYS_EXT_SMPS_LDO: + case PWR_SYS_EXT_SMPS_LDO_BYP: + pwr_set_mode_smps_ldo(false, smps_level, mode == PWR_SYS_EXT_SMPS_LDO); + break; + case PWR_SYS_BYPASS: + pwr_set_mode_bypass(); + break; + } + /* Wait for power supply status to state ready. */ while (!(PWR_CSR1 & PWR_CSR1_ACTVOSRDY)); } @@ -50,16 +115,49 @@ void pwr_set_svos_scale(enum pwr_svos_scale scale) } void pwr_set_vos_scale(enum pwr_vos_scale scale) { - rcc_periph_clock_enable(RCC_SYSCFG); /* Ensure we can access ODEN. */ - uint32_t d3cr_masked = PWR_D3CR & ~(PWR_D3CR_VOS_MASK << PWR_D3CR_VOS_SHIFT); + static const uint8_t srdcr_vos_values[] = { + PWR_SRDCR_VOS_SCALE_0, + PWR_SRDCR_VOS_SCALE_1, + PWR_SRDCR_VOS_SCALE_2, + PWR_SRDCR_VOS_SCALE_3, + }; + static const uint8_t d3cr_vos_values[] = { + PWR_D3CR_VOS_SCALE_0, + PWR_D3CR_VOS_SCALE_1, + PWR_D3CR_VOS_SCALE_2, + PWR_D3CR_VOS_SCALE_3, + }; + cm3_assert(scale != PWR_VOS_SCALE_UNDEFINED); /* Make sure this has been set. */ - /* Per the manual, VOS0 is implemented as VOS1 + ODEN. Handle this case. */ - if (scale == PWR_VOS_SCALE_0) { - PWR_D3CR = d3cr_masked | PWR_VOS_SCALE_1; - SYSCFG_PWRCR |= SYSCFG_PWRCR_ODEN; + /* "SmartRun Domain" devices (presently only know of A3/B3/B0) have different mapping. + * Note: DBGMCU_IDCODE_DEV_ID_STM32H7A3 covers all three of these models. + */ + uint32_t devid = DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK; + if (devid == DBGMCU_IDCODE_DEV_ID_STM32H7A3_B3_B0) { + const uint32_t srdcr_vos_mask = (PWR_SRDCR_VOS_MASK << PWR_SRDCR_VOS_SHIFT); + const uint32_t vos_value = srdcr_vos_values[scale - 1] << PWR_SRDCR_VOS_SHIFT; + PWR_SRDCR = (PWR_SRDCR & ~srdcr_vos_mask) | vos_value; } else { - SYSCFG_PWRCR &= ~SYSCFG_PWRCR_ODEN; - PWR_D3CR = d3cr_masked | scale; + /* Get the VOS value for the non-smart domain types. */ + uint32_t d3cr_vos = (uint32_t)d3cr_vos_values[scale - 1] << PWR_D3CR_VOS_SHIFT; + uint32_t d3cr_masked = PWR_D3CR & ~(PWR_D3CR_VOS_MASK << PWR_D3CR_VOS_SHIFT); + /* STM32H742/43/45/47/50/53/55/57 have special handling of VOS0, which is to set + * VOS1, and also enable the ODEN in the SYSCFG_PWRCR. + * Note: Conveniently, all devices with this setup share a devid, so pick one. + */ + if (devid == DBGMCU_IDCODE_DEV_ID_STM32H74X_5X) { + rcc_periph_clock_enable(RCC_SYSCFG); /* Ensure we can access ODEN. */ + /* Per the manual, VOS0 is implemented as VOS1 + ODEN. Handle this case. */ + if (scale == PWR_VOS_SCALE_0) { + PWR_D3CR = d3cr_masked | (PWR_D3CR_VOS_SCALE_1 << PWR_SRDCR_VOS_SHIFT); + SYSCFG_PWRCR |= SYSCFG_PWRCR_ODEN; + } else { + SYSCFG_PWRCR &= ~SYSCFG_PWRCR_ODEN; + PWR_D3CR = d3cr_masked | d3cr_vos; + } + } else { + PWR_D3CR = d3cr_masked | d3cr_vos; + } } - while (!(PWR_D3CR & PWR_D3CR_VOSRDY)); + while (!(PWR_D3CR & PWR_D3CR_VOSRDY)); /* VOSRDY bit is same between D3CR and SRDCR. */ } diff --git a/lib/stm32/h7/rcc.c b/lib/stm32/h7/rcc.c index 71f7fae9..30f3b4bb 100644 --- a/lib/stm32/h7/rcc.c +++ b/lib/stm32/h7/rcc.c @@ -185,8 +185,8 @@ void rcc_clock_setup_pll(const struct rcc_pll_config *config) { while (((RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_HSI); RCC_CR = RCC_CR_HSION; - /* Now that we're safely running on HSI, let's setup the LDO. */ - pwr_set_mode_ldo(); + /* Now that we're safely running on HSI, let's setup the power system for scaling. */ + pwr_set_mode(config->power_mode, config->smps_level); pwr_set_vos_scale(config->voltage_scale); /* Set flash waitstates. Enable flash prefetch if we have at least 1WS */ From aeb3cee0235dd3e8784c003ff1af82ce44b7b38c Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 4 Feb 2021 10:02:06 +0000 Subject: [PATCH 090/206] stm32h7: document optional parameters Provide linking and explanations of optional values --- include/libopencm3/stm32/h7/pwr.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/include/libopencm3/stm32/h7/pwr.h b/include/libopencm3/stm32/h7/pwr.h index 70c6d8fa..dd3943d1 100644 --- a/include/libopencm3/stm32/h7/pwr.h +++ b/include/libopencm3/stm32/h7/pwr.h @@ -140,16 +140,18 @@ LGPL License Terms @ref lgpl_license /** V BAT charging enable */ #define PWR_CR3_VBE BIT8 -/** SMPS step-down converter voltage output level selection +/** @defgroup pwr_cr3_smpslevel SMPS step-down converter voltage output level selection * This setting is used when both the LDO and SMPS step-down converter are enabled with SMPSEN and * LDOEN enabled or when SMPSEXTHP is enabled. In this case SMPSLEVEL must be written with * a value different than 00 to reach the appropriate voltage, based on VOS or external supply. + * @{ */ -#define PWR_CR3_SMPSLEVEL_SHIFT 4 -#define PWR_CR3_SMPSLEVEL_MASK 0x3 #define PWR_CR3_SMPSLEVEL_VOS 0x0 #define PWR_CR3_SMPSLEVEL_1P8V 0x1 #define PWR_CR3_SMPSLEVEL_2P5V 0x2 +/**@}*/ +#define PWR_CR3_SMPSLEVEL_SHIFT 4 +#define PWR_CR3_SMPSLEVEL_MASK 0x3 /** SMPS step-down converter external power delivery selection */ #define PWR_CR3_SMPSEXTHP BIT3 @@ -215,15 +217,16 @@ void pwr_set_mode_ldo(void); void pwr_set_mode_scu_ldo(void); /** Set power subsystem to utilize the SMPS run through the LDO for CPU. - * @param[in] supply_external Supply is powering external circuits, enable high power mode. - * @param[in] smps_level Voltage level from available PWR_CR3_SMPSLEVEL_XXX settings (1.8V/2.5V) - * @param[in] use_ldo Set this value to true if the internal LDO should be enabled. + * @param[in] supply_external Supply is powering external circuits, enable high power mode. + * @param[in] smps_level Voltage level from @ref pwr_cr3_smpslevel (1.8V/2.5V) + * @param[in] use_ldo Set this value to true if the internal LDO should be enabled. */ void pwr_set_mode_smps_ldo(bool supply_external, uint32_t smps_level, bool use_ldo); /** Set power system based on "System Supply Configurations" table in reference manual. - * @param[in] mode Mode mapping to a mode in the system configuration. Note special SCU modes. - * @param[in] smps_level Optional, only needed if using an EXT_SMPS or SMPS_LDO mode. + * @param[in] mode Mode mapping to a mode in the system configuration. Note special SCU modes. + * @param[in] smps_level Optional, only needed if using an EXT_SMPS or SMPS_LDO mode. + * Provide zero if unused, otherwise @ref pwr_cr3_smpslevel. */ void pwr_set_mode(enum pwr_sys_mode mode, uint8_t smps_level); From b4c03a840d17da6ae6b9aa3a80376d1ca41df553 Mon Sep 17 00:00:00 2001 From: Marek Koza Date: Tue, 23 Feb 2021 02:12:34 +0100 Subject: [PATCH 091/206] stm32: rtc-v2: Fix ADD1S bit definition in the RTC SHIFTR register --- include/libopencm3/stm32/common/rtc_common_l1f024.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/common/rtc_common_l1f024.h b/include/libopencm3/stm32/common/rtc_common_l1f024.h index 4ae116b8..127a81a3 100644 --- a/include/libopencm3/stm32/common/rtc_common_l1f024.h +++ b/include/libopencm3/stm32/common/rtc_common_l1f024.h @@ -330,7 +330,7 @@ specific memorymap.h header before including this header file.*/ /**@}*/ /* RTC shift control register (RTC_SHIFTR) ---------------------- */ -#define RTC_SHIFTR_ADD1S (31) +#define RTC_SHIFTR_ADD1S (1<<31) #define RTC_SHIFTR_SUBFS_SHIFT (0) #define RTC_SHIFTR_SUBFS_MASK (0x7fff) From a9cc6953817e0de1cad06662ce58a81607cd796b Mon Sep 17 00:00:00 2001 From: Jean THOMAS Date: Wed, 30 Dec 2020 21:12:30 +0100 Subject: [PATCH 092/206] stm32: i2c: Use const qualifier for read-only pointer in i2c_transfer7 --- include/libopencm3/stm32/common/i2c_common_v1.h | 2 +- include/libopencm3/stm32/common/i2c_common_v2.h | 2 +- lib/stm32/common/i2c_common_v1.c | 4 ++-- lib/stm32/common/i2c_common_v2.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/libopencm3/stm32/common/i2c_common_v1.h b/include/libopencm3/stm32/common/i2c_common_v1.h index 9892abf8..8e62324b 100644 --- a/include/libopencm3/stm32/common/i2c_common_v1.h +++ b/include/libopencm3/stm32/common/i2c_common_v1.h @@ -415,7 +415,7 @@ void i2c_enable_dma(uint32_t i2c); void i2c_disable_dma(uint32_t i2c); void i2c_set_dma_last_transfer(uint32_t i2c); void i2c_clear_dma_last_transfer(uint32_t i2c); -void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn); +void i2c_transfer7(uint32_t i2c, uint8_t addr, const uint8_t *w, size_t wn, uint8_t *r, size_t rn); void i2c_set_speed(uint32_t i2c, enum i2c_speeds speed, uint32_t clock_megahz); END_DECLS diff --git a/include/libopencm3/stm32/common/i2c_common_v2.h b/include/libopencm3/stm32/common/i2c_common_v2.h index ad4846b9..316d0f1e 100644 --- a/include/libopencm3/stm32/common/i2c_common_v2.h +++ b/include/libopencm3/stm32/common/i2c_common_v2.h @@ -444,7 +444,7 @@ void i2c_enable_rxdma(uint32_t i2c); void i2c_disable_rxdma(uint32_t i2c); void i2c_enable_txdma(uint32_t i2c); void i2c_disable_txdma(uint32_t i2c); -void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn); +void i2c_transfer7(uint32_t i2c, uint8_t addr, const uint8_t *w, size_t wn, uint8_t *r, size_t rn); void i2c_set_speed(uint32_t i2c, enum i2c_speeds speed, uint32_t clock_megahz); END_DECLS diff --git a/lib/stm32/common/i2c_common_v1.c b/lib/stm32/common/i2c_common_v1.c index caab1485..59f75886 100644 --- a/lib/stm32/common/i2c_common_v1.c +++ b/lib/stm32/common/i2c_common_v1.c @@ -465,7 +465,7 @@ void i2c_clear_dma_last_transfer(uint32_t i2c) I2C_CR2(i2c) &= ~I2C_CR2_LAST; } -static void i2c_write7_v1(uint32_t i2c, int addr, uint8_t *data, size_t n) +static void i2c_write7_v1(uint32_t i2c, int addr, const uint8_t *data, size_t n) { while ((I2C_SR2(i2c) & I2C_SR2_BUSY)) { } @@ -532,7 +532,7 @@ static void i2c_read7_v1(uint32_t i2c, int addr, uint8_t *res, size_t n) * @param r destination buffer to read into * @param rn number of bytes to read (r should be at least this long) */ -void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn) { +void i2c_transfer7(uint32_t i2c, uint8_t addr, const uint8_t *w, size_t wn, uint8_t *r, size_t rn) { if (wn) { i2c_write7_v1(i2c, addr, w, wn); } diff --git a/lib/stm32/common/i2c_common_v2.c b/lib/stm32/common/i2c_common_v2.c index fbb339bc..426219c6 100644 --- a/lib/stm32/common/i2c_common_v2.c +++ b/lib/stm32/common/i2c_common_v2.c @@ -395,7 +395,7 @@ void i2c_disable_txdma(uint32_t i2c) * @param r destination buffer to read into * @param rn number of bytes to read (r should be at least this long) */ -void i2c_transfer7(uint32_t i2c, uint8_t addr, uint8_t *w, size_t wn, uint8_t *r, size_t rn) +void i2c_transfer7(uint32_t i2c, uint8_t addr, const uint8_t *w, size_t wn, uint8_t *r, size_t rn) { /* waiting for busy is unnecessary. read the RM */ if (wn) { From 458250dc6147dc807eec9e4d5a6caf38a699ecb1 Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Tue, 23 Feb 2021 22:36:04 +0100 Subject: [PATCH 093/206] STM32G4: Add support for FDCAN Add stm32g4 support for FDCAN peripheral. Normal / FDCAN operation supported, bitrate switching and filtering supported via API. Timestamping and transmit event buffer support in API are TBD. Originally tracked as: https://github.com/libopencm3/libopencm3/pull/1317 Reviewed-by: Karl Palsson --- include/libopencm3/stm32/fdcan.h | 892 +++++++++++++++++++++++++++++++ lib/stm32/common/fdcan.c | 779 +++++++++++++++++++++++++++ lib/stm32/g4/Makefile | 1 + 3 files changed, 1672 insertions(+) create mode 100644 include/libopencm3/stm32/fdcan.h create mode 100644 lib/stm32/common/fdcan.c diff --git a/include/libopencm3/stm32/fdcan.h b/include/libopencm3/stm32/fdcan.h new file mode 100644 index 00000000..61ac87d0 --- /dev/null +++ b/include/libopencm3/stm32/fdcan.h @@ -0,0 +1,892 @@ +/** @defgroup fdcan_defines FDCAN Defines + +@ingroup STM32G_defines + +@brief libopencm3 Defined Constants and Types for STM32 FD-CAN + +@author @htmlonly © @endhtmlonly 2021 Eduard Drusa + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + + + +#ifndef LIBOPENCM3_FDCAN_H +#define LIBOPENCM3_FDCAN_H + +#include +#include + +/** @{ */ + +/* FDCAN block base addresses. Used in functions to identify FDCAN block being manipulated. */ + +/** @defgroup fdcan_block FDCAN block base addresses + * @{ + */ +#define CAN1 FDCAN1_BASE +#define CAN2 FDCAN2_BASE +#define CAN3 FDCAN3_BASE +/**@}*/ + + +/** @defgroup fdcan_fifo Named constants for FIFOs + * @{ + */ +#define FDCAN_FIFO0 0 +#define FDCAN_FIFO1 1 +/**@}*/ + + +/** @defgroup FDCAN registers file in each FDCAN block. */ + +#define FDCAN_CREL(can_base) MMIO32(can_base + 0x0000) +#define FDCAN_ENDN(can_base) MMIO32(can_base + 0x0004) +#define FDCAN_DBTP(can_base) MMIO32(can_base + 0x000C) +#define FDCAN_TEST(can_base) MMIO32(can_base + 0x0010) +#define FDCAN_RWD(can_base) MMIO32(can_base + 0x0014) +#define FDCAN_CCCR(can_base) MMIO32(can_base + 0x0018) +#define FDCAN_NBTP(can_base) MMIO32(can_base + 0x001C) +#define FDCAN_TSCC(can_base) MMIO32(can_base + 0x0020) +#define FDCAN_TSCV(can_base) MMIO32(can_base + 0x0024) +#define FDCAN_TOCC(can_base) MMIO32(can_base + 0x0028) +#define FDCAN_TOCV(can_base) MMIO32(can_base + 0x002C) +#define FDCAN_ECR(can_base) MMIO32(can_base + 0x0040) +#define FDCAN_PSR(can_base) MMIO32(can_base + 0x0044) +#define FDCAN_TDCR(can_base) MMIO32(can_base + 0x0048) +#define FDCAN_IR(can_base) MMIO32(can_base + 0x0050) +#define FDCAN_IE(can_base) MMIO32(can_base + 0x0054) +#define FDCAN_ILS(can_base) MMIO32(can_base + 0x0058) +#define FDCAN_ILE(can_base) MMIO32(can_base + 0x005C) +#define FDCAN_RXGFC(can_base) MMIO32(can_base + 0x0080) +#define FDCAN_XIDAM(can_base) MMIO32(can_base + 0x0084) +#define FDCAN_HPMS(can_base) MMIO32(can_base + 0x0088) + +/** Generic access to Rx FIFO status registers. + * @param can_base FDCAN block base address @ref fdcan_block + * @param fifo_id ID of FIFO, 0 or 1 + */ +#define FDCAN_RXFIS(can_base, fifo_id) MMIO32(can_base + 0x0090 + (8 * fifo_id)) +#define FDCAN_RXF0S(can_base) FDCAN_RXFIS(can_base, 0) +#define FDCAN_RXF1S(can_base) FDCAN_RXFIS(can_base, 1) + +/** Generic access to Rx FIFO acknowledge registers. + * @param can_base FDCAN block base address @ref fdcan_block + * @param fifo_id ID of FIFO, 0 or 1 + */ +#define FDCAN_RXFIA(can_base, fifo_id) MMIO32(can_base + 0x0094 + (8 * fifo_id)) +#define FDCAN_RXF0A(can_base) FDCAN_RXFIA(can_base, 0) +#define FDCAN_RXF1A(can_base) FDCAN_RXFIA(can_base, 1) + +#define FDCAN_TXBC(can_base) MMIO32(can_base + 0x00C0) +#define FDCAN_TXFQS(can_base) MMIO32(can_base + 0x00C4) +#define FDCAN_TXBRP(can_base) MMIO32(can_base + 0x00C8) +#define FDCAN_TXBAR(can_base) MMIO32(can_base + 0x00CC) +#define FDCAN_TXBCR(can_base) MMIO32(can_base + 0x00D0) +#define FDCAN_TXBTO(can_base) MMIO32(can_base + 0x00D4) +#define FDCAN_TXBCF(can_base) MMIO32(can_base + 0x00D8) +#define FDCAN_TXBTIE(can_base) MMIO32(can_base + 0x00DC) +#define FDCAN_TXBCIE(can_base) MMIO32(can_base + 0x00E0) +#define FDCAN_TXEFS(can_base) MMIO32(can_base + 0x00E4) +#define FDCAN_TXEFA(can_base) MMIO32(can_base + 0x00E8) +#define FDCAN_CKDIV(can_base) MMIO32(can_base + 0x0100) + +/* DAY[7:0]: FDCAN core revision date */ +#define FDCAN_CREL_DAY_SHIFT 0 +#define FDCAN_CREL_DAY_MASK 0xFF + +/* MON[7:0]: FDCAN core revision month */ +#define FDCAN_CREL_MON_SHIFT 8 +#define FDCAN_CREL_MON_MASK 0xFF + +/* YEAR[3:0]: FDCAN core revision year */ +#define FDCAN_CREL_YEAR_SHIFT 16 +#define FDCAN_CREL_YEAR_MASK 0xF + +/* SUBSTEP[3:0]: FDCAN core release sub stepping */ +#define FDCAN_CREL_SUBSTEP_SHIFT 20 +#define FDCAN_CREL_SUBSTEP_MASK 0xF + +/* STEP[3:0]: FDCAN core release stepping */ +#define FDCAN_CREL_STEP_SHIFT 24 +#define FDCAN_CREL_STEP_MASK 0xF + +/* REL[3:0]: FDCAN core release number */ +#define FDCAN_CREL_REL_SHIFT 28 +#define FDCAN_CREL_REL_MASK 0xF + + +/* DSJW[3:0]: Synchronization jump width */ +#define FDCAN_DBTP_DSJW_SHIFT 0 +#define FDCAN_DBTP_DSJW_MASK 0xF + +/* DTSEG2[3:0]: Data time segment after sample point */ +#define FDCAN_DBTP_DTSEG2_SHIFT 4 +#define FDCAN_DBTP_DTSEG2_MASK 0xF + +/* DTSEG1[4:0]: Data time segment before sample point */ +#define FDCAN_DBTP_DTSEG1_SHIFT 8 +#define FDCAN_DBTP_DTSEG1_MASK 0x1F + +/* DBRP[4:0]: Data bit rate prescaler */ +#define FDCAN_DBTP_DBRP_SHIFT 16 +#define FDCAN_DBTP_DBRP_MASK 0x1F + +#define FDCAN_DBTP_TDC (1 << 23) + +#define FDCAN_TEST_LBCK (1 << 4) +/* TX[1:0]: Control of transmit pin */ +#define FDCAN_TEST_TX_SHIFT 5 +#define FDCAN_TEST_TX_MASK 0x3 + +#define FDCAN_TEST_RX (1 << 7) + +/* WDC[7:0]: RAM watchdog configuration */ +#define FDCAN_RWD_WDC_SHIFT 0 +#define FDCAN_RWD_WDC_MASK 0xFF + +/* WDV[7:0]: RAM watchdog actual value */ +#define FDCAN_RWD_WDV_SHIFT 7 +#define FDCAN_RWD_WDV_MASK 0xFF + +/** @defgroup fdcan_cccr FDCAN CC control register bits + * @{ + */ +#define FDCAN_CCCR_INIT (1 << 0) +#define FDCAN_CCCR_CCE (1 << 1) +#define FDCAN_CCCR_ASM (1 << 2) +#define FDCAN_CCCR_CSA (1 << 3) +#define FDCAN_CCCR_CSR (1 << 4) +#define FDCAN_CCCR_MON (1 << 5) +#define FDCAN_CCCR_DAR (1 << 6) +#define FDCAN_CCCR_TEST (1 << 7) +#define FDCAN_CCCR_FDOE (1 << 8) +#define FDCAN_CCCR_BRSE (1 << 9) +#define FDCAN_CCCR_PXHD (1 << 12) +#define FDCAN_CCCR_EFBI (1 << 13) +#define FDCAN_CCCR_TXP (1 << 14) +#define FDCAN_CCCR_NISO (1 << 15) +/**@}*/ + +/** Timeout for FDCAN_CCCR register INIT bit to accept set value. + * + * This timeout is required because FDCAN uses two different clocks + * feeding two different portions of block. There can be slight delay + * based on how clocks are set up. While amount of FDCAN_clk / + * FDCAN_pclk combinations is high and clock speeds may vary a lot, + * following value has been choosen as sane default. You are free to + * use any timeout value you want. + */ +#define FDCAN_CCCR_INIT_TIMEOUT 0x0000FFFF + +/* NTSEG2[6:0]: Nominal timing segment after sample point length */ +#define FDCAN_NBTP_NTSEG2_SHIFT 0 +#define FDCAN_NBTP_NTSEG2_MASK 0x7F + +/* NTSEG1[7:0]: Nominal timing segment before sample point length */ +#define FDCAN_NBTP_NTSEG1_SHIFT 8 +#define FDCAN_NBTP_NTSEG1_MASK 0xFF + +/* NBRP[8:0]: Norminal timing bit rate prescaler */ +#define FDCAN_NBTP_NBRP_SHIFT 16 +#define FDCAN_NBTP_NBRP_MASK 0x1FF + +/* NSJW[6:0]: Norminal timing resynchronization jumb width*/ +#define FDCAN_NBTP_NSJW_SHIFT 25 +#define FDCAN_NBTP_NSJW_MASK 0x7F + +/* TSS[1:0]: Timestamp select */ +#define FDCAN_TSCC_TSS_SHIFT 0 +#define FDCAN_TSCC_TSS_MASK 0x3 + +/* TCP[3:0]: Timestamp counter prescaler */ +#define FDCAN_TSCC_TCP_SHIFT 16 +#define FDCAN_TSCC_TCP_MASK 0xF + + +/* TSC[15:0]: Timestamp counter value */ +#define FDCAN_TSCV_TSC_SHIFT 0 +#define FDCAN_TSCV_TSC_MASK 0xFFFF + +#define FDCAN_TOCC_ETOC (1 << 0) +/* TOS[1:0]: Timeout select */ +#define FDCAN_TOCC_TOS_SHIFT 1 +#define FDCAN_TOCC_TOS_MASK 0x3 + +/* TOP[15:0]: Timeout period */ +#define FDCAN_TOCC_TOP_SHIFT 16 +#define FDCAN_TOCC_TOP_MASK 0xFFFF + +/* TOC[15:0]: Timeout counter */ +#define FDCAN_TOCV_TOC_SHIFT 0 +#define FDCAN_TOCV_TOC_MASK 0xFFFF + +/* TEC[7:0]: Transmit error counter */ +#define FDCAN_ECR_TEC_SHIFT 0 +#define FDCAN_ECR_TEC_MASK 0xFF + +/* REC[6:0]: Receive error counter */ +#define FDCAN_ECR_REC_SHIFT 8 +#define FDCAN_ECR_REC_MASK 0x7F + +#define FDCAN_ECR_RP (1 << 15) +/* CEL[7:0]: CAN error logging */ +#define FDCAN_ECR_CEL_SHIFT 16 +#define FDCAN_ECR_CEL_MASK 0xFF + + +/* LEC[2:0]: Last error code */ +#define FDCAN_PSR_LEC_SHIFT 0 +#define FDCAN_PSR_LEC_MASK 0x7 + +/* ACT[1:0]: CAN block activity */ +#define FDCAN_PSR_ACT_SHIFT 3 +#define FDCAN_PSR_ACT_MASK 0x3 + +#define FDCAN_PSR_EP (1 << 5) +#define FDCAN_PSR_EW (1 << 6) +#define FDCAN_PSR_BO (1 << 7) +/* DLEC[2:0]: Last error code in data section */ +#define FDCAN_PSR_DLEC_SHIFT 8 +#define FDCAN_PSR_DLEC_MASK 0x7 + +#define FDCAN_PSR_RESI (1 << 11) + +/* the what? */ +#define FDCAN_PSR_RBRSRESI1 (1 << 12) +#define FDCAN_PSR_REDL (1 << 13) +#define FDCAN_PSR_PXE (1 << 14) + +/* TDCV[6:0]: Transmitter delay compensation value */ +#define FDCAN_PSR_TDCV_SHIFT 16 +#define FDCAN_PSR_TDCV_MASK 0x7F + +/* TDCF[6:0]: Transmitter delay compensation filter window length */ +#define FDCAN_TDCR_TDCF_SHIFT 0 +#define FDCAN_TDCR_TDCF_MASK 0x7F + +/* TDCO[6:0]: Transmitter delay compensation offset */ +#define FDCAN_TDCR_TDCO_SHIFT 8 +#define FDCAN_TDCR_TDCO_MASK 0x7F + +/** @defgroup fdcan_ir FDCAN interrupt register flags + * @{ + */ +#define FDCAN_IR_RF0N (1 << 0) +#define FDCAN_IR_RF0F (1 << 1) +#define FDCAN_IR_RF0L (1 << 2) +#define FDCAN_IR_RF1N (1 << 3) +#define FDCAN_IR_RF1F (1 << 4) +#define FDCAN_IR_RF1L (1 << 5) +#define FDCAN_IR_HPM (1 << 6) +#define FDCAN_IR_TC (1 << 7) +#define FDCAN_IR_TCF (1 << 8) +#define FDCAN_IR_TFE (1 << 9) +#define FDCAN_IR_TEFN (1 << 10) +#define FDCAN_IR_TEFF (1 << 11) +#define FDCAN_IR_TEFL (1 << 12) +#define FDCAN_IR_TSW (1 << 13) +#define FDCAN_IR_MRAF (1 << 14) +#define FDCAN_IR_TOO (1 << 15) +#define FDCAN_IR_ELO (1 << 16) +#define FDCAN_IR_EP (1 << 17) +#define FDCAN_IR_EW (1 << 18) +#define FDCAN_IR_BO (1 << 19) +#define FDCAN_IR_WDI (1 << 20) +#define FDCAN_IR_PEA (1 << 21) +#define FDCAN_IR_PED (1 << 22) +#define FDCAN_IR_ARA (1 << 23) +/**@}*/ + +/** @defgroup fdcan_ie FDCAN interrupt enable flags + * @{ + */ +#define FDCAN_IE_RF0NE (1 << 0) +#define FDCAN_IE_RF0FE (1 << 1) +#define FDCAN_IE_RF0LE (1 << 2) +#define FDCAN_IE_RF1NE (1 << 3) +#define FDCAN_IE_RF1FE (1 << 4) +#define FDCAN_IE_RF1LE (1 << 5) +#define FDCAN_IE_HPME (1 << 6) +#define FDCAN_IE_TCE (1 << 7) +#define FDCAN_IE_TCFE (1 << 8) +#define FDCAN_IE_TFEE (1 << 9) +#define FDCAN_IE_TEFNE (1 << 10) +#define FDCAN_IE_TEFFE (1 << 11) +#define FDCAN_IE_TEFLE (1 << 12) +#define FDCAN_IE_TSWE (1 << 13) +#define FDCAN_IE_MRAFE (1 << 14) +#define FDCAN_IE_TOOE (1 << 15) +#define FDCAN_IE_ELOE (1 << 16) +#define FDCAN_IE_EPE (1 << 17) +#define FDCAN_IE_EWE (1 << 18) +#define FDCAN_IE_BOE (1 << 19) +#define FDCAN_IE_WDIE (1 << 20) +#define FDCAN_IE_PEAE (1 << 21) +#define FDCAN_IE_PEDE (1 << 22) +#define FDCAN_IE_ARAE (1 << 23) +/**@}*/ + +/** @defgroup fdcan_ils FDCAN_ILS interrupt line select flags + * @{ + */ +#define FDCAN_ILS_RxFIFO0 (1 << 0) +#define FDCAN_ILS_RxFIFO1 (1 << 1) +#define FDCAN_ILS_SMSG (1 << 2) +#define FDCAN_ILS_TFERR (1 << 3) +#define FDCAN_ILS_MISC (1 << 4) +#define FDCAN_ILS_BERR (1 << 5) +#define FDCAN_ILS_PERR (1 << 6) +/**@}*/ + +#define FDCAN_ILE_INT0 (1 << 0) +#define FDCAN_ILE_INT1 (1 << 1) + +#define FDCAN_RXGFC_RRFE (1 << 0) +#define FDCAN_RXGFC_RRFS (1 << 1) +/* ANFE[1:0]: Accept non-matching frames w/ extended ID */ +#define FDCAN_RXGFC_ANFE_SHIFT 2 +#define FDCAN_RXGFC_ANFE_MASK 0x3 + +/* ANFS[1:0]: Accept non-matching frames w/ standard ID */ +#define FDCAN_RXGFC_ANFS_SHIFT 4 +#define FDCAN_RXGFC_ANFS_MASK 0x3 + +#define FDCAN_RXGFC_F1OM (1 << 8) +#define FDCAN_RXGFC_F0OM (1 << 9) +/* LSS[4:0]: List size of standard ID filters */ +#define FDCAN_RXGFC_LSS_SHIFT 16 +#define FDCAN_RXGFC_LSS_MASK 0x1F + +/* LSE[3:0]: List size of extended ID filters */ +#define FDCAN_RXGFC_LSE_SHIFT 24 +#define FDCAN_RXGFC_LSE_MASK 0xF + + +/* EIDM[28:0]: Extended ID mask for filtering */ +#define FDCAN_XIDAM_EIDM_SHIFT 0 +#define FDCAN_XIDAM_EIDM_MASK 0x1FFFFFFF + + +/* BIDX[2:0]: Buffer index */ +#define FDCAN_HPMS_BIDX_SHIFT 0 +#define FDCAN_HPMS_BIDX_MASK 0x7 + +/* MSI[1:0]: Message storage indicator */ +#define FDCAN_HPMS_MSI_SHIFT 6 +#define FDCAN_HPMS_MSI_MASK 0x3 + +/* FIDX[4:0]: Filter index */ +#define FDCAN_HPMS_FIDX_SHIFT 8 +#define FDCAN_HPMS_FIDX_MASK 0x1F + +#define FDCAN_HPMS_FLS (1 << 15) + +/* Fill level of Rx FIFOs */ +#define FDCAN_RXFIFO_FL_SHIFT 0 +#define FDCAN_RXFIFO_FL_MASK 0xF + +/* Get index of Rx FIFOs */ +#define FDCAN_RXFIFO_GI_SHIFT 8 +#define FDCAN_RXFIFO_GI_MASK 0x3 + +/* Put index of Rx FIFOs */ +#define FDCAN_RXFIFO_PI_SHIFT 16 +#define FDCAN_RXFIFO_PI_MASK 0x3 + +#define FDCAN_RXFIFO_FF (1 << 24) +#define FDCAN_RXFIFO_RFL (1 << 25) + +/* F0FL[3:0]: Fill level of Rx FIFO 0 */ +#define FDCAN_RXF0S_F0FL_SHIFT FDCAN_RXFIFO_FL_SHIFT +#define FDCAN_RXF0S_F0FL_MASK FDCAN_RXFIFO_FL_MASK + +/* F0GI[1:0]: Get index of Rx FIFO 0 */ +#define FDCAN_RXF0S_F0GI_SHIFT FDCAN_RXFIFO_GI_SHIFT +#define FDCAN_RXF0S_F0GI_MASK FDCAN_RXFIFO_GI_MASK + +/* F0PI[1:0]: Put index of Rx FIFO 0 */ +#define FDCAN_RXF0S_F0PI_SHIFT FDCAN_RXFIFO_PI_SHIFT +#define FDCAN_RXF0S_F0PI_MASK FDCAN_RXFIFO_PI_MASK + +#define FDCAN_RXF0S_F0F FDCAN_RXFIFO_FF +#define FDCAN_RXF0S_RF0L FDCAN_RXFIFO_RFL + +/* Rx FIFOs acknowledge index */ +#define FDCAN_RXFIFO_AI_SHIFT 0 +#define FDCAN_RXFIFO_AI_MASK 0x7 + +/* R0AI[2:0]: Rx FIFO 0 acknowledge index */ +#define FDCAN_RXF0A_R0AI_SHIFT FDCAN_RXFIFO_AI_SHIFT +#define FDCAN_RXF0A_R0AI_MASK FDCAN_RXFIFO_AI_MASK + +/* F1FL[3:1]: Fill level of Rx FIFO 1 */ +#define FDCAN_RXF1S_F1FL_SHIFT FDCAN_RXFIFO_FL_SHIFT +#define FDCAN_RXF1S_F1FL_MASK FDCAN_RXFIFO_FL_MASK + +/* F1GI[1:1]: Get index of Rx FIFO 1 */ +#define FDCAN_RXF1S_F1GI_SHIFT FDCAN_RXFIFO_GI_SHIFT +#define FDCAN_RXF1S_F1GI_MASK FDCAN_RXFIFO_GI_MASK + +/* F1PI[1:1]: Put index of Rx FIFO 1 */ +#define FDCAN_RXF1S_F1PI_SHIFT FDCAN_RXFIFO_PI_SHIFT +#define FDCAN_RXF1S_F1PI_MASK FDCAN_RXFIFO_PI_MASK + +#define FDCAN_RXF1S_F1F FDCAN_RXFIFO_FF +#define FDCAN_RXF1S_RF1L FDCAN_RXFIFO_RFL + +/* R1AI[2:0]: Rx FIFO 1 acknowledge index */ +#define FDCAN_RXF1A_R1AI_SHIFT FDCAN_RXFIFO_AI_SHIFT +#define FDCAN_RXF1A_R1AI_MASK FDCAN_RXFIFO_AI_MASK + +#define FDCAN_TXBC_TFQM (1 << 24) + +/* TFFL[2:0]: Tx FIFO free level */ +#define FDCAN_TXFQS_TFFL_SHIFT 0 +#define FDCAN_TXFQS_TFFL_MASK 0x7 + +/* TFGI[1:0]: Tx FIFO get index */ +#define FDCAN_TXFQS_TFGI_SHIFT 0 +#define FDCAN_TXFQS_TFGI_MASK 0x3 + +/* TFQPI[1:0]: Tx FIFO put index */ +#define FDCAN_TXFQS_TFQPI_SHIFT 0 +#define FDCAN_TXFQS_TFQPI_MASK 0x3 + +#define FDCAN_TXFQS_TFQF (1 << 0) + +/** @defgroup fdcan_txbrp FDCAN_TXBRP Transmit request pending bits + * @{ + */ +#define FDCAN_TXBRP_TRP0 (1 << 0) +#define FDCAN_TXBRP_TRP1 (1 << 1) +#define FDCAN_TXBRP_TRP2 (1 << 2) +/**@}*/ + +/** @defgroup fdcan_txbar FDCAN_TXBAR Transmit buffer add request bits + * @{ + */ +#define FDCAN_TXBAR_AR0 (1 << 0) +#define FDCAN_TXBAR_AR1 (1 << 1) +#define FDCAN_TXBAR_AR2 (1 << 2) +/**@}*/ + +/** @defgroup fdcan_txbcr FDCAN_TXBCR Transmit buffer cancel request bits + * @{ + */ +#define FDCAN_TXBCR_CR0 (1 << 0) +#define FDCAN_TXBCR_CR1 (1 << 1) +#define FDCAN_TXBCR_CR2 (1 << 2) +/**@}*/ + +/** @defgroup fdcan_txbto FDCAN_TXBTO Transmit buffer transfer occured bits + * @{ + */ +#define FDCAN_TXBTO_TO0 (1 << 0) +#define FDCAN_TXBTO_TO1 (1 << 1) +#define FDCAN_TXBTO_TO2 (1 << 2) +/**@}*/ + +/** @defgroup fdcan_txbcf FDCAN_TXBCF Transmit buffer cancellation finished bits + * @{ + */ +#define FDCAN_TXBCF_CF0 (1 << 0) +#define FDCAN_TXBCF_CF1 (1 << 1) +#define FDCAN_TXBCF_CF2 (1 << 2) +/**@}*/ + +/** @defgroup fdcan_txbtie FDCAN_TXBTIE Transmit interrupt enable bits + * + * Each bit enables or disables transmit interrupt for transmit buffer + * slot. + * @{ + */ +#define FDCAN_TXBTIE_TIE0 (1 << 0) +#define FDCAN_TXBTIE_TIE1 (1 << 1) +#define FDCAN_TXBTIE_TIE2 (1 << 2) +/**@}*/ + +/** @defgroup fdcan_txbcie FDCAN_TXBCIE Transmit cancelled interrupt enable bits + * + * Each bit enables or disables transmit cancelled interrupt for transmit buffer + * slot. + * @{ + */ +#define FDCAN_TXBCIE_CFIE0 (1 << 0) +#define FDCAN_TXBCIE_CFIE1 (1 << 1) +#define FDCAN_TXBCIE_CFIE2 (1 << 2) +/**@}*/ + +/* EFFL[2:0]: Event FIFO fill level*/ +#define FDCAN_TXEFS_EFFL_SHIFT 0 +#define FDCAN_TXEFS_EFFL_MASK 0x7 + +/* EFG[1:0]: Event FIFO get index */ +#define FDCAN_TXEFS_EFGI_SHIFT 8 +#define FDCAN_TXEFS_EFGI_MASK 0x3 + +/* EFPI[1:0]: Event FIFO put index */ +#define FDCAN_TXEFS_EFPI_SHIFT 16 +#define FDCAN_TXEFS_EFPI_MASK 0x3 + +#define FDCAN_TXEFS_EFF (1 << 24) +#define FDCAN_TXEFS_TEF (1 << 25) + +/* EFAI[1:0]: Event FIFO acknowledge index */ +#define FDCAN_TXEFA_EFAI_SHIFT 0 +#define FDCAN_TXEFA_EFAI_MASK 0x3 + + +/* PDIV[3:0]: Input clock divider */ +#define FDCAN_CKDIV_PDIV_SHIFT 0 +#define FDCAN_CKDIV_PDIV_MASK 0xF + +/* --- FD-CAN memory block defines------------------------------------------ */ + +/** Structure describing standard ID filter. + * Standard ID filter is composed of one 32bit value. + * This region of memory cannot be accessed in quantities less than 32bits. + */ +struct fdcan_standard_filter { + /** Aggregate of filter type, filter action and two IDs */ + uint32_t type_id1_conf_id2; +}; + +#define FDCAN_SFT_SHIFT 30 +#define FDCAN_SFT_MASK 0x3 + +/** @defgroup fdcan_sft Standard ID filter match type + * + * Matching strategy for standard ID filters. + * @{ + */ +/** Filter matches all messages in range from id1 to id2. */ +#define FDCAN_SFT_RANGE 0x0 + +/** Filter matches messages with id1 or id2 */ +#define FDCAN_SFT_DUAL 0x1 + +/** Filter matches messages which match id1 after being unmasked + * using id2. */ +#define FDCAN_SFT_ID_MASK 0x2 + +/** Disable this filter. */ +#define FDCAN_SFT_DISABLE 0x3 +/**@}*/ + +#define FDCAN_SFEC_SHIFT 27 +#define FDCAN_SFEC_MASK 0x7 + +/** @defgroup fdcan_sfec Standard ID filter action + * + * Defines possible actions for standard ID filters. All actions except + * of @ref FDCAN_SFEC_PRIO cause filter matching to terminate immediately + * with desired outcome. FDCAN_SFEC_PRIO sets priority flag for message + * and continues processing remaining filters. + * @{ + */ + +/** Filter is disabled. No matchin occurrs. */ +#define FDCAN_SFEC_DISABLE 0x0 + +/** Put message into FIFO0 */ +#define FDCAN_SFEC_FIFO0 0x1 + +/** Put message into FIFO1 */ +#define FDCAN_SFEC_FIFO1 0x2 + +/** Reject message */ +#define FDCAN_SFEC_REJECT 0x3 + +/** Treat message as priority message (and continue processing further rules) */ +#define FDCAN_SFEC_PRIO 0x4 + +/** Treat message as priority and put it into FIFO0 */ +#define FDCAN_SFEC_PRIO_FIFO0 0x5 + +/** Treat message as priority and put it into FIFO1 */ +#define FDCAN_SFEC_PRIO_FIFO1 0x6 +/**@}*/ + +/** Amount of standard filters allocated in Message RAM + * This number may vary between devices. 28 is value valid + * for STM32G4 + **/ +#define FDCAN_SFT_MAX_NR 28 + +/* SFEC = 0x7 is unused */ + +#define FDCAN_SFID1_SHIFT 16 +#define FDCAN_SFID1_MASK 0x7FF + +#define FDCAN_SFID2_SHIFT 0 +#define FDCAN_SFID2_MASK 0x7FF + +/** Structure describing extended ID filters. + * Extended ID filter is composed of two 32bit values. + * This region of memory cannot be accessed in quantities less than 32bits. + */ +struct fdcan_extended_filter { + /** Aggregate of filter action and extended ID */ + uint32_t conf_id1; + /** Aggregate of filter type and extended ID or mask */ + uint32_t type_id2; +}; + +#define FDCAN_EFEC_SHIFT 29 +#define FDCAN_EFEC_MASK 0x7 + +/** @defgroup fdcan_efec Extended ID filter action + * + * These are possible actions, extended filter can have. If filter is + * disabled, then no matching is performed. All other actions except of + * @ref FDCAN_EFEC_PRIO cause matching to terminate with required outcome. + * FDCAN_EFEC_PRIO marks message as priority and continues matching. + * @{ + */ + +/** Disable this filter. */ +#define FDCAN_EFEC_DISABLE 0x0 + +/** Put message into FIFO0 */ +#define FDCAN_EFEC_FIFO0 0x1 + +/** Put message into FIFO1 */ +#define FDCAN_EFEC_FIFO1 0x2 + +/** Reject message */ +#define FDCAN_EFEC_REJECT 0x3 + +/** Treat message as priority message (and continue processing further rules) */ +#define FDCAN_EFEC_PRIO 0x4 + +/** Treat message as priority and put it into FIFO0 */ +#define FDCAN_EFEC_PRIO_FIFO0 0x5 + +/** Treat message as priority and put it into FIFO1 */ +#define FDCAN_EFEC_PRIO_FIFO1 0x6 +/**@}*/ + +#define FDCAN_EFID1_SHIFT 0 +#define FDCAN_EFID1_MASK 0x1FFFFFFF + +#define FDCAN_EFT_SHIFT 30 +#define FDCAN_EFT_MASK 0x3 + +/** @defgroup fdcan_eft Extended ID filter match type + * + * Matching strategy for extended ID filters. + * @{ + */ +/** Filter matches all messages in range from id1 to id2. */ +#define FDCAN_EFT_RANGE 0x0 + +/** Filter matches messages with id1 or id2 */ +#define FDCAN_EFT_DUAL 0x1 + +/** Filter matches messages which match id1 after being unmasked + * using id2. */ +#define FDCAN_EFT_ID_MASK 0x2 + +/** Similar to @ref FDCAN_EFT_RANGE except of ignoring global mask + * set using @ref FDCAN_XIDAM register. + */ +#define FDCAN_EFT_RANGE_NOXIDAM 0x3 +/**@}*/ + +#define FDCAN_EFID2_SHIFT 0 +#define FDCAN_EFID2_MASK 0x1FFFFFFF + +/** Amount of extended filters allocated in Message RAM + * This number may vary between devices. 8 is value valid + * for STM32G4 + **/ +#define FDCAN_EFT_MAX_NR 8 + +/** Structure describing receive FIFO element. + * Receive FIFO element consists of 2 32bit values for header + * and 16 32bit values for message payload. + * This area of memory can only be accessed in 32bit quantities + */ +struct fdcan_rx_fifo_element { + /** Aggregate of message identifier and flags. */ + uint32_t identifier_flags; + /** Aggregate of filter match ID, transfer format, DLC and timestamp */ + uint32_t filt_fmt_dlc_ts; + /** Message payload data */ + uint32_t data[64 / sizeof(uint32_t)]; +}; + +/** Structure describing transmit event element. + * Transmit event element consists of 2 32bit values. + * This area of memory can only be accessed in 32bit quantities + */ +struct fdcan_tx_event_element { + /** Aggregate of message identifier and flags. */ + uint32_t identifier_flags; + + /** Aggregate of event ID, transfer format, DLC and timestamp */ + uint32_t evt_fmt_dlc_ts; +}; + +/** Structure describing transmit buffer element. + * Transmit buffer consists of 2 32bit values for header + * and 16 32bit values for message payload. + * This area of memory can only be accessed in 32bit quantities + */ +struct fdcan_tx_buffer_element { + /** Aggregate of message identifier and flags. */ + uint32_t identifier_flags; + + /** Aggregate of event ID, transfer format and DLC */ + uint32_t evt_fmt_dlc_res; + /** Message payload data */ + uint32_t data[64 / sizeof(uint32_t)]; +}; + +/** @defgroup fdcan_fifo_flags FIFO / buffer flags + * @{ + */ +#define FDCAN_FIFO_ESI (1 << 31) +#define FDCAN_FIFO_XTD (1 << 20) +#define FDCAN_FIFO_RTR (1 << 29) +#define FDCAN_FIFO_EFC (1 << 23) +#define FDCAN_FIFO_FDF (1 << 21) +#define FDCAN_FIFO_BRS (1 << 20) +/**@}*/ + +#define FDCAN_FIFO_EID_SHIFT 0 +#define FDCAN_FIFO_EID_MASK 0x1FFFFFFF + +#define FDCAN_FIFO_SID_SHIFT 18 +#define FDCAN_FIFO_SID_MASK 0x7FF + +#define FDCAN_FIFO_DLC_SHIFT 16 +#define FDCAN_FIFO_DLC_MASK 0xF + +#define FDCAN_FIFO_MM_SHIFT 24 +#define FDCAN_FIFO_MM_MASK 0xFF + +#define FDCAN_FIFO_ANMF (1 << 31) +#define FDCAN_FIFO_FIDX_SHIFT 24 +#define FDCAN_FIFO_FIDX_MASK 0x7F + +#define FDCAN_FIFO_RXTS_SHIFT 0 +#define FDCAN_FIFO_RXTS_MASK 0xFFFF + +/** Message RAM layout for one FDCAN block. + * There are as many memory blocks as there are FDCAN blocks + */ +struct fdcan_message_ram { + /* List of standard ID filters */ + struct fdcan_standard_filter lfssa[FDCAN_SFT_MAX_NR]; + + /* List of extended ID filters */ + struct fdcan_extended_filter lfesa[FDCAN_EFT_MAX_NR]; + + /* Buffer area for two receive FIFOs each having space for three messages */ + struct fdcan_rx_fifo_element rx_fifo[2][3]; + + /* Buffer area for transmit event buffers */ + struct fdcan_tx_event_element tx_event[3]; + + /* Buffer area for transmitted messages. May act either as FIFO or as queue + * depending on configuration + */ + struct fdcan_tx_buffer_element tx_buffer[3]; +}; + + +/* --- FD-CAN error returns ------------------------------------------------- */ + +/** FDCAN error return values + */ +enum fdcan_error { + /** No error. Operation finished successfully */ + FDCAN_E_OK, + + /** Value provided was out of range */ + FDCAN_E_OUTOFRANGE, + + /** Timeout waiting for FDCAN block to accept INIT bit change */ + FDCAN_E_TIMEOUT, + + /** Value provided was invalid (FIFO index, FDCAN block base address, length, etc.) */ + FDCAN_E_INVALID, + + /** Device is busy: Transmit buffer is full, unable to queue additional message or device + * is outside of INIT mode and cannot perform desired operation. */ + FDCAN_E_BUSY, + + /** Receive buffer is empty, unable to read any new message */ + FDCAN_E_NOTAVAIL +}; + +/**@}*/ + +/* --- FD-CAN functions ----------------------------------------------------- */ + +BEGIN_DECLS + +int fdcan_init(uint32_t canport, uint32_t timeout); + +void fdcan_set_can(uint32_t canport, bool auto_retry_disable, bool rx_fifo_locked, + bool tx_queue_mode, bool silent, uint32_t n_sjw, uint32_t n_ts1, uint32_t n_ts2, + uint32_t n_br_presc); + +void fdcan_set_fdcan(uint32_t canport, bool brs_enable, bool fd_op_enable, + uint32_t f_sjw, uint32_t f_ts1, uint32_t f_ts2, uint32_t f_br_presc); + +void fdcan_set_test(uint32_t canport, bool testing, bool loopback); + +void fdcan_init_filter(uint32_t canport, uint8_t std_filt, uint8_t ext_filt); + +int fdcan_start(uint32_t canport, uint32_t timeout); + +int fdcan_get_init_state(uint32_t canport); + +void fdcan_set_std_filter(uint32_t canport, uint32_t nr, + uint8_t id_list_mode, uint32_t id1, uint32_t id2, + uint8_t action); + +void fdcan_set_ext_filter(uint32_t canport, uint32_t nr, + uint8_t id_list_mode, uint32_t id1, uint32_t id2, + uint8_t action); + +void fdcan_enable_irq(uint32_t canport, uint32_t irq); +void fdcan_disable_irq(uint32_t canport, uint32_t irq); + +int fdcan_transmit(uint32_t canport, uint32_t id, bool ext, bool rtr, + bool fdcan_fmt, bool btr_switch, uint8_t length, const uint8_t *data); + +int fdcan_receive(uint32_t canport, uint8_t fifo, bool release, uint32_t *id, + bool *ext, bool *rtr, uint8_t *fmi, uint8_t *length, + uint8_t *data, uint16_t *timestamp); + +void fdcan_release_fifo(uint32_t canport, uint8_t fifo); + +bool fdcan_available_tx(uint32_t canport); +bool fdcan_available_rx(uint32_t canport, uint8_t fifo); + +END_DECLS + + +#endif diff --git a/lib/stm32/common/fdcan.c b/lib/stm32/common/fdcan.c new file mode 100644 index 00000000..30e6956a --- /dev/null +++ b/lib/stm32/common/fdcan.c @@ -0,0 +1,779 @@ +/** @defgroup fdcan_file FDCAN peripheral API + * + * @ingroup peripheral_apis + * + * @brief libopencm3 STM32 FDCAN + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + * Devices can have up to three FDCAN peripherals residing in one FDCAN block. The peripherals + * support both CAN 2.0 A and B standard and Bosch FDCAN standard. FDCAN frame format and + * bitrate switching is supported. The peripheral has several filters for incoming messages that + * can be distributed between two FIFOs and three transmit mailboxes. For transmitted messages + * it is possible to opt for event notification once message is transmitted. + * + * LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + + +/* --- FD-CAN internal functions -------------------------------------------- */ + +/** Routine implementing FDCAN_CCCR's INIT bit manipulation. + * + * This routine will change INIT bit and wait for it to actually + * change its value. If change won't happen before timeout, + * error is signalized. If INIT bit already has value which + * should be set, this function will return immediately. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] set new value of INIT, true means set + * @param [in] timeout Amount of busyloop cycles, function will wait for FDCAN + * to switch it's state. If set to 0, then function returns immediately. + * @returns FDCAN_E_OK on success, FDCAN_E_TIMEOUT if INIT bit value + * didn't change before timeout has expired. + */ +static int fdcan_cccr_init_cfg(uint32_t canport, bool set, uint32_t timeout) +{ + uint32_t expected; + uint32_t wait_ack; + + if (set) { + if ((FDCAN_CCCR(canport) & FDCAN_CCCR_INIT) == FDCAN_CCCR_INIT) { + /* Already there, sir */ + return FDCAN_E_OK; + } + + FDCAN_CCCR(canport) |= FDCAN_CCCR_INIT; + expected = FDCAN_CCCR_INIT; + } else { + if ((FDCAN_CCCR(canport) & FDCAN_CCCR_INIT) == 0) { + /* Already there, sir */ + return FDCAN_E_OK; + } + + FDCAN_CCCR(canport) &= ~FDCAN_CCCR_INIT; + expected = 0; + } + + /* Wait, until INIT bit is acknowledged */ + wait_ack = timeout; + while ((wait_ack--) && + ((FDCAN_CCCR(canport) & FDCAN_CCCR_INIT) == expected)); + + if ((FDCAN_CCCR(canport) & FDCAN_CCCR_INIT) == expected) { + return FDCAN_E_OK; + } else { + return FDCAN_E_TIMEOUT; + } +} + +/** Return ID of next free Tx buffer. + * + * Examines transmit buffer allocation in message RAM + * and returns ID of buffer, which is free. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @returns Non-negative number ID of Tx buffer which is free, + * or FDCAN_E_BUSY if no Tx buffer is available + */ +static int fdcan_get_free_txbuf(uint32_t canport) +{ + if ((FDCAN_TXBRP(canport) & FDCAN_TXBRP_TRP0) == 0) { + return 0; + } else if ((FDCAN_TXBRP(canport) & FDCAN_TXBRP_TRP1) == 0) { + return 1; + } else if ((FDCAN_TXBRP(canport) & FDCAN_TXBRP_TRP2) == 0) { + return 2; + } + + return FDCAN_E_BUSY; +} + +/** Returns fill state and next available get index from receive FIFO. + * + * Examines FDCAN receive FIFO and returns fill status of FIFO and ID of + * next message available for reading. If fill status is 0 (FIFO is empty), + * then get index is undefined. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] fifo_id ID of fifo queried (currently 0 or 1) + * @param [out] get_index Address of buffer where next get index will be stored + * @param [out] pending_frames Address of buffer where amount of pending frame will be stored. + */ +static void fdcan_get_fill_rxfifo(uint32_t canport, uint8_t fifo_id, unsigned *get_index, + unsigned *pending_frames) +{ + *get_index = (FDCAN_RXFIS(canport, fifo_id) >> FDCAN_RXFIFO_GI_SHIFT) + & FDCAN_RXFIFO_GI_MASK; + + *pending_frames = (FDCAN_RXFIS(canport, fifo_id) >> FDCAN_RXFIFO_FL_SHIFT) + & FDCAN_RXFIFO_FL_MASK; +} + +/** Obtain address of FDCAN Message RAM for certain FDCAN block. + * + * @param [in] canport identification of FDCAN block. See @ref fdcan_block. + * @return Address of Message RAM for given FDCAN block or null pointer + * if FDCAN block identification is invalid. + */ +static struct fdcan_message_ram *fdcan_get_msgram_addr(uint32_t canport) +{ + /* This piece of code may look wrong, after one examines + * STM32G4 datasheet and/or g4/memorymap.h. There are three + * memory regions defined for FDCANx_RAM_BASE. They are 0x400 + * bytes apart as per chapter 2.2.2 of [RM0440]. + * + * It turns out, that these addresses are not in line with what + * is specified later in chapter 44.3.3 of [RM0440]. There it is + * stated, that message RAMs are packed and in case of multiple + * FDCAN blocks, message RAM for n-th FDCAN starts at address + * end of (n-1)-th block + 4 (explicitly, offset 0x354). + * + * It turns out, that this statement is also false! In fact FDCAN + * message RAMs are packed tightly and n-th block starts immediately + * after (n-1)-th block ends. Thus offset is going to be computed + * using formula: + * + * FDCAN1_RAM_BASE + (block_id * sizeof(struct fdcan_message_ram)) + */ + if (canport == CAN1) { + return (struct fdcan_message_ram *) (FDCAN1_RAM_BASE + 0); + } else if (canport == CAN2) { + return (struct fdcan_message_ram *) + (FDCAN1_RAM_BASE + sizeof(struct fdcan_message_ram)); + } else if (canport == CAN3) { + return (struct fdcan_message_ram *) + (FDCAN1_RAM_BASE + (2 * sizeof(struct fdcan_message_ram))); + } + + return NULL; +} + +/** Converts frame length to DLC value. + * + * Works for both CAN and FDCAN frame lengths. If length + * is invalid value, then returns 0xFF. + * + * @param [in] length intended frame payload length in bytes + * @returns DLC value representing lengths or 0xFF if length cannot + * be encoded into DLC format (applies only to FDCAN frame lengths) + */ +static uint32_t fdcan_length_to_dlc(uint8_t length) +{ + if (length <= 8) { + return length; + } else if (length <= 24) { + if ((length % 4) != 0) { + return 0xFF; + } + return 8 + ((length - 8) / 4); + } else { + if ((length % 16) != 0) { + return 0xFF; + } + return 11 + (length / 16); + } +} + +/** Converts DLC value into frame payload length. + * + * Works for both CAN and FDCAN DLC values. + * + * @param [in] dlc DLC value + * @returns data payload length in bytes + */ +static uint8_t fdcan_dlc_to_length(uint32_t dlc) +{ + if (dlc <= 8) { + return dlc; + } else if (dlc <= 12) { + return 8 + ((dlc - 8) * 4); + } else { + return 16 + ((dlc - 12) * 16); + } +} + +/* --- FD-CAN functions ----------------------------------------------------- */ + +/** @ingroup fdcan_file */ +/**@{ + * */ + +/** Put FDCAN block into INIT mode for setup + * + * Initialize the selected CAN peripheral block. This function will switch CAN block + * into initialization mode. CAN block is then left in initialization mode in order to + * perform setup, which can't be adjusted once FDCAN block is started. It is mandatory + * to call at least @ref fdcan_set_can function to configure basic timing values for + * CAN 2.0 operation. Functions which only have effect, if FDCAN block is in INIT mode + * are: + * * @ref fdcan_set_can + * * @ref fdcan_set_fdcan + * * @ref fdcan_init_filter + * * @ref fdcan_set_test + * + * You can check if FDCAN block is in INIT mode or it is started using + * @ref fdcan_get_init_state. + * + * @param[in] canport CAN register base address. See @ref fdcan_block. + * @param [in] timeout Amount of empty busy loops, which routine should wait for FDCAN + * confirming that it entered INIT mode. If set to 0, function will return + * immediately. + * @returns Operation error status. See @ref fdcan_error. + */ +int fdcan_init(uint32_t canport, uint32_t timeout) +{ + if (fdcan_cccr_init_cfg(canport, true, timeout) != 0) { + return FDCAN_E_TIMEOUT; + } + + FDCAN_CCCR(canport) |= FDCAN_CCCR_CCE; + + return FDCAN_E_OK; +} + +/** Set essential FDCAN block parameters for plain CAN operation + * + * Allows configuration of prescalers and essential transmit and FIFO behavior + * used during transmission in plain CAN 2.0 mode. In this mode FDCAN frame format + * is not available nor is possible to use fast bitrates. + * This function does neither enable FD-CAN mode after reset nor disable it + * after re-entering INIT mode of previously configured block. Timing values set + * here are valid for both arbitration phase of all frames and for data phase of + * both CAN and FDCAN frames, which don't use bitrate switching. This function can + * only be called after FDCAN block has been switched into INIT mode. + * It is possible to receive FDCAN frames even if FDCAN block is configured only using + * this function as long as bitrate switching is not used. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] auto_retry_disable Disable automatic frame retransmission on error + * @param [in] rx_fifo_locked Enable FIFO locked mode. Upon FIFO overflow all received + * messages are discarded. + * @param [in] tx_queue_mode Enable transmission queue mode. Otherwise transmission + * works in FIFO mode. + * @param [in] silent Enable silent mode. Transmitter stays recessive all the time. + * @param [in] n_sjw Resynchronization time quanta jump width + * @param [in] n_ts1 Time segment 1 time quanta + * @param [in] n_ts2 Time segment 2 time quanta + * @param [in] n_br_presc Arbitration phase / CAN mode bitrate prescaler + */ +void fdcan_set_can(uint32_t canport, bool auto_retry_disable, bool rx_fifo_locked, + bool tx_queue_mode, bool silent, uint32_t n_sjw, uint32_t n_ts1, uint32_t n_ts2, + uint32_t n_br_presc) +{ + FDCAN_NBTP(canport) = (n_sjw << FDCAN_NBTP_NSJW_SHIFT) + | (n_ts1 << FDCAN_NBTP_NTSEG1_SHIFT) + | (n_ts2 << FDCAN_NBTP_NTSEG2_SHIFT) + | (n_br_presc << FDCAN_NBTP_NBRP_SHIFT); + + if (tx_queue_mode) { + FDCAN_TXBC(canport) |= FDCAN_TXBC_TFQM; + } else { + FDCAN_TXBC(canport) &= ~FDCAN_TXBC_TFQM; + } + + if (auto_retry_disable) { + FDCAN_CCCR(canport) |= FDCAN_CCCR_DAR; + } else { + FDCAN_CCCR(canport) &= ~FDCAN_CCCR_DAR; + } + + if (silent) { + FDCAN_CCCR(canport) |= FDCAN_CCCR_MON; + } else { + FDCAN_CCCR(canport) &= ~FDCAN_CCCR_MON; + } + + if (rx_fifo_locked) { + FDCAN_RXGFC(canport) &= ~(FDCAN_RXGFC_F1OM | FDCAN_RXGFC_F0OM); + } else { + FDCAN_RXGFC(canport) |= FDCAN_RXGFC_F1OM | FDCAN_RXGFC_F0OM; + } + +} + +/** Set FDCAN block parameters for FDCAN transmission + * + * Enables and configures parameters related to FDCAN transmission. This function + * allows configuration of bitrate switching, FDCAN frame format and fast mode + * timing. This function can only be called if FDCAN block is in INIT mode. + * It is safe to call this function on previously configured block in order + * to enable/disable/change FDCAN mode parameters. Non-FDCAN parameters won't + * be affected. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] brs_enable Enable FDCAN bitrate switching for fast mode operation + * @param [in] fd_op_enable Enable transmission of FDCAN-formatted frames + * @param [in] f_sjw Resynchronization time quanta jump width in fast mode + * @param [in] f_ts1 Time segment 1 time quanta in fast mode + * @param [in] f_ts2 Time segment 2 time quanta in fast mode + * @param [in] f_br_presc Fast mode operation bitrate prescaler + */ +void fdcan_set_fdcan(uint32_t canport, bool brs_enable, bool fd_op_enable, + uint32_t f_sjw, uint32_t f_ts1, uint32_t f_ts2, uint32_t f_br_presc) +{ + FDCAN_DBTP(canport) = (f_sjw << FDCAN_DBTP_DSJW_SHIFT) + | (f_ts1 << FDCAN_DBTP_DTSEG1_SHIFT) + | (f_ts2 << FDCAN_DBTP_DTSEG2_SHIFT) + | (f_br_presc << FDCAN_DBTP_DBRP_SHIFT); + + if (fd_op_enable) { + FDCAN_CCCR(canport) |= FDCAN_CCCR_FDOE; + } else { + FDCAN_CCCR(canport) &= ~FDCAN_CCCR_FDOE; + } + + if (brs_enable) { + FDCAN_CCCR(canport) |= FDCAN_CCCR_BRSE; + } else { + FDCAN_CCCR(canport) &= ~FDCAN_CCCR_BRSE; + } +} + +/** Set FDCAN block testing features. + * + * Configures self-test functions of FDCAN block. It is safe to call + * this function on fully configured interface. This function can + * only be called after FDCAN block is put into INIT mode. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] testing Enables testing mode of FDCAN block + * @param [in] loopback Enables transmission loopback + */ +void fdcan_set_test(uint32_t canport, bool testing, bool loopback) +{ + if (testing) { + FDCAN_CCCR(canport) |= FDCAN_CCCR_TEST; + if (loopback) { + FDCAN_TEST(canport) |= FDCAN_TEST_LBCK; + } else { + FDCAN_TEST(canport) &= ~FDCAN_TEST_LBCK; + } + } else { + FDCAN_CCCR(canport) &= ~FDCAN_CCCR_TEST; + /* FDCAN_TEST is automatically reset to default values by + * FDCAN at this point */ + } +} + +/** Enable FDCAN operation after FDCAN block has been set up. + * + * This function will disable FDCAN configuration effectively + * allowing FDCAN to sync up with the bus. After calling this function + * it is not possible to reconfigure amount of filter rules, yet + * it is possible to configure rules themselves. FDCAN block operation + * state can be checked using @ref fdcan_get_init_state. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] timeout Amount of empty busy loops, which routine should wait for FDCAN + * confirming that it left INIT mode. If set to 0, function will return + * immediately. + * @returns Operation error status. See @ref fdcan_error. + * @note If this function returns with timeout, it usually means that + * FDCAN_clk is not set up properly. + */ +int fdcan_start(uint32_t canport, uint32_t timeout) +{ + /* Error here usually means, that FDCAN_clk is not set up + * correctly, or at all. This usually can't be seen above + * when INIT is set to 1, because default value for INIT is + * 1 as long as one has FDCAN_pclk configured properly. + **/ + if (fdcan_cccr_init_cfg(canport, false, timeout) != 0) { + return FDCAN_E_TIMEOUT; + } + + return FDCAN_E_OK; +} + +/** Return current FDCAN block operation state. + * + * This function effectively returns value of FDCAN_CCCR's INIT bit. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @returns 1 if FDCAN block is in INIT mode, 0 if it is already started. + */ +int fdcan_get_init_state(uint32_t canport) +{ + return ((FDCAN_CCCR(canport) & FDCAN_CCCR_INIT) == FDCAN_CCCR_INIT); +} + +/** Configure amount of filters and initialize filtering block. + * + * This function allows to configure global amount of filters present. + * FDCAN block will only ever check as many filters as this function configures. + * Function will also clear all filter blocks to zero values. This function + * can be only called after @ref fdcan_init has already been called and + * @ref fdcan_start has not been called yet as registers holding filter + * count are write-protected unless FDCAN block is in INIT mode. It is possible + * to reconfigure filters (@ref fdcan_set_std_filter and @ref fdcan_set_ext_filter) + * after FDCAN block has already been started. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] std_filt requested amount of standard ID filter rules (0-28) + * @param [in] ext_filt requested amount of extended ID filter rules (0-8) + */ +void fdcan_init_filter(uint32_t canport, uint8_t std_filt, uint8_t ext_filt) +{ + struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); + + /* Only perform initialization of message RAM if there are + * any filters required + */ + if (std_filt > 0) { + FDCAN_RXGFC(canport) = + (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSS_MASK << FDCAN_RXGFC_LSS_SHIFT)) + | (std_filt << FDCAN_RXGFC_LSS_SHIFT); + + + for (int q = 0; q < FDCAN_SFT_MAX_NR; ++q) { + ram->lfssa[q].type_id1_conf_id2 = 0; + } + } else { + /* Reset filter count to zero */ + FDCAN_RXGFC(canport) = + (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSS_MASK << FDCAN_RXGFC_LSS_SHIFT)); + } + + if (ext_filt > 0) { + FDCAN_RXGFC(canport) = + (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSE_MASK << FDCAN_RXGFC_LSE_SHIFT)) + | (ext_filt << FDCAN_RXGFC_LSE_SHIFT); + + for (int q = 0; q < FDCAN_EFT_MAX_NR; ++q) { + ram->lfesa[q].conf_id1 = 0; + ram->lfesa[q].type_id2 = 0; + } + } else { + /* Reset filter count to zero */ + FDCAN_RXGFC(canport) = + (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSE_MASK << FDCAN_RXGFC_LSE_SHIFT)); + } +} + +/** Configure filter rule for standard ID frames. + * + * Sets up filter rule for frames having standard ID. Each FDCAN block can + * have its own set of filtering rules. It is only possible to configure as + * many filters as was configured previously using @ref fdcan_init_filter. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] nr number of filter to be configured + * @param [in] id_list_mode Mode in which id1 and id2 are used to match the rule. + * See @ref fdcan_sft. + * @param [in] id1 standard ID for matching. Used as exact value, lower bound or bit + * pattern depending on matching mode selected + * @param [in] id2 standard ID or bitmask. Used as exact value, upper bound or bit mask + * depending on matching mode selected + * @param [in] action Action performed if filtering rule matches frame ID. + * See @ref fdcan_sfec. + */ +void fdcan_set_std_filter(uint32_t canport, uint32_t nr, + uint8_t id_list_mode, uint32_t id1, uint32_t id2, + uint8_t action) +{ + struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); + + /* id_list_mode and action are passed unguarded. Simply use + * defines and it will be OK. id1 and id2 are masked for + * correct size, because it is way too simple to pass ID + * larger than 11 bits unintentionally. It then leads to all + * kind of extremely weird errors while excessive ID bits + * overflow into flags. This tends to be extremely time + * consuming to debug. + */ + ram->lfssa[nr].type_id1_conf_id2 = + (id_list_mode << FDCAN_SFT_SHIFT) + | (action << FDCAN_SFEC_SHIFT) + | ((id1 & FDCAN_SFID1_MASK) << FDCAN_SFID1_SHIFT) + | ((id2 & FDCAN_SFID2_MASK) << FDCAN_SFID2_SHIFT); + + return; +} + +/** Configure filter rule for extended ID frames. + * + * Sets up filter rule for frames having extended ID. Each FDCAN block can + * have its own set of filtering rules. It is only possible to configure as + * many filters as was configured previously using @ref fdcan_init_filter. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] nr number of filter to be configured + * @param [in] id_list_mode mode in which id1 and id2 are used to match the rule. + * See @ref fdcan_eft. + * @param [in] id1 extended ID for matching. Used as exact value, lower bound or bit + * pattern depending on matching mode selected + * @param [in] id2 extended ID or bitmask. Used as exact value, upper bound or bit mask + * depending on matching mode selected + * @param [in] action Action performed if filtering rule matches frame ID. + * See @ref fdcan_efec. + */ +void fdcan_set_ext_filter(uint32_t canport, uint32_t nr, + uint8_t id_list_mode, uint32_t id1, uint32_t id2, + uint8_t action) +{ + struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); + + ram->lfesa[nr].conf_id1 = + (action << FDCAN_EFEC_SHIFT) + | ((id1 & FDCAN_EFID1_MASK) << FDCAN_EFID1_SHIFT); + + ram->lfesa[nr].type_id2 = + (id_list_mode << FDCAN_EFT_SHIFT) + | ((id2 & FDCAN_EFID2_MASK) << FDCAN_EFID2_SHIFT); +} + +/** Transmit Message using FDCAN + * + * @param [in] canport CAN block register base. See @ref fdcan_block. + * @param [in] id Message ID + * @param [in] ext Extended message ID + * @param [in] rtr Request transmit + * @param [in] fdcan_fmt Use FDCAN format + * @param [in] btr_switch Switch bitrate for data portion of frame + * @param [in] length Message payload length. Must be valid CAN or FDCAN frame length + * @param [in] data Message payload data + * @returns int 0, 1 or 2 on success and depending on which outgoing mailbox got + * selected. Otherwise returns error code. For error codes, see @ref fdcan_error. + */ +int fdcan_transmit(uint32_t canport, uint32_t id, bool ext, bool rtr, + bool fdcan_fmt, bool btr_switch, uint8_t length, const uint8_t *data) +{ + int mailbox; + uint32_t dlc, flags = 0; + + mailbox = fdcan_get_free_txbuf(canport); + + if (mailbox == FDCAN_E_BUSY) { + return mailbox; + } + + struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); + + /* Early check: if FDCAN message lentgh is > 8, it must be + * a multiple of 4 *and* fdcan format must be enabled. + */ + dlc = fdcan_length_to_dlc(length); + + if (dlc == 0xFF) { + return FDCAN_E_INVALID; + } + + if (ext) { + ram->tx_buffer[mailbox].identifier_flags = FDCAN_FIFO_XTD + | ((id & FDCAN_FIFO_EID_MASK) << FDCAN_FIFO_EID_SHIFT); + } else { + ram->tx_buffer[mailbox].identifier_flags = + (id & FDCAN_FIFO_SID_MASK) << FDCAN_FIFO_SID_SHIFT; + } + + if (rtr) { + ram->tx_buffer[mailbox].identifier_flags |= FDCAN_FIFO_RTR; + } + + if (fdcan_fmt) { + flags |= FDCAN_FIFO_FDF; + } + + if (btr_switch) { + flags |= FDCAN_FIFO_BRS; + } + + ram->tx_buffer[mailbox].evt_fmt_dlc_res = + (dlc << FDCAN_FIFO_DLC_SHIFT) | flags; + + for (int q = 0; q < length; q += 4) { + ram->tx_buffer[mailbox].data[q / 4] = *((uint32_t *) &data[q]); + } + + FDCAN_TXBAR(canport) |= 1 << mailbox; + + return mailbox; +} + +/** Receive Message from FDCAN FIFO + * + * Reads one message from receive FIFO. Returns message ID, type of ID, message length + * and message payload. It is mandatory to provide valid pointers to suitably sized buffers + * for these outputs. Additionally, it is optinally possible to provide non-zero pointer to + * obtain filter identification, request of transmission flag and message timestamp. + * If pointers provided for optional outputs are NULL, then no information is returned + * for given pointer. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block + * @param [in] fifo_id FIFO id. + * @param [in] release Release the FIFO automatically after copying data out + * @param [out] id Returned message ID. Mandatory. + * @param [out] ext Returned type of the message ID (true if extended). Mandatory. + * @param [out] rtr Returnes flag if request of transmission was requested. Optional. + * @param [out] fmi Returned ID of the filter which matched this frame. Optional. + * @param [out] length Length of message payload in bytes. Mandatory. + * @param [out] data Buffer for storage of message payload data. Mandatory. + * @param [out] timestamp Returned timestamp of received frame. Optional. + * @returns Operation error status. See @ref fdcan_error. + */ +int fdcan_receive(uint32_t canport, uint8_t fifo_id, bool release, uint32_t *id, + bool *ext, bool *rtr, uint8_t *fmi, uint8_t *length, + uint8_t *data, uint16_t *timestamp) +{ + const struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); + + const struct fdcan_rx_fifo_element *fifo; + + unsigned pending_frames, get_index, dlc, len; + + fdcan_get_fill_rxfifo(canport, fifo_id, &get_index, &pending_frames); + + fifo = ram->rx_fifo[fifo_id]; + + if (pending_frames == 0) { + return FDCAN_E_NOTAVAIL; + } + + dlc = (fifo[get_index].filt_fmt_dlc_ts >> FDCAN_FIFO_DLC_SHIFT) + & FDCAN_FIFO_DLC_MASK; + + len = fdcan_dlc_to_length(dlc); + + *length = len; + if ((fifo[get_index].identifier_flags & FDCAN_FIFO_XTD) == FDCAN_FIFO_XTD) { + *ext = true; + *id = (fifo[get_index].identifier_flags >> FDCAN_FIFO_EID_SHIFT) + & FDCAN_FIFO_EID_MASK; + } else { + *ext = false; + *id = (fifo[get_index].identifier_flags >> FDCAN_FIFO_SID_SHIFT) + & FDCAN_FIFO_SID_MASK; + } + + if (timestamp) { + *timestamp = (uint16_t) (fifo[get_index].filt_fmt_dlc_ts >> FDCAN_FIFO_RXTS_SHIFT) + & FDCAN_FIFO_RXTS_MASK; + } + + if (fmi) { + *fmi = (uint8_t) (fifo[get_index].filt_fmt_dlc_ts >> FDCAN_FIFO_MM_SHIFT) + & FDCAN_FIFO_MM_MASK; + } + + if (rtr) { + *rtr = ((fifo[get_index].identifier_flags & FDCAN_FIFO_RTR) == FDCAN_FIFO_RTR); + } + + for (unsigned int q = 0; q < len; q += 4) { + *((uint32_t *) &data[q]) = fifo[get_index].data[q / 4]; + } + + if (release) { + FDCAN_RXFIA(canport, fifo_id) |= get_index << FDCAN_RXFIFO_AI_SHIFT; + } + + return FDCAN_E_OK; +} + +/** Release receive oldest FIFO entry. + * + * This function will mask oldest entry in FIFO as released making + * space for another received frame. This function can be used if + * fdcan_receive was called using release = false. If used in other + * case, then messages can get lost. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] fifo_id ID of FIFO where release should be performed (0 or 1) + */ +void fdcan_release_fifo(uint32_t canport, uint8_t fifo_id) +{ + unsigned pending_frames, get_index; + + get_index = (FDCAN_RXFIS(canport, fifo_id) >> FDCAN_RXFIFO_GI_SHIFT) + & FDCAN_RXFIFO_GI_SHIFT; + + pending_frames = (FDCAN_RXFIS(canport, fifo_id) >> FDCAN_RXFIFO_FL_SHIFT) + & FDCAN_RXFIFO_FL_SHIFT; + + if (pending_frames) { + FDCAN_RXFIA(canport, fifo_id) |= get_index << FDCAN_RXFIFO_AI_SHIFT; + } +} + +/** Enable IRQ from FDCAN block. + * + * This routine configures FDCAN to enable certain IRQ. + * Each FDCAN block supports two IRQs. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] irq number of IRQ to be enabled (currently 0 or 1) + */ +void fdcan_enable_irq(uint32_t canport, uint32_t irq) +{ + FDCAN_ILE(canport) |= irq & (FDCAN_ILE_INT0 | FDCAN_ILE_INT1); +} + +/** Disable IRQ from FDCAN block. + * + * This routine configures FDCAN to disable certain IRQ. + * Each FDCAN block supports two IRQs. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] irq number of IRQ to be enabled (currently 0 or 1) + */ +void fdcan_disable_irq(uint32_t canport, uint32_t irq) +{ + FDCAN_ILE(canport) &= ~(irq & (FDCAN_ILE_INT0 | FDCAN_ILE_INT1)); +} + +/** Check if there is free transmit buffer. + * + * @param [in] canport FDCAN port. See @ref fdcan_block. + * @returns true if there is at least one free transmit buffer for new message + * to be sent, false otherwise. + */ +bool fdcan_available_tx(uint32_t canport) +{ + return (fdcan_get_free_txbuf(canport) != FDCAN_E_BUSY); +} + +/** Tell if there is message waiting in receive FIFO. + * + * @param [in] canport FDCAN port. See @ref fdcan_block. + * @param [in] fifo Rx FIFO number, 0 or 1 + * @returns true if there is at least one message waiting in given receive FIFO, + * false otherwise. + */ +bool fdcan_available_rx(uint32_t canport, uint8_t fifo) +{ + unsigned pending_frames; + + pending_frames = (FDCAN_RXFIS(canport, fifo) >> FDCAN_RXFIFO_FL_SHIFT) + & FDCAN_RXFIFO_FL_MASK; + + return (pending_frames != 0); +} + +/**@}*/ + + diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index ddaddb73..63a13e81 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -40,6 +40,7 @@ OBJS += crs_common_all.o OBJS += dac_common_all.o dac_common_v2.o OBJS += dma_common_l1f013.o OBJS += dmamux.o +OBJS += fdcan.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += opamp_common_all.o opamp_common_v2.o From dc6ebac84167679b90b1994403a5ee5e6e405acb Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 25 Mar 2021 21:05:02 +0000 Subject: [PATCH 094/206] stm32h7: fix typo in fdcan2_it1 irq definition reported by Ventyl on irc. --- include/libopencm3/stm32/h7/irq.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/h7/irq.json b/include/libopencm3/stm32/h7/irq.json index 70d8c06b..5e639565 100644 --- a/include/libopencm3/stm32/h7/irq.json +++ b/include/libopencm3/stm32/h7/irq.json @@ -22,7 +22,7 @@ "fdcan1_it0", "fdcan2_it0", "fdcan1_it1", - "fdcan2_it2", + "fdcan2_it1", "exti9_5", "tim1_brk_tim9", "tim1_up_tim10", From 0d72e6739c5f7c90f28350a8bb228722ff094806 Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Mon, 8 Mar 2021 01:19:40 -0500 Subject: [PATCH 095/206] stm32 added better RTC periph API functions Originally tracked at https://github.com/libopencm3/libopencm3/pull/1319 --- .../stm32/common/rtc_common_l1f024.h | 27 +++ include/libopencm3/stm32/f0/rcc.h | 4 +- include/libopencm3/stm32/f4/rcc.h | 3 + lib/stm32/common/rtc_common_l1f024.c | 213 ++++++++++++++++++ 4 files changed, 245 insertions(+), 2 deletions(-) diff --git a/include/libopencm3/stm32/common/rtc_common_l1f024.h b/include/libopencm3/stm32/common/rtc_common_l1f024.h index 127a81a3..2b886f16 100644 --- a/include/libopencm3/stm32/common/rtc_common_l1f024.h +++ b/include/libopencm3/stm32/common/rtc_common_l1f024.h @@ -426,6 +426,15 @@ specific memorymap.h header before including this header file.*/ #define RTC_ALRMXSSR_SS_SHIFT (0) #define RTC_ALARXSSR_SS_MASK (0x7fff) +enum rtc_weekday { + RTC_DR_WDU_MON = 0x01, + RTC_DR_WDU_TUE, + RTC_DR_WDU_WED, + RTC_DR_WDU_THU, + RTC_DR_WDU_FRI, + RTC_DR_WDU_SAT, + RTC_DR_WDU_SUN, +}; BEGIN_DECLS @@ -435,6 +444,24 @@ void rtc_lock(void); void rtc_unlock(void); void rtc_set_wakeup_time(uint16_t wkup_time, uint8_t rtc_cr_wucksel); void rtc_clear_wakeup_flag(void); +void rtc_set_init_flag(void); +void rtc_clear_init_flag(void); +bool rtc_init_flag_is_ready(void); +void rtc_wait_for_init_ready(void); +void rtc_set_bypass_shadow_register(void); +void rtc_enable_bypass_shadow_register(void); +void rtc_disable_bypass_shadow_register(void); +void rtc_set_am_format(void); +void rtc_set_pm_format(void); +void rtc_calendar_set_year(uint8_t year); +void rtc_calendar_set_weekday(enum rtc_weekday rtc_dr_wdu); +void rtc_calendar_set_month(uint8_t month); +void rtc_calendar_set_day(uint8_t day); +void rtc_calendar_set_date(uint8_t year, uint8_t month, uint8_t day, enum rtc_weekday rtc_dr_wdu); +void rtc_time_set_hour(uint8_t hour, bool use_am_notation); +void rtc_time_set_minute(uint8_t minute); +void rtc_time_set_second(uint8_t second); +void rtc_time_set_time(uint8_t hour, uint8_t minute, uint8_t second, bool use_am_notation); END_DECLS /**@}*/ diff --git a/include/libopencm3/stm32/f0/rcc.h b/include/libopencm3/stm32/f0/rcc.h index e0663eb5..ea5b4062 100644 --- a/include/libopencm3/stm32/f0/rcc.h +++ b/include/libopencm3/stm32/f0/rcc.h @@ -538,8 +538,8 @@ enum rcc_periph_rst { RST_DAC1 = _REG_BIT(0x10, 29), /* Compatibility alias */ RST_CEC = _REG_BIT(0x10, 30), - /* Advanced peripherals */ - RST_BACKUPDOMAIN = _REG_BIT(0x20, 16),/* BDCR[16] */ + /* Backup domain control */ + RST_BDCR = _REG_BIT(0x20, 16),/* BDCR[16] */ /* AHB peripherals */ RST_GPIOA = _REG_BIT(0x28, 17), diff --git a/include/libopencm3/stm32/f4/rcc.h b/include/libopencm3/stm32/f4/rcc.h index 31cce195..977cd38a 100644 --- a/include/libopencm3/stm32/f4/rcc.h +++ b/include/libopencm3/stm32/f4/rcc.h @@ -1092,6 +1092,9 @@ enum rcc_periph_rst { RST_SAI1RST = _REG_BIT(0x24, 22),/* F42x, F43x */ RST_LTDC = _REG_BIT(0x24, 26),/* F42x, F43x */ RST_DSI = _REG_BIT(0x24, 27),/* F42x, F43x */ + + /* Backup domain control */ + RST_BDCR = _REG_BIT(0x70, 16),/* BDCR[16] */ }; #undef _REG_BIT diff --git a/lib/stm32/common/rtc_common_l1f024.c b/lib/stm32/common/rtc_common_l1f024.c index d7825a7c..8ea990d8 100644 --- a/lib/stm32/common/rtc_common_l1f024.c +++ b/lib/stm32/common/rtc_common_l1f024.c @@ -28,6 +28,11 @@ #include +static uint8_t _rtc_dec_to_bcd(uint8_t dec) +{ + return ((dec / 10) << 4) | (dec % 10); +} + /*---------------------------------------------------------------------------*/ /** @brief Set RTC prescalars. @@ -122,4 +127,212 @@ void rtc_clear_wakeup_flag(void) RTC_ISR &= ~RTC_ISR_WUTF; } +/*---------------------------------------------------------------------------*/ +/** @brief Sets the initialization flag + +@details Requires unlocking backup domain write protection (PWR_CR_DBP) +*/ +void rtc_set_init_flag(void) +{ + RTC_ISR |= RTC_ISR_INIT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clears (resets) the initialization flag + +@details Requires unlocking backup domain write protection (PWR_CR_DBP) +*/ +void rtc_clear_init_flag(void) +{ + RTC_ISR &= ~RTC_ISR_INIT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Returns if the RTC_ISR init flag RTC_ISR_INITF is set + +@details Requires unlocking backup domain write protection (PWR_CR_DBP) +*/ +bool rtc_init_flag_is_ready(void) +{ + return (RTC_ISR & RTC_ISR_INITF); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Waits infinitely for initialization flag to be set in RTC_ISR + +@details Requires unlocking backup domain write protection (PWR_CR_DBP) +*/ +void rtc_wait_for_init_ready(void) +{ + while (!rtc_init_flag_is_ready()); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the bypass shadow bit in RTC_CR + +@details Requires unlocking backup domain write protection (PWR_CR_DBP) +*/ +void rtc_enable_bypass_shadow_register(void) +{ + RTC_CR |= RTC_CR_BYPSHAD; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clears the bypass shadow bit in RTC_CR + +@details Requires unlocking backup domain write protection (PWR_CR_DBP) +*/ +void rtc_disable_bypass_shadow_register(void) +{ + RTC_CR &= ~RTC_CR_BYPSHAD; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC control register hour format to AM (24h) + +@details Requires unlocking backup domain write protection (PWR_CR_DBP) +*/ +void rtc_set_am_format(void) +{ + RTC_CR &= ~RTC_CR_FMT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC control register hour format to PM (12h) + +@details Requires unlocking backup domain write protection (PWR_CR_DBP) +*/ +void rtc_set_pm_format(void) +{ + RTC_CR |= RTC_CR_FMT; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD calendar year value + +@details Requires unlocking the RTC write-protection (RTC_WPR) + +The year value should only be the abbreviated year tens, meaning if 2021 is +desired pass in only 21. +*/ +void rtc_calendar_set_year(uint8_t year) +{ + uint8_t bcd_year = _rtc_dec_to_bcd(year); + RTC_DR &= ~(RTC_DR_YT_MASK << RTC_DR_YT_SHIFT | RTC_DR_YU_MASK << RTC_DR_YU_SHIFT); + RTC_DR |= (((bcd_year >> 4) & RTC_DR_YT_MASK) << RTC_DR_YT_SHIFT) | + ((bcd_year & RTC_DR_YU_MASK) << RTC_DR_YU_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD calendar weekday + +@details Requires unlocking the RTC write-protection (RTC_WPR) +*/ +void rtc_calendar_set_weekday(enum rtc_weekday rtc_dr_wdu) +{ + RTC_DR &= ~(RTC_DR_WDU_MASK << RTC_DR_WDU_SHIFT); + RTC_DR |= (rtc_dr_wdu << RTC_DR_WDU_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD calendar month value + +@details Requires unlocking the RTC write-protection (RTC_WPR) +*/ +void rtc_calendar_set_month(uint8_t month) +{ + uint8_t bcd_month = _rtc_dec_to_bcd(month); + RTC_DR &= ~(RTC_DR_MT_MASK << RTC_DR_MT_SHIFT | RTC_DR_MU_MASK << RTC_DR_MU_SHIFT); + RTC_DR |= (((bcd_month >> 4) & RTC_DR_MT_MASK) << RTC_DR_MT_SHIFT) | + ((bcd_month & RTC_DR_MU_MASK) << RTC_DR_MU_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD calendar day value + +@details Requires unlocking the RTC write-protection (RTC_WPR) +*/ +void rtc_calendar_set_day(uint8_t day) +{ + uint8_t bcd_day = _rtc_dec_to_bcd(day); + RTC_DR &= ~(RTC_DR_DT_MASK << RTC_DR_DT_SHIFT | RTC_DR_DU_MASK << RTC_DR_DU_SHIFT); + RTC_DR |= (((bcd_day >> 4) & RTC_DR_DT_MASK) << RTC_DR_DT_SHIFT) | + ((bcd_day & RTC_DR_DU_MASK) << RTC_DR_DU_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD calendar value + +@details Requires unlocking the RTC write-protection (RTC_WPR) + +The year value should only be the abbreviated year tens, meaning if 2021 is +desired pass in only 21. +*/ +void rtc_calendar_set_date(uint8_t year, uint8_t month, uint8_t day, enum rtc_weekday rtc_dr_wdu) +{ + rtc_calendar_set_year(year); + rtc_calendar_set_month(month); + rtc_calendar_set_weekday(rtc_dr_wdu); + rtc_calendar_set_day(day); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD time hour value + +@details Requires unlocking the RTC write-protection (RTC_WPR) + +Pass true to use_am_notation to use 24-hour input time; pass false to +use_am_notation to use 12-hour (AM/PM) input time +*/ +void rtc_time_set_hour(uint8_t hour, bool use_am_notation) +{ + if (use_am_notation) { + RTC_TR &= ~(RTC_TR_PM); + } else { + RTC_TR |= RTC_TR_PM; + } + + uint8_t bcd_hour = _rtc_dec_to_bcd(hour); + RTC_TR &= ~(RTC_TR_HT_MASK << RTC_TR_HT_SHIFT | RTC_TR_HU_MASK << RTC_TR_HU_SHIFT); + RTC_TR |= (((bcd_hour >> 4) & RTC_TR_HT_MASK) << RTC_TR_HT_SHIFT) | + ((bcd_hour & RTC_TR_HU_MASK) << RTC_TR_HU_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD time minute value + +@details Requires unlocking the RTC write-protection (RTC_WPR) +*/ +void rtc_time_set_minute(uint8_t minute) +{ + uint8_t bcd_minute = _rtc_dec_to_bcd(minute); + RTC_TR &= ~(RTC_TR_MNT_MASK << RTC_TR_MNT_SHIFT | RTC_TR_MNU_MASK << RTC_TR_MNU_SHIFT); + RTC_TR |= (((bcd_minute >> 4) & RTC_TR_MNT_MASK) << RTC_TR_MNT_SHIFT) | + ((bcd_minute & RTC_TR_MNU_MASK) << RTC_TR_MNU_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD time second value + +@details Requires unlocking the RTC write-protection (RTC_WPR) +*/ +void rtc_time_set_second(uint8_t second) +{ + uint8_t bcd_second = _rtc_dec_to_bcd(second); + RTC_TR &= ~(RTC_TR_ST_MASK << RTC_TR_ST_SHIFT | RTC_TR_SU_MASK << RTC_TR_SU_SHIFT); + RTC_TR |= (((bcd_second >> 4) & RTC_TR_ST_MASK) << RTC_TR_ST_SHIFT) | + ((bcd_second & RTC_TR_SU_MASK) << RTC_TR_SU_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the RTC BCD time + +@details Requires unlocking the RTC write-protection (RTC_WPR) +*/ +void rtc_time_set_time(uint8_t hour, uint8_t minute, uint8_t second, bool use_am_notation) +{ + rtc_time_set_hour(hour, use_am_notation); + rtc_time_set_minute(minute); + rtc_time_set_second(second); +} /**@}*/ From 32354846bd98a570a6b043b6941b824b3c3c5f14 Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Fri, 9 Apr 2021 17:43:21 +0200 Subject: [PATCH 096/206] STM32H7: Implement basic FDCAN support Add stm32h7 support for FDCAN peripheral. Source level compatibility is provided with stm32g4. Additional features of stm32h7 such as configurable buffers are supported. Implementation offers feature parity with stm32g4 implementation. --- include/libopencm3/stm32/fdcan.h | 148 ++---- include/libopencm3/stm32/g4/fdcan.h | 132 ++++++ include/libopencm3/stm32/h7/fdcan.h | 257 ++++++++++ lib/stm32/common/{fdcan.c => fdcan_common.c} | 278 ++++------- lib/stm32/g4/Makefile | 2 +- lib/stm32/g4/fdcan.c | 187 ++++++++ lib/stm32/h7/Makefile | 1 + lib/stm32/h7/fdcan.c | 473 +++++++++++++++++++ 8 files changed, 1182 insertions(+), 296 deletions(-) create mode 100644 include/libopencm3/stm32/g4/fdcan.h create mode 100644 include/libopencm3/stm32/h7/fdcan.h rename lib/stm32/common/{fdcan.c => fdcan_common.c} (73%) create mode 100644 lib/stm32/g4/fdcan.c create mode 100644 lib/stm32/h7/fdcan.c diff --git a/include/libopencm3/stm32/fdcan.h b/include/libopencm3/stm32/fdcan.h index 61ac87d0..f59e9d1b 100644 --- a/include/libopencm3/stm32/fdcan.h +++ b/include/libopencm3/stm32/fdcan.h @@ -1,17 +1,7 @@ -/** @defgroup fdcan_defines FDCAN Defines - -@ingroup STM32G_defines - -@brief libopencm3 Defined Constants and Types for STM32 FD-CAN - -@author @htmlonly © @endhtmlonly 2021 Eduard Drusa - -LGPL License Terms @ref lgpl_license -*/ /* * This file is part of the libopencm3 project. * - * Copyright (C) 2021 Eduard Drusa + * Copyright (C) 2021 Eduard Drusa * * 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 @@ -27,26 +17,20 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ - - -#ifndef LIBOPENCM3_FDCAN_H -#define LIBOPENCM3_FDCAN_H +#pragma once #include #include -/** @{ */ +#if defined(STM32G4) +# include +#elif defined(STM32H7) +# include +#endif -/* FDCAN block base addresses. Used in functions to identify FDCAN block being manipulated. */ - -/** @defgroup fdcan_block FDCAN block base addresses +/** @addtogroup fdcan_defines * @{ */ -#define CAN1 FDCAN1_BASE -#define CAN2 FDCAN2_BASE -#define CAN3 FDCAN3_BASE -/**@}*/ - /** @defgroup fdcan_fifo Named constants for FIFOs * @{ @@ -55,6 +39,7 @@ LGPL License Terms @ref lgpl_license #define FDCAN_FIFO1 1 /**@}*/ +#define FDCAN_BLOCK_ID(can_base) (((can_base) - CAN1)/(CAN2 - CAN1)) /** @defgroup FDCAN registers file in each FDCAN block. */ @@ -76,38 +61,29 @@ LGPL License Terms @ref lgpl_license #define FDCAN_IE(can_base) MMIO32(can_base + 0x0054) #define FDCAN_ILS(can_base) MMIO32(can_base + 0x0058) #define FDCAN_ILE(can_base) MMIO32(can_base + 0x005C) -#define FDCAN_RXGFC(can_base) MMIO32(can_base + 0x0080) -#define FDCAN_XIDAM(can_base) MMIO32(can_base + 0x0084) -#define FDCAN_HPMS(can_base) MMIO32(can_base + 0x0088) + /** Generic access to Rx FIFO status registers. * @param can_base FDCAN block base address @ref fdcan_block * @param fifo_id ID of FIFO, 0 or 1 */ -#define FDCAN_RXFIS(can_base, fifo_id) MMIO32(can_base + 0x0090 + (8 * fifo_id)) +#define FDCAN_RXFIS(can_base, fifo_id) \ + MMIO32(can_base + FDCAN_RXFIS_BASE + (FDCAN_RXFI_OFFSET * fifo_id)) + #define FDCAN_RXF0S(can_base) FDCAN_RXFIS(can_base, 0) #define FDCAN_RXF1S(can_base) FDCAN_RXFIS(can_base, 1) + /** Generic access to Rx FIFO acknowledge registers. * @param can_base FDCAN block base address @ref fdcan_block * @param fifo_id ID of FIFO, 0 or 1 */ -#define FDCAN_RXFIA(can_base, fifo_id) MMIO32(can_base + 0x0094 + (8 * fifo_id)) +#define FDCAN_RXFIA(can_base, fifo_id) MMIO32(can_base + 0x0094 + (FDCAN_RXFI_OFFSET * fifo_id)) #define FDCAN_RXF0A(can_base) FDCAN_RXFIA(can_base, 0) #define FDCAN_RXF1A(can_base) FDCAN_RXFIA(can_base, 1) #define FDCAN_TXBC(can_base) MMIO32(can_base + 0x00C0) #define FDCAN_TXFQS(can_base) MMIO32(can_base + 0x00C4) -#define FDCAN_TXBRP(can_base) MMIO32(can_base + 0x00C8) -#define FDCAN_TXBAR(can_base) MMIO32(can_base + 0x00CC) -#define FDCAN_TXBCR(can_base) MMIO32(can_base + 0x00D0) -#define FDCAN_TXBTO(can_base) MMIO32(can_base + 0x00D4) -#define FDCAN_TXBCF(can_base) MMIO32(can_base + 0x00D8) -#define FDCAN_TXBTIE(can_base) MMIO32(can_base + 0x00DC) -#define FDCAN_TXBCIE(can_base) MMIO32(can_base + 0x00E0) -#define FDCAN_TXEFS(can_base) MMIO32(can_base + 0x00E4) -#define FDCAN_TXEFA(can_base) MMIO32(can_base + 0x00E8) -#define FDCAN_CKDIV(can_base) MMIO32(can_base + 0x0100) /* DAY[7:0]: FDCAN core revision date */ #define FDCAN_CREL_DAY_SHIFT 0 @@ -360,26 +336,6 @@ LGPL License Terms @ref lgpl_license #define FDCAN_ILE_INT0 (1 << 0) #define FDCAN_ILE_INT1 (1 << 1) -#define FDCAN_RXGFC_RRFE (1 << 0) -#define FDCAN_RXGFC_RRFS (1 << 1) -/* ANFE[1:0]: Accept non-matching frames w/ extended ID */ -#define FDCAN_RXGFC_ANFE_SHIFT 2 -#define FDCAN_RXGFC_ANFE_MASK 0x3 - -/* ANFS[1:0]: Accept non-matching frames w/ standard ID */ -#define FDCAN_RXGFC_ANFS_SHIFT 4 -#define FDCAN_RXGFC_ANFS_MASK 0x3 - -#define FDCAN_RXGFC_F1OM (1 << 8) -#define FDCAN_RXGFC_F0OM (1 << 9) -/* LSS[4:0]: List size of standard ID filters */ -#define FDCAN_RXGFC_LSS_SHIFT 16 -#define FDCAN_RXGFC_LSS_MASK 0x1F - -/* LSE[3:0]: List size of extended ID filters */ -#define FDCAN_RXGFC_LSE_SHIFT 24 -#define FDCAN_RXGFC_LSE_MASK 0xF - /* EIDM[28:0]: Extended ID mask for filtering */ #define FDCAN_XIDAM_EIDM_SHIFT 0 @@ -402,15 +358,12 @@ LGPL License Terms @ref lgpl_license /* Fill level of Rx FIFOs */ #define FDCAN_RXFIFO_FL_SHIFT 0 -#define FDCAN_RXFIFO_FL_MASK 0xF /* Get index of Rx FIFOs */ #define FDCAN_RXFIFO_GI_SHIFT 8 -#define FDCAN_RXFIFO_GI_MASK 0x3 /* Put index of Rx FIFOs */ #define FDCAN_RXFIFO_PI_SHIFT 16 -#define FDCAN_RXFIFO_PI_MASK 0x3 #define FDCAN_RXFIFO_FF (1 << 24) #define FDCAN_RXFIFO_RFL (1 << 25) @@ -432,7 +385,6 @@ LGPL License Terms @ref lgpl_license /* Rx FIFOs acknowledge index */ #define FDCAN_RXFIFO_AI_SHIFT 0 -#define FDCAN_RXFIFO_AI_MASK 0x7 /* R0AI[2:0]: Rx FIFO 0 acknowledge index */ #define FDCAN_RXF0A_R0AI_SHIFT FDCAN_RXFIFO_AI_SHIFT @@ -461,17 +413,14 @@ LGPL License Terms @ref lgpl_license /* TFFL[2:0]: Tx FIFO free level */ #define FDCAN_TXFQS_TFFL_SHIFT 0 -#define FDCAN_TXFQS_TFFL_MASK 0x7 /* TFGI[1:0]: Tx FIFO get index */ -#define FDCAN_TXFQS_TFGI_SHIFT 0 -#define FDCAN_TXFQS_TFGI_MASK 0x3 +#define FDCAN_TXFQS_TFGI_SHIFT 8 /* TFQPI[1:0]: Tx FIFO put index */ -#define FDCAN_TXFQS_TFQPI_SHIFT 0 -#define FDCAN_TXFQS_TFQPI_MASK 0x3 +#define FDCAN_TXFQS_TFQPI_SHIFT 16 -#define FDCAN_TXFQS_TFQF (1 << 0) +#define FDCAN_TXFQS_TFQF (1 << 21) /** @defgroup fdcan_txbrp FDCAN_TXBRP Transmit request pending bits * @{ @@ -527,7 +476,7 @@ LGPL License Terms @ref lgpl_license /** @defgroup fdcan_txbcie FDCAN_TXBCIE Transmit cancelled interrupt enable bits * * Each bit enables or disables transmit cancelled interrupt for transmit buffer - * slot. + * slot. * @{ */ #define FDCAN_TXBCIE_CFIE0 (1 << 0) @@ -537,15 +486,12 @@ LGPL License Terms @ref lgpl_license /* EFFL[2:0]: Event FIFO fill level*/ #define FDCAN_TXEFS_EFFL_SHIFT 0 -#define FDCAN_TXEFS_EFFL_MASK 0x7 /* EFG[1:0]: Event FIFO get index */ #define FDCAN_TXEFS_EFGI_SHIFT 8 -#define FDCAN_TXEFS_EFGI_MASK 0x3 /* EFPI[1:0]: Event FIFO put index */ #define FDCAN_TXEFS_EFPI_SHIFT 16 -#define FDCAN_TXEFS_EFPI_MASK 0x3 #define FDCAN_TXEFS_EFF (1 << 24) #define FDCAN_TXEFS_TEF (1 << 25) @@ -555,10 +501,6 @@ LGPL License Terms @ref lgpl_license #define FDCAN_TXEFA_EFAI_MASK 0x3 -/* PDIV[3:0]: Input clock divider */ -#define FDCAN_CKDIV_PDIV_SHIFT 0 -#define FDCAN_CKDIV_PDIV_MASK 0xF - /* --- FD-CAN memory block defines------------------------------------------ */ /** Structure describing standard ID filter. @@ -626,12 +568,6 @@ struct fdcan_standard_filter { #define FDCAN_SFEC_PRIO_FIFO1 0x6 /**@}*/ -/** Amount of standard filters allocated in Message RAM - * This number may vary between devices. 28 is value valid - * for STM32G4 - **/ -#define FDCAN_SFT_MAX_NR 28 - /* SFEC = 0x7 is unused */ #define FDCAN_SFID1_SHIFT 16 @@ -706,7 +642,7 @@ struct fdcan_extended_filter { * using id2. */ #define FDCAN_EFT_ID_MASK 0x2 -/** Similar to @ref FDCAN_EFT_RANGE except of ignoring global mask +/** Similar to @ref FDCAN_EFT_RANGE except of ignoring global mask * set using @ref FDCAN_XIDAM register. */ #define FDCAN_EFT_RANGE_NOXIDAM 0x3 @@ -715,12 +651,6 @@ struct fdcan_extended_filter { #define FDCAN_EFID2_SHIFT 0 #define FDCAN_EFID2_MASK 0x1FFFFFFF -/** Amount of extended filters allocated in Message RAM - * This number may vary between devices. 8 is value valid - * for STM32G4 - **/ -#define FDCAN_EFT_MAX_NR 8 - /** Structure describing receive FIFO element. * Receive FIFO element consists of 2 32bit values for header * and 16 32bit values for message payload. @@ -792,29 +722,6 @@ struct fdcan_tx_buffer_element { #define FDCAN_FIFO_RXTS_SHIFT 0 #define FDCAN_FIFO_RXTS_MASK 0xFFFF -/** Message RAM layout for one FDCAN block. - * There are as many memory blocks as there are FDCAN blocks - */ -struct fdcan_message_ram { - /* List of standard ID filters */ - struct fdcan_standard_filter lfssa[FDCAN_SFT_MAX_NR]; - - /* List of extended ID filters */ - struct fdcan_extended_filter lfesa[FDCAN_EFT_MAX_NR]; - - /* Buffer area for two receive FIFOs each having space for three messages */ - struct fdcan_rx_fifo_element rx_fifo[2][3]; - - /* Buffer area for transmit event buffers */ - struct fdcan_tx_event_element tx_event[3]; - - /* Buffer area for transmitted messages. May act either as FIFO or as queue - * depending on configuration - */ - struct fdcan_tx_buffer_element tx_buffer[3]; -}; - - /* --- FD-CAN error returns ------------------------------------------------- */ /** FDCAN error return values @@ -886,7 +793,18 @@ void fdcan_release_fifo(uint32_t canport, uint8_t fifo); bool fdcan_available_tx(uint32_t canport); bool fdcan_available_rx(uint32_t canport, uint8_t fifo); +int fdcan_cccr_init_cfg(uint32_t canport, bool set, uint32_t timeout); +struct fdcan_standard_filter *fdcan_get_flssa_addr(uint32_t canport); +struct fdcan_extended_filter *fdcan_get_flesa_addr(uint32_t canport); + +struct fdcan_rx_fifo_element *fdcan_get_rxfifo_addr(uint32_t canport, + unsigned fifo_id, unsigned element_id); + +struct fdcan_tx_event_element *fdcan_get_txevt_addr(uint32_t canport); +struct fdcan_tx_buffer_element *fdcan_get_txbuf_addr(uint32_t canport, unsigned element_id); +void fdcan_set_fifo_locked_mode(uint32_t canport, bool locked); +uint32_t fdcan_length_to_dlc(uint8_t length); +uint8_t fdcan_dlc_to_length(uint32_t dlc); + END_DECLS - -#endif diff --git a/include/libopencm3/stm32/g4/fdcan.h b/include/libopencm3/stm32/g4/fdcan.h new file mode 100644 index 00000000..4b94625b --- /dev/null +++ b/include/libopencm3/stm32/g4/fdcan.h @@ -0,0 +1,132 @@ +/** @defgroup fdcan_defines FDCAN Defines + +@ingroup STM32G4xx_defines + +@author @htmlonly © @endhtmlonly 2021 Eduard Drusa + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +/** @{ */ + +/* FDCAN block base addresses. Used in functions to identify FDCAN block being manipulated. */ + +/** @defgroup fdcan_block FDCAN block base addresses + * @{ + */ +#define CAN1 FDCAN1_BASE +#define CAN2 FDCAN2_BASE +#define CAN3 FDCAN3_BASE +/**@}*/ + +#define CAN_MSG_BASE FDCAN1_RAM_BASE + +#define FDCAN_RXFIS_BASE 0x0090 +#define FDCAN_RXFIA_BASE 0x0094 +#define FDCAN_RXFI_OFFSET 0x0008 + +#define FDCAN_RXGFC(can_base) MMIO32(can_base + 0x0080) +#define FDCAN_XIDAM(can_base) MMIO32(can_base + 0x0084) +#define FDCAN_HPMS(can_base) MMIO32(can_base + 0x0088) + +#define FDCAN_TXBRP(can_base) MMIO32(can_base + 0x00C8) +#define FDCAN_TXBAR(can_base) MMIO32(can_base + 0x00CC) +#define FDCAN_TXBCR(can_base) MMIO32(can_base + 0x00D0) +#define FDCAN_TXBTO(can_base) MMIO32(can_base + 0x00D4) +#define FDCAN_TXBCF(can_base) MMIO32(can_base + 0x00D8) +#define FDCAN_TXBTIE(can_base) MMIO32(can_base + 0x00DC) +#define FDCAN_TXBCIE(can_base) MMIO32(can_base + 0x00E0) +#define FDCAN_TXEFS(can_base) MMIO32(can_base + 0x00E4) +#define FDCAN_TXEFA(can_base) MMIO32(can_base + 0x00E8) + +#define FDCAN_CKDIV(can_base) MMIO32(can_base + 0x0100) + +#define FDCAN_RXGFC_RRFE (1 << 0) +#define FDCAN_RXGFC_RRFS (1 << 1) +/* ANFE[1:0]: Accept non-matching frames w/ extended ID */ +#define FDCAN_RXGFC_ANFE_SHIFT 2 +#define FDCAN_RXGFC_ANFE_MASK 0x3 + +/* ANFS[1:0]: Accept non-matching frames w/ standard ID */ +#define FDCAN_RXGFC_ANFS_SHIFT 4 +#define FDCAN_RXGFC_ANFS_MASK 0x3 + +#define FDCAN_RXGFC_F1OM (1 << 8) +#define FDCAN_RXGFC_F0OM (1 << 9) +/* LSS[4:0]: List size of standard ID filters */ +#define FDCAN_RXGFC_LSS_SHIFT 16 +#define FDCAN_RXGFC_LSS_MASK 0x1F + +/* LSE[3:0]: List size of extended ID filters */ +#define FDCAN_RXGFC_LSE_SHIFT 24 +#define FDCAN_RXGFC_LSE_MASK 0xF + +#define FDCAN_RXFIFO_FL_MASK 0xF +#define FDCAN_RXFIFO_GI_MASK 0x3 +#define FDCAN_RXFIFO_PI_MASK 0x3 +#define FDCAN_RXFIFO_AI_MASK 0x3 + +#define FDCAN_TXFQS_TFFL_MASK 0x7 +#define FDCAN_TXFQS_TFGI_MASK 0x3 +#define FDCAN_TXFQS_TFQPI_MASK 0x3 + +#define FDCAN_TXEFS_EFFL_MASK 0x7 +#define FDCAN_TXEFS_EFGI_MASK 0x3 +#define FDCAN_TXEFS_EFPI_MASK 0x3 + +/* PDIV[3:0]: Input clock divider */ +#define FDCAN_CKDIV_PDIV_SHIFT 0 +#define FDCAN_CKDIV_PDIV_MASK 0xF + +/** Amount of standard filters allocated in Message RAM + * This number may vary between devices. 28 is value valid + * for STM32G4 + **/ +#define FDCAN_SFT_MAX_NR 28 + +/** Amount of extended filters allocated in Message RAM + * This number may vary between devices. 8 is value valid + * for STM32G4 + **/ +#define FDCAN_EFT_MAX_NR 8 + +#define FDCAN_LFSSA_OFFSET(can_base) ((FDCAN_BLOCK_ID(can_base) * 0x0350) + 0x0000) +#define FDCAN_LFESA_OFFSET(can_base) ((FDCAN_BLOCK_ID(can_base) * 0x0350) + 0x0070) + +#define FDCAN_RXFIFOS_OFFSET(can_base) ((FDCAN_BLOCK_ID(can_base) * 0x0350) + 0x00B0) + +#define FDCAN_RXFIFO_OFFSET(can_base, fifo_id) \ + (FDCAN_RXFIFOS_OFFSET(can_base) + (0x00D8 * (fifo_id))) + +#define FDCAN_TXEVT_OFFSET(can_base) ((FDCAN_BLOCK_ID(can_base) * 0x0350) + 0x0260) + +#define FDCAN_TXBUF_OFFSET(can_base) ((FDCAN_BLOCK_ID(can_base) * 0x0350) + 0x0278) + +BEGIN_DECLS + +unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id); +unsigned fdcan_get_txbuf_element_size(uint32_t canport); + +END_DECLS + + diff --git a/include/libopencm3/stm32/h7/fdcan.h b/include/libopencm3/stm32/h7/fdcan.h new file mode 100644 index 00000000..0a5cbe7a --- /dev/null +++ b/include/libopencm3/stm32/h7/fdcan.h @@ -0,0 +1,257 @@ +/** @defgroup fdcan_defines FDCAN Defines + +@ingroup STM32H7xx_defines + + +@author @htmlonly © @endhtmlonly 2021 Eduard Drusa + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +/** @{ */ + +/* FDCAN block base addresses. Used in functions to identify FDCAN block being manipulated. */ + +/** @defgroup fdcan_block FDCAN block base addresses + * @{ + */ +#define CAN1 FDCAN1_BASE +#define CAN2 FDCAN2_BASE +/**@}*/ + +/* Size of FDCAN peripheral message RAM in bytes */ +#define CAN_MSG_SIZE 0x2800 + +#define FDCAN_GFC(can_base) MMIO32(can_base + 0x0080) + +#define FDCAN_SIDFC(can_base) MMIO32(can_base + 0x0084) +#define FDCAN_XIDFC(can_base) MMIO32(can_base + 0x0088) +#define FDCAN_XIDAM(can_base) MMIO32(can_base + 0x0090) + +#define FDCAN_HPMS(can_base) MMIO32(can_base + 0x0094) +#define FDCAN_NDAT1(can_base) MMIO32(can_base + 0x0098) +#define FDCAN_HDAT2(can_base) MMIO32(can_base + 0x009C) + +#define FDCAN_RXFIC_BASE 0x00A0 +#define FDCAN_RXFI_OFFSET 0x0010 + +#define FDCAN_RXFIC(can_base, fifo_id) \ + MMIO32((can_base) + FDCAN_RXFIC_BASE + (FDCAN_RXFI_OFFSET * (fifo_id))) + +#define FDCAN_RXF0C(can_base) FDCAN_RXFIC(can_base, 0) +#define FDCAN_RXF1C(can_base) FDCAN_RXFIC(can_base, 1) + +#define FDCAN_RXFIS_BASE 0x00A4 +#define FDCAN_RXFIA_BASE 0x00A8 + +#define FDCAN_RXBC(can_base) MMIO32(can_base + 0x00AC) + +#define FDCAN_RXESC(can_base) MMIO32(can_base + 0x00BC) +#define FDCAN_TXESC(can_base) MMIO32(can_base + 0x00C8) +#define FDCAN_TXBRP(can_base) MMIO32(can_base + 0x00CC) +#define FDCAN_TXBAR(can_base) MMIO32(can_base + 0x00D0) +#define FDCAN_TXBCR(can_base) MMIO32(can_base + 0x00D4) +#define FDCAN_TXBTO(can_base) MMIO32(can_base + 0x00D8) +#define FDCAN_TXBCF(can_base) MMIO32(can_base + 0x00DC) +#define FDCAN_TXBTIE(can_base) MMIO32(can_base + 0x00E0) +#define FDCAN_TXBCIE(can_base) MMIO32(can_base + 0x00E4) +#define FDCAN_TXEFC(can_base) MMIO32(can_base + 0x00F0) +#define FDCAN_TXEFS(can_base) MMIO32(can_base + 0x00F4) +#define FDCAN_TXEFA(can_base) MMIO32(can_base + 0x00F8) + +#define FDCAN_TTTMC(can_base) MMIO32(can_base + 0x0100) +#define FDCAN_TTRMC(can_base) MMIO32(can_base + 0x0104) +#define FDCAN_TTOCF(can_base) MMIO32(can_base + 0x0108) +#define FDCAN_TTMLM(can_base) MMIO32(can_base + 0x010C) +#define FDCAN_TURCF(can_base) MMIO32(can_base + 0x0110) +#define FDCAN_TTOCN(can_base) MMIO32(can_base + 0x0114) +#define FDCAN_TTGTP(can_base) MMIO32(can_base + 0x0118) +#define FDCAN_TTTMK(can_base) MMIO32(can_base + 0x011C) +#define FDCAN_TTTIR(can_base) MMIO32(can_base + 0x0120) +#define FDCAN_TTIE(can_base) MMIO32(can_base + 0x0124) +#define FDCAN_TTILS(can_base) MMIO32(can_base + 0x0128) +#define FDCAN_TTOST(can_base) MMIO32(can_base + 0x012C) +#define FDCAN_TURNA(can_base) MMIO32(can_base + 0x0130) +#define FDCAN_TTLGT(can_base) MMIO32(can_base + 0x0134) +#define FDCAN_TTCTC(can_base) MMIO32(can_base + 0x0138) +#define FDCAN_TTCPT(can_base) MMIO32(can_base + 0x013C) +#define FDCAN_TTCSM(can_base) MMIO32(can_base + 0x0140) +#define FDCAN_TTTS(can_base) MMIO32(can_base + 0x0300) + +#define FDCAN_CCU_CCFG MMIO32(CAN_CCU_BASE + 0x0004) +#define FDCAN_CCU_CREL MMIO32(CAN_CCU_BASE + 0x0000) + +#define FDCAN_GFC_RRFE (1 << 0) +#define FDCAN_GFC_RRFS (1 << 1) + +/* ANFE[1:0]: Accept non-matching frames w/ extended ID */ +#define FDCAN_GFC_ANFE_SHIFT 2 +#define FDCAN_GFC_ANFE_MASK 0x3 + +/* ANFS[1:0]: Accept non-matching frames w/ standard ID */ +#define FDCAN_GFC_ANFS_SHIFT 4 +#define FDCAN_GFC_ANFS_MASK 0x3 + +#define FDCAN_FXS_MASK 0xFF +#define FDCAN_FXS_SHIFT 16 + +/* Position of start address of relocatable object within register */ +#define FDCAN_FXSA_MASK 0x3FFF +#define FDCAN_FXSA_SHIFT 2 + +/* LSS[7:0]: List size of standard ID filters */ +#define FDCAN_SIDFC_LSS_MASK FDCAN_FXS_MASK +#define FDCAN_SIDFC_LSS_SHIFT FDCAN_FXS_SHIFT + +/* LFSSA[13:0]: Filter List standard start address */ +#define FDCAN_SIDFC_FLSSA_MASK FDCAN_FXSA_MASK +#define FDCAN_SIDFC_FLSSA_SHIFT FDCAN_FXSA_SHIFT + +/* LSE[7:0]: List size of extended ID filters */ +#define FDCAN_XIDFC_LSE_MASK FDCAN_FXS_MASK +#define FDCAN_XIDFC_LSE_SHIFT FDCAN_FXS_SHIFT + +/* LFSSA[7:0]: Filter List extended start address */ +#define FDCAN_XIDFC_FLESA_MASK FDCAN_FXSA_MASK +#define FDCAN_XIDFC_FLESA_SHIFT FDCAN_FXSA_SHIFT + +/* TFQS[5:0]: Tx FIFO/Queue size */ +#define FDCAN_TXBC_TFQS_MASK 0x3F +#define FDCAN_TXBC_TFQS_SHIFT 24 + +/* TBSA[7:0]: Transmit buffer start address */ +#define FDCAN_TXBC_TBSA_MASK FDCAN_FXSA_MASK +#define FDCAN_TXBC_TBSA_SHIFT FDCAN_FXSA_SHIFT + +#define FDCAN_TXEFC_EFS_MASK 0x3F +#define FDCAN_TXEFC_EFS_SHIFT 16 + +/* EFSA[7:0]: (Transmit) event FIFO start address */ +#define FDCAN_TXEFC_EFSA_MASK FDCAN_FXSA_MASK +#define FDCAN_TXEFC_EFSA_SHIFT FDCAN_FXSA_SHIFT + +#define FDCAN_RXFIC_FIOM (1 << 31) + +#define FDCAN_RXFIC_FIWM_MASK 0x7F +#define FDCAN_RXFIC_FIWM_SHIFT 24 + +#define FDCAN_RXFIC_FIS_MASK 0x7F +#define FDCAN_RXFIC_FIS_SHIFT 16 + + +#define FDCAN_RXFIC_FISA_MASK FDCAN_FXSA_MASK +#define FDCAN_RXFIC_FISA_SHIFT FDCAN_FXSA_SHIFT + +#define FDCAN_RXF0C_F0OM FDCAN_RXFIC_FIOM + +/* F0WM[6:0]: FIFO0 watermark mode */ +#define FDCAN_RXF0C_F0WM_MASK FDCAN_RXFIC_FIWM_MASK +#define FDCAN_RXF0C_F0WM_SHIFT FDCAN_RXFIC_FIWM_SHIFT + +/* F0S[6:0]: FIFO0 size */ +#define FDCAN_RXF0C_F0S_MASK FDCAN_RXFIC_FIS_MASK +#define FDCAN_RXF0C_F0S_SHIFT FDCAN_RXFIC_FIS_SHIFT + +/* F0SA[13:0]: FIFO0 start address */ +#define FDCAN_RXF0C_F0SA_MASK FDCAN_RXFIC_FISA_MASK +#define FDCAN_RXF0C_F0SA_SHIFT FDCAN_RXFIC_FISA_SHIFT + +#define FDCAN_RXF1C_F1OM FDCAN_RXFIC_FIOM + +/* F1WM[6:0]: FIFO1 watermark mode */ +#define FDCAN_RXF1C_F1WM_MASK FDCAN_RXFIC_FIWM_MASK +#define FDCAN_RXF1C_F1WM_SHIFT FDCAN_RXFIC_FIWM_SHIFT + +/* F1S[6:0]: FIFO1 size */ +#define FDCAN_RXF1C_F1S_MASK FDCAN_RXFIC_FIS_MASK +#define FDCAN_RXF1C_F1S_SHIFT FDCAN_RXFIC_FIS_SHIFT + +/* F1SA[13:0]: FIFO1 start address */ +#define FDCAN_RXF1C_F1SA_MASK FDCAN_RXFIC_FISA_MASK +#define FDCAN_RXF1C_F1SA_SHIFT FDCAN_RXFIC_FISA_SHIFT + +/* RBDS[3:0]: RX buffer data field size */ +#define FDCAN_RXESC_RBDS_MASK 0x7 +#define FDCAN_RXESC_RBDS_SHIFT 8 + +/* F0DS[3:0]: FIFO0 data field size */ +#define FDCAN_RXESC_F0DS_MASK 0x7 +#define FDCAN_RXESC_F0DS_SHIFT 0 + +/* F1DS[3:0]: FIFO1 data field size */ +#define FDCAN_RXESC_F1DS_MASK 0x7 +#define FDCAN_RXESC_F1DS_SHIFT 4 + +/* TBDS[3:0]: TX buffer data field size */ +#define FDCAN_TXESC_TBDS_MASK 0x7 +#define FDCAN_TXESC_TBDS_SHIFT 0 + +#define FDCAN_RXFIFO_FL_MASK 0x7F +#define FDCAN_RXFIFO_GI_MASK 0x3F +#define FDCAN_RXFIFO_PI_MASK 0x3F + +#define FDCAN_RXFIFO_AI_MASK 0x3F + +#define FDCAN_TXFQS_TFFL_MASK 0x3F +#define FDCAN_TXFQS_TFGI_MASK 0x1F +#define FDCAN_TXFQS_TFQPI_MASK 0x1F + +#define FDCAN_TXEFS_EFFL_MASK 0x3F +#define FDCAN_TXEFS_EFGI_MASK 0x1F +#define FDCAN_TXEFS_EFPI_MASK 0x1F + +/* PDIV[3:0]: Input clock divider */ +#define FDCAN_CCU_CCFG_CDIV_SHIFT 16 +#define FDCAN_CCU_CCFG_CDIV_MASK 0xF + + + +#define FDCAN_LFSSA_OFFSET(can_base) \ + (FDCAN_SIDFC(can_base) & (FDCAN_SIDFC_FLSSA_MASK << FDCAN_SIDFC_FLSSA_SHIFT)) + +#define FDCAN_LFESA_OFFSET(can_base) \ + (FDCAN_XIDFC(can_base) & (FDCAN_XIDFC_FLESA_MASK << FDCAN_XIDFC_FLESA_SHIFT)) + +#define FDCAN_RXFIFO_OFFSET(can_base, fifo_id) \ + (FDCAN_RXFIC(can_base, fifo_id) & (FDCAN_FXSA_MASK << FDCAN_FXSA_SHIFT)) + +#define FDCAN_TXBUF_OFFSET(can_base) \ + (FDCAN_TXBC(can_base) & (FDCAN_TXBC_TBSA_MASK << FDCAN_TXBC_TBSA_SHIFT)) + +#define FDCAN_TXEVT_OFFSET(can_base) \ + (FDCAN_TXEFC(can_base) & (FDCAN_TXEFC_EFSA_MASK << FDCAN_TXEFC_EFSA_SHIFT)) + +BEGIN_DECLS + +void fdcan_init_std_filter_ram(uint32_t canport, uint32_t flssa, uint8_t lss); +void fdcan_init_ext_filter_ram(uint32_t canport, uint32_t flesa, uint8_t lse); +void fdcan_init_fifo_ram(uint32_t canport, unsigned fifo_id, uint32_t fxsa, uint8_t fxs); +void fdcan_init_tx_event_ram(uint32_t canport, uint32_t tesa, uint8_t tes); +void fdcan_init_tx_buffer_ram(uint32_t canport, uint32_t tbsa, uint8_t tbs); +unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id); +unsigned fdcan_get_txbuf_element_size(uint32_t canport); +int fdcan_set_rx_element_size(uint32_t canport, uint8_t rxbuf, uint8_t rxfifo0, uint8_t rxfifo1); +int fdcan_set_tx_element_size(uint32_t canport, uint8_t txbuf); + +END_DECLS + diff --git a/lib/stm32/common/fdcan.c b/lib/stm32/common/fdcan_common.c similarity index 73% rename from lib/stm32/common/fdcan.c rename to lib/stm32/common/fdcan_common.c index 30e6956a..ef7eeab9 100644 --- a/lib/stm32/common/fdcan.c +++ b/lib/stm32/common/fdcan_common.c @@ -1,22 +1,3 @@ -/** @defgroup fdcan_file FDCAN peripheral API - * - * @ingroup peripheral_apis - * - * @brief libopencm3 STM32 FDCAN - * - * @version 1.0.0 - * - * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa - * - * Devices can have up to three FDCAN peripherals residing in one FDCAN block. The peripherals - * support both CAN 2.0 A and B standard and Bosch FDCAN standard. FDCAN frame format and - * bitrate switching is supported. The peripheral has several filters for incoming messages that - * can be distributed between two FIFOs and three transmit mailboxes. For transmitted messages - * it is possible to opt for event notification once message is transmitted. - * - * LGPL License Terms @ref lgpl_license -*/ - /* * This file is part of the libopencm3 project. * @@ -53,11 +34,11 @@ * @param [in] canport FDCAN block base address. See @ref fdcan_block. * @param [in] set new value of INIT, true means set * @param [in] timeout Amount of busyloop cycles, function will wait for FDCAN - * to switch it's state. If set to 0, then function returns immediately. + * to switch it's state. If set to 0, then function returns immediately. * @returns FDCAN_E_OK on success, FDCAN_E_TIMEOUT if INIT bit value * didn't change before timeout has expired. */ -static int fdcan_cccr_init_cfg(uint32_t canport, bool set, uint32_t timeout) +int fdcan_cccr_init_cfg(uint32_t canport, bool set, uint32_t timeout) { uint32_t expected; uint32_t wait_ack; @@ -135,43 +116,71 @@ static void fdcan_get_fill_rxfifo(uint32_t canport, uint8_t fifo_id, unsigned *g & FDCAN_RXFIFO_FL_MASK; } -/** Obtain address of FDCAN Message RAM for certain FDCAN block. +/** Returns standard filter start address in message RAM * - * @param [in] canport identification of FDCAN block. See @ref fdcan_block. - * @return Address of Message RAM for given FDCAN block or null pointer - * if FDCAN block identification is invalid. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @returns Base address of standard filter configuration block. */ -static struct fdcan_message_ram *fdcan_get_msgram_addr(uint32_t canport) +struct fdcan_standard_filter *fdcan_get_flssa_addr(uint32_t canport) { - /* This piece of code may look wrong, after one examines - * STM32G4 datasheet and/or g4/memorymap.h. There are three - * memory regions defined for FDCANx_RAM_BASE. They are 0x400 - * bytes apart as per chapter 2.2.2 of [RM0440]. - * - * It turns out, that these addresses are not in line with what - * is specified later in chapter 44.3.3 of [RM0440]. There it is - * stated, that message RAMs are packed and in case of multiple - * FDCAN blocks, message RAM for n-th FDCAN starts at address - * end of (n-1)-th block + 4 (explicitly, offset 0x354). - * - * It turns out, that this statement is also false! In fact FDCAN - * message RAMs are packed tightly and n-th block starts immediately - * after (n-1)-th block ends. Thus offset is going to be computed - * using formula: - * - * FDCAN1_RAM_BASE + (block_id * sizeof(struct fdcan_message_ram)) - */ - if (canport == CAN1) { - return (struct fdcan_message_ram *) (FDCAN1_RAM_BASE + 0); - } else if (canport == CAN2) { - return (struct fdcan_message_ram *) - (FDCAN1_RAM_BASE + sizeof(struct fdcan_message_ram)); - } else if (canport == CAN3) { - return (struct fdcan_message_ram *) - (FDCAN1_RAM_BASE + (2 * sizeof(struct fdcan_message_ram))); - } + struct fdcan_standard_filter *lfssa = (struct fdcan_standard_filter *) + (CAN_MSG_BASE + FDCAN_LFSSA_OFFSET(canport)); + return lfssa; +} - return NULL; +/** Returns extended filter start address in message RAM + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @returns Base address of extended filter configuration block. + */ +struct fdcan_extended_filter *fdcan_get_flesa_addr(uint32_t canport) +{ + struct fdcan_extended_filter *lfesa = (struct fdcan_extended_filter *) + (CAN_MSG_BASE + FDCAN_LFESA_OFFSET(canport)); + return lfesa; +} + +/** Returns FIFO start address in message RAM + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] fifo_id ID of FIFO whose address is requested + * @returns Base address of FIFO block. + */ +struct fdcan_rx_fifo_element *fdcan_get_rxfifo_addr(uint32_t canport, + unsigned fifo_id, unsigned element_id) +{ + struct fdcan_rx_fifo_element *rxfifo = (struct fdcan_rx_fifo_element *) + (CAN_MSG_BASE + FDCAN_RXFIFO_OFFSET(canport, fifo_id) + + (element_id * fdcan_get_fifo_element_size(canport, fifo_id)) + ); + return rxfifo; +} + +/** Returns transmit event start address in message RAM + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @returns Base address of transmit event block. + */ +struct fdcan_tx_event_element *fdcan_get_txevt_addr(uint32_t canport) +{ + struct fdcan_tx_event_element *rxfifo = (struct fdcan_tx_event_element *) + (CAN_MSG_BASE + FDCAN_TXEVT_OFFSET(canport)); + return rxfifo; +} + +/** Returns transmit buffer start address in message RAM + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @returns Base address of transmit buffer block. + */ +struct fdcan_tx_buffer_element *fdcan_get_txbuf_addr(uint32_t canport, unsigned element_id) +{ + struct fdcan_tx_buffer_element *rxfifo = (struct fdcan_tx_buffer_element *) + (CAN_MSG_BASE + FDCAN_TXBUF_OFFSET(canport) + + (element_id * fdcan_get_txbuf_element_size(canport)) + ); + + return rxfifo; } /** Converts frame length to DLC value. @@ -183,7 +192,7 @@ static struct fdcan_message_ram *fdcan_get_msgram_addr(uint32_t canport) * @returns DLC value representing lengths or 0xFF if length cannot * be encoded into DLC format (applies only to FDCAN frame lengths) */ -static uint32_t fdcan_length_to_dlc(uint8_t length) +uint32_t fdcan_length_to_dlc(uint8_t length) { if (length <= 8) { return length; @@ -207,7 +216,7 @@ static uint32_t fdcan_length_to_dlc(uint8_t length) * @param [in] dlc DLC value * @returns data payload length in bytes */ -static uint8_t fdcan_dlc_to_length(uint32_t dlc) +uint8_t fdcan_dlc_to_length(uint32_t dlc) { if (dlc <= 8) { return dlc; @@ -237,13 +246,13 @@ static uint8_t fdcan_dlc_to_length(uint32_t dlc) * * @ref fdcan_init_filter * * @ref fdcan_set_test * - * You can check if FDCAN block is in INIT mode or it is started using + * You can check if FDCAN block is in INIT mode or it is started using * @ref fdcan_get_init_state. * * @param[in] canport CAN register base address. See @ref fdcan_block. * @param [in] timeout Amount of empty busy loops, which routine should wait for FDCAN - * confirming that it entered INIT mode. If set to 0, function will return - * immediately. + * confirming that it entered INIT mode. If set to 0, function will + * return immediately. * @returns Operation error status. See @ref fdcan_error. */ int fdcan_init(uint32_t canport, uint32_t timeout) @@ -309,16 +318,11 @@ void fdcan_set_can(uint32_t canport, bool auto_retry_disable, bool rx_fifo_locke FDCAN_CCCR(canport) &= ~FDCAN_CCCR_MON; } - if (rx_fifo_locked) { - FDCAN_RXGFC(canport) &= ~(FDCAN_RXGFC_F1OM | FDCAN_RXGFC_F0OM); - } else { - FDCAN_RXGFC(canport) |= FDCAN_RXGFC_F1OM | FDCAN_RXGFC_F0OM; - } - + fdcan_set_fifo_locked_mode(canport, rx_fifo_locked); } /** Set FDCAN block parameters for FDCAN transmission - * + * * Enables and configures parameters related to FDCAN transmission. This function * allows configuration of bitrate switching, FDCAN frame format and fast mode * timing. This function can only be called if FDCAN block is in INIT mode. @@ -381,36 +385,6 @@ void fdcan_set_test(uint32_t canport, bool testing, bool loopback) } } -/** Enable FDCAN operation after FDCAN block has been set up. - * - * This function will disable FDCAN configuration effectively - * allowing FDCAN to sync up with the bus. After calling this function - * it is not possible to reconfigure amount of filter rules, yet - * it is possible to configure rules themselves. FDCAN block operation - * state can be checked using @ref fdcan_get_init_state. - * - * @param [in] canport FDCAN block base address. See @ref fdcan_block. - * @param [in] timeout Amount of empty busy loops, which routine should wait for FDCAN - * confirming that it left INIT mode. If set to 0, function will return - * immediately. - * @returns Operation error status. See @ref fdcan_error. - * @note If this function returns with timeout, it usually means that - * FDCAN_clk is not set up properly. - */ -int fdcan_start(uint32_t canport, uint32_t timeout) -{ - /* Error here usually means, that FDCAN_clk is not set up - * correctly, or at all. This usually can't be seen above - * when INIT is set to 1, because default value for INIT is - * 1 as long as one has FDCAN_pclk configured properly. - **/ - if (fdcan_cccr_init_cfg(canport, false, timeout) != 0) { - return FDCAN_E_TIMEOUT; - } - - return FDCAN_E_OK; -} - /** Return current FDCAN block operation state. * * This function effectively returns value of FDCAN_CCCR's INIT bit. @@ -422,59 +396,6 @@ int fdcan_get_init_state(uint32_t canport) return ((FDCAN_CCCR(canport) & FDCAN_CCCR_INIT) == FDCAN_CCCR_INIT); } -/** Configure amount of filters and initialize filtering block. - * - * This function allows to configure global amount of filters present. - * FDCAN block will only ever check as many filters as this function configures. - * Function will also clear all filter blocks to zero values. This function - * can be only called after @ref fdcan_init has already been called and - * @ref fdcan_start has not been called yet as registers holding filter - * count are write-protected unless FDCAN block is in INIT mode. It is possible - * to reconfigure filters (@ref fdcan_set_std_filter and @ref fdcan_set_ext_filter) - * after FDCAN block has already been started. - * - * @param [in] canport FDCAN block base address. See @ref fdcan_block. - * @param [in] std_filt requested amount of standard ID filter rules (0-28) - * @param [in] ext_filt requested amount of extended ID filter rules (0-8) - */ -void fdcan_init_filter(uint32_t canport, uint8_t std_filt, uint8_t ext_filt) -{ - struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); - - /* Only perform initialization of message RAM if there are - * any filters required - */ - if (std_filt > 0) { - FDCAN_RXGFC(canport) = - (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSS_MASK << FDCAN_RXGFC_LSS_SHIFT)) - | (std_filt << FDCAN_RXGFC_LSS_SHIFT); - - - for (int q = 0; q < FDCAN_SFT_MAX_NR; ++q) { - ram->lfssa[q].type_id1_conf_id2 = 0; - } - } else { - /* Reset filter count to zero */ - FDCAN_RXGFC(canport) = - (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSS_MASK << FDCAN_RXGFC_LSS_SHIFT)); - } - - if (ext_filt > 0) { - FDCAN_RXGFC(canport) = - (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSE_MASK << FDCAN_RXGFC_LSE_SHIFT)) - | (ext_filt << FDCAN_RXGFC_LSE_SHIFT); - - for (int q = 0; q < FDCAN_EFT_MAX_NR; ++q) { - ram->lfesa[q].conf_id1 = 0; - ram->lfesa[q].type_id2 = 0; - } - } else { - /* Reset filter count to zero */ - FDCAN_RXGFC(canport) = - (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSE_MASK << FDCAN_RXGFC_LSE_SHIFT)); - } -} - /** Configure filter rule for standard ID frames. * * Sets up filter rule for frames having standard ID. Each FDCAN block can @@ -483,20 +404,20 @@ void fdcan_init_filter(uint32_t canport, uint8_t std_filt, uint8_t ext_filt) * * @param [in] canport FDCAN block base address. See @ref fdcan_block. * @param [in] nr number of filter to be configured - * @param [in] id_list_mode Mode in which id1 and id2 are used to match the rule. - * See @ref fdcan_sft. + * @param [in] id_list_mode Mode in which id1 and id2 are used to match the rule. + * See @ref fdcan_sft. * @param [in] id1 standard ID for matching. Used as exact value, lower bound or bit * pattern depending on matching mode selected * @param [in] id2 standard ID or bitmask. Used as exact value, upper bound or bit mask * depending on matching mode selected - * @param [in] action Action performed if filtering rule matches frame ID. - * See @ref fdcan_sfec. + * @param [in] action Action performed if filtering rule matches frame ID. + * See @ref fdcan_sfec. */ void fdcan_set_std_filter(uint32_t canport, uint32_t nr, uint8_t id_list_mode, uint32_t id1, uint32_t id2, uint8_t action) { - struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); + struct fdcan_standard_filter *lfssa = fdcan_get_flssa_addr(canport); /* id_list_mode and action are passed unguarded. Simply use * defines and it will be OK. id1 and id2 are masked for @@ -506,7 +427,7 @@ void fdcan_set_std_filter(uint32_t canport, uint32_t nr, * overflow into flags. This tends to be extremely time * consuming to debug. */ - ram->lfssa[nr].type_id1_conf_id2 = + lfssa[nr].type_id1_conf_id2 = (id_list_mode << FDCAN_SFT_SHIFT) | (action << FDCAN_SFEC_SHIFT) | ((id1 & FDCAN_SFID1_MASK) << FDCAN_SFID1_SHIFT) @@ -524,25 +445,25 @@ void fdcan_set_std_filter(uint32_t canport, uint32_t nr, * @param [in] canport FDCAN block base address. See @ref fdcan_block. * @param [in] nr number of filter to be configured * @param [in] id_list_mode mode in which id1 and id2 are used to match the rule. - * See @ref fdcan_eft. + * See @ref fdcan_eft. * @param [in] id1 extended ID for matching. Used as exact value, lower bound or bit * pattern depending on matching mode selected * @param [in] id2 extended ID or bitmask. Used as exact value, upper bound or bit mask * depending on matching mode selected * @param [in] action Action performed if filtering rule matches frame ID. - * See @ref fdcan_efec. + * See @ref fdcan_efec. */ void fdcan_set_ext_filter(uint32_t canport, uint32_t nr, uint8_t id_list_mode, uint32_t id1, uint32_t id2, uint8_t action) { - struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); + struct fdcan_extended_filter *lfesa = fdcan_get_flesa_addr(canport); - ram->lfesa[nr].conf_id1 = + lfesa[nr].conf_id1 = (action << FDCAN_EFEC_SHIFT) | ((id1 & FDCAN_EFID1_MASK) << FDCAN_EFID1_SHIFT); - ram->lfesa[nr].type_id2 = + lfesa[nr].type_id2 = (id_list_mode << FDCAN_EFT_SHIFT) | ((id2 & FDCAN_EFID2_MASK) << FDCAN_EFID2_SHIFT); } @@ -572,7 +493,7 @@ int fdcan_transmit(uint32_t canport, uint32_t id, bool ext, bool rtr, return mailbox; } - struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); + struct fdcan_tx_buffer_element *tx_buffer = fdcan_get_txbuf_addr(canport, mailbox); /* Early check: if FDCAN message lentgh is > 8, it must be * a multiple of 4 *and* fdcan format must be enabled. @@ -584,15 +505,15 @@ int fdcan_transmit(uint32_t canport, uint32_t id, bool ext, bool rtr, } if (ext) { - ram->tx_buffer[mailbox].identifier_flags = FDCAN_FIFO_XTD + tx_buffer->identifier_flags = FDCAN_FIFO_XTD | ((id & FDCAN_FIFO_EID_MASK) << FDCAN_FIFO_EID_SHIFT); } else { - ram->tx_buffer[mailbox].identifier_flags = + tx_buffer->identifier_flags = (id & FDCAN_FIFO_SID_MASK) << FDCAN_FIFO_SID_SHIFT; } if (rtr) { - ram->tx_buffer[mailbox].identifier_flags |= FDCAN_FIFO_RTR; + tx_buffer->identifier_flags |= FDCAN_FIFO_RTR; } if (fdcan_fmt) { @@ -603,11 +524,11 @@ int fdcan_transmit(uint32_t canport, uint32_t id, bool ext, bool rtr, flags |= FDCAN_FIFO_BRS; } - ram->tx_buffer[mailbox].evt_fmt_dlc_res = + tx_buffer->evt_fmt_dlc_res = (dlc << FDCAN_FIFO_DLC_SHIFT) | flags; for (int q = 0; q < length; q += 4) { - ram->tx_buffer[mailbox].data[q / 4] = *((uint32_t *) &data[q]); + tx_buffer->data[q / 4] = *((uint32_t *) &data[q]); } FDCAN_TXBAR(canport) |= 1 << mailbox; @@ -640,52 +561,49 @@ int fdcan_receive(uint32_t canport, uint8_t fifo_id, bool release, uint32_t *id, bool *ext, bool *rtr, uint8_t *fmi, uint8_t *length, uint8_t *data, uint16_t *timestamp) { - const struct fdcan_message_ram *ram = fdcan_get_msgram_addr(canport); - - const struct fdcan_rx_fifo_element *fifo; - unsigned pending_frames, get_index, dlc, len; fdcan_get_fill_rxfifo(canport, fifo_id, &get_index, &pending_frames); - fifo = ram->rx_fifo[fifo_id]; - if (pending_frames == 0) { return FDCAN_E_NOTAVAIL; } - dlc = (fifo[get_index].filt_fmt_dlc_ts >> FDCAN_FIFO_DLC_SHIFT) + const struct fdcan_rx_fifo_element *fifo = fdcan_get_rxfifo_addr(canport, + fifo_id, get_index); + + dlc = (fifo->filt_fmt_dlc_ts >> FDCAN_FIFO_DLC_SHIFT) & FDCAN_FIFO_DLC_MASK; len = fdcan_dlc_to_length(dlc); *length = len; - if ((fifo[get_index].identifier_flags & FDCAN_FIFO_XTD) == FDCAN_FIFO_XTD) { + if ((fifo->identifier_flags & FDCAN_FIFO_XTD) == FDCAN_FIFO_XTD) { *ext = true; - *id = (fifo[get_index].identifier_flags >> FDCAN_FIFO_EID_SHIFT) + *id = (fifo->identifier_flags >> FDCAN_FIFO_EID_SHIFT) & FDCAN_FIFO_EID_MASK; } else { *ext = false; - *id = (fifo[get_index].identifier_flags >> FDCAN_FIFO_SID_SHIFT) + *id = (fifo->identifier_flags >> FDCAN_FIFO_SID_SHIFT) & FDCAN_FIFO_SID_MASK; } if (timestamp) { - *timestamp = (uint16_t) (fifo[get_index].filt_fmt_dlc_ts >> FDCAN_FIFO_RXTS_SHIFT) + *timestamp = (uint16_t) (fifo->filt_fmt_dlc_ts >> FDCAN_FIFO_RXTS_SHIFT) & FDCAN_FIFO_RXTS_MASK; } if (fmi) { - *fmi = (uint8_t) (fifo[get_index].filt_fmt_dlc_ts >> FDCAN_FIFO_MM_SHIFT) + *fmi = (uint8_t) (fifo->filt_fmt_dlc_ts >> FDCAN_FIFO_MM_SHIFT) & FDCAN_FIFO_MM_MASK; } if (rtr) { - *rtr = ((fifo[get_index].identifier_flags & FDCAN_FIFO_RTR) == FDCAN_FIFO_RTR); + *rtr = ((fifo->identifier_flags & FDCAN_FIFO_RTR) == FDCAN_FIFO_RTR); } for (unsigned int q = 0; q < len; q += 4) { - *((uint32_t *) &data[q]) = fifo[get_index].data[q / 4]; + *((uint32_t *) &data[q]) = fifo->data[q / 4]; } if (release) { diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 63a13e81..70318c6f 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -40,7 +40,7 @@ OBJS += crs_common_all.o OBJS += dac_common_all.o dac_common_v2.o OBJS += dma_common_l1f013.o OBJS += dmamux.o -OBJS += fdcan.o +OBJS += fdcan.o fdcan_common.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o OBJS += opamp_common_all.o opamp_common_v2.o diff --git a/lib/stm32/g4/fdcan.c b/lib/stm32/g4/fdcan.c new file mode 100644 index 00000000..b2193587 --- /dev/null +++ b/lib/stm32/g4/fdcan.c @@ -0,0 +1,187 @@ +/** @addtogroup fdcan_file FDCAN peripheral API + * + * @ingroup peripheral_apis + * + * @brief libopencm3 STM32 FDCAN + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + * Devices can have up to three FDCAN peripherals residing in one FDCAN block. The peripherals + * support both CAN 2.0 A and B standard and Bosch FDCAN standard. FDCAN frame format and + * bitrate switching is supported. The peripheral has several filters for incoming messages that + * can be distributed between two FIFOs and three transmit mailboxes. For transmitted messages + * it is possible to opt for event notification once message is transmitted. + * + * LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +/* --- FD-CAN functions ----------------------------------------------------- */ + +/** @ingroup fdcan_file */ +/**@{ + * */ + +/** Returns actual size of FIFO entry in FIFO for given CAN port and FIFO. + * + * Obtains value of FIFO entry length. For G4 it returns constant value as + * G4 has FIFO element length hardcoded. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. Unused. + * @param [in] fifo_id ID of FIFO whole length is queried. Unused. + * @returns Length of FIFO entry length covering frame header and frame payload. + */ +unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id) +{ + /* Silences compiler. Variables are present for API compatibility + * with STM32H7 + */ + (void) (canport); + (void) (fifo_id); + return sizeof(struct fdcan_rx_fifo_element); +} + +/** Returns actual size of transmit entry in transmit queue/FIFO for given CAN port. + * + * Obtains value of entry length in transmit queue/FIFO. For G4 it returns constant value + * as G4 has transmit buffer entries of fixed length. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. Unused. + * @param [in] fifo_id ID of FIFO whole length is queried. Unused. + * @returns Length of FIFO entry length covering frame header and frame payload. + */ +unsigned fdcan_get_txbuf_element_size(uint32_t canport) +{ + /* Silences compiler. Variables are present for API compatibility + * with STM32H7 + */ + (void) (canport); + return sizeof(struct fdcan_tx_buffer_element); +} + +/** Configure amount of filters and initialize filtering block. + * + * This function allows to configure global amount of filters present. + * FDCAN block will only ever check as many filters as this function configures. + * Function will also clear all filter blocks to zero values. This function + * can be only called after @ref fdcan_init has already been called and + * @ref fdcan_start has not been called yet as registers holding filter + * count are write-protected unless FDCAN block is in INIT mode. It is possible + * to reconfigure filters (@ref fdcan_set_std_filter and @ref fdcan_set_ext_filter) + * after FDCAN block has already been started. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] std_filt requested amount of standard ID filter rules (0-28) + * @param [in] ext_filt requested amount of extended ID filter rules (0-8) + */ +void fdcan_init_filter(uint32_t canport, uint8_t std_filt, uint8_t ext_filt) +{ + struct fdcan_standard_filter *lfssa = fdcan_get_flssa_addr(canport); + struct fdcan_extended_filter *lfesa = fdcan_get_flesa_addr(canport); + + /* Only perform initialization of message RAM if there are + * any filters required + */ + if (std_filt > 0) { + FDCAN_RXGFC(canport) = + (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSS_MASK << FDCAN_RXGFC_LSS_SHIFT)) + | (std_filt << FDCAN_RXGFC_LSS_SHIFT); + + + for (int q = 0; q < FDCAN_SFT_MAX_NR; ++q) { + lfssa[q].type_id1_conf_id2 = 0; + } + } else { + /* Reset filter count to zero */ + FDCAN_RXGFC(canport) = + (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSS_MASK << FDCAN_RXGFC_LSS_SHIFT)); + } + + if (ext_filt > 0) { + FDCAN_RXGFC(canport) = + (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSE_MASK << FDCAN_RXGFC_LSE_SHIFT)) + | (ext_filt << FDCAN_RXGFC_LSE_SHIFT); + + for (int q = 0; q < FDCAN_EFT_MAX_NR; ++q) { + lfesa[q].conf_id1 = 0; + lfesa[q].type_id2 = 0; + } + } else { + /* Reset filter count to zero */ + FDCAN_RXGFC(canport) = + (FDCAN_RXGFC(canport) & ~(FDCAN_RXGFC_LSE_MASK << FDCAN_RXGFC_LSE_SHIFT)); + } +} + +/** Enable FDCAN operation after FDCAN block has been set up. + * + * This function will disable FDCAN configuration effectively + * allowing FDCAN to sync up with the bus. After calling this function + * it is not possible to reconfigure amount of filter rules, yet + * it is possible to configure rules themselves. FDCAN block operation + * state can be checked using @ref fdcan_get_init_state. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] timeout Amount of empty busy loops, which routine should wait for FDCAN + * confirming that it left INIT mode. If set to 0, function will return + * immediately. + * @returns Operation error status. See @ref fdcan_error. + * @note If this function returns with timeout, it usually means that + * FDCAN_clk is not set up properly. + */ +int fdcan_start(uint32_t canport, uint32_t timeout) +{ + /* Error here usually means, that FDCAN_clk is not set up + * correctly, or at all. This usually can't be seen above + * when INIT is set to 1, because default value for INIT is + * 1 as long as one has FDCAN_pclk configured properly. + **/ + if (fdcan_cccr_init_cfg(canport, false, timeout) != 0) { + return FDCAN_E_TIMEOUT; + } + + return FDCAN_E_OK; +} + +/** Configure FDCAN FIFO lock mode + * + * This function allows to choose between locked and overewrite mode of FIFOs. In locked mode, + * whenever FIFO is full and new frame arrives, which would normally been stored into given + * FIFO, then frame is dropped. If overwrite mode is active, then most recent message in FIFO + * is rewritten by frame just received. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] locked true activates locked mode, false activates overwrite mode + */ +void fdcan_set_fifo_locked_mode(uint32_t canport, bool locked) +{ + if (locked) { + FDCAN_RXGFC(canport) &= ~(FDCAN_RXGFC_F1OM | FDCAN_RXGFC_F0OM); + } else { + FDCAN_RXGFC(canport) |= FDCAN_RXGFC_F1OM | FDCAN_RXGFC_F0OM; + } +} + +/** @} */ diff --git a/lib/stm32/h7/Makefile b/lib/stm32/h7/Makefile index 5a133ec7..2c7cbb18 100644 --- a/lib/stm32/h7/Makefile +++ b/lib/stm32/h7/Makefile @@ -39,6 +39,7 @@ ARFLAGS = rcs OBJS += dac_common_all.o dac_common_v2.o OBJS += exti_common_all.o +OBJS += fdcan.o fdcan_common.o OBJS += flash_common_all.o flash_common_f.o flash_common_f24.o OBJS += fmc_common_f47.o OBJS += gpio_common_all.o gpio_common_f0234.o diff --git a/lib/stm32/h7/fdcan.c b/lib/stm32/h7/fdcan.c new file mode 100644 index 00000000..fd0cad0e --- /dev/null +++ b/lib/stm32/h7/fdcan.c @@ -0,0 +1,473 @@ +/** @addtogroup fdcan_file FDCAN peripheral API + * + * @ingroup peripheral_apis + * + * @brief libopencm3 STM32 FDCAN + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + * Device is equipped with two FDCAN peripherals residing in one FDCAN block. The peripherals + * support both CAN 2.0 A and B standard and Bosch FDCAN standard. FDCAN frame format and + * bitrate switching is supported. The peripheral has several filters for incoming messages that + * can be distributed between two FIFOs and transmit buffer all of configurable amount of + * entries. For transmitted messages it is possible to opt for event notification once message + * is transmitted. + * + * The FDCAN peripheral present in STM32 H7 is a superset of FDCAN peripheral found in other MCUs + * such as STM32 G4. It allows more fine-grade control over buffer and filter allocation and + * supports TTCAN on CAN1, etc. This driver provides source-level backwards compatible + * implementation of driver, which allows build of unmodified software originally written for + * STM32 G4 on STM32 H7. + * + * LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +#define FDCAN_LSS_COUNT(can_base) \ + ((FDCAN_SIDFC(can_base) >> FDCAN_SIDFC_LSS_SHIFT) & FDCAN_SIDFC_LSS_MASK) + +#define FDCAN_LSE_COUNT(can_base) \ + ((FDCAN_XIDFC(can_base) >> FDCAN_XIDFC_LSE_SHIFT) & FDCAN_XIDFC_LSE_MASK) + +/* --- FD-CAN functions ----------------------------------------------------- */ + +/** @ingroup fdcan_file */ +/**@{ + * */ + +/** Returns actual size of FIFO entry in FIFO for given CAN port and FIFO. + * + * Obtains value of FIFO entry length. This value covers both fixed-size frame + * header block and payload buffer. User can configure payload buffer size individually + * for each FIFO and designated RX buffer. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] fifo_id ID of FIFO whole length is queried. + * @returns Length of FIFO entry length covering frame header and frame payload. + */ +unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id) +{ + unsigned element_size; + if (fifo_id == 0) { + element_size = FDCAN_RXESC(canport) >> FDCAN_RXESC_F0DS_SHIFT; + } else { + element_size = FDCAN_RXESC(canport) >> FDCAN_RXESC_F1DS_SHIFT; + } + + /* Mask is unshifted and at this point, element_size is unshifted too */ + return 8 + fdcan_dlc_to_length((element_size & FDCAN_RXESC_F0DS_MASK) | 0x7); +} + +/** Returns actual size of transmit entry in transmit queue/FIFO for given CAN port. + * + * Obtains value of entry length in transmit queue/FIFO. This value covers both + * fixed-sized frame header block and payload buffer. User can configure payload buffer + * size. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] fifo_id ID of FIFO whole length is queried. + * @returns Length of FIFO entry length covering frame header and frame payload. + */ +unsigned fdcan_get_txbuf_element_size(uint32_t canport) +{ + unsigned element_size; + element_size = (FDCAN_TXESC(canport) >> FDCAN_TXESC_TBDS_SHIFT) & FDCAN_TXESC_TBDS_MASK; + return 8 + fdcan_dlc_to_length((element_size & FDCAN_TXESC_TBDS_MASK) | 0x7); +} + +/** Initialize allocation of standard filter block in CAN message RAM. + * + * Allows specifying size of standard filtering block (in term of available filtering + * rules and filter base address within CAN message RAM. Note, that there are no limitations + * nor checking on address provided. It is possible to share whole filtering block or + * portion of it between multiple CAN interfaces. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] flssa standard filtering block start address offset in message RAM + * @param [in] lss amount of standard filters + */ +void fdcan_init_std_filter_ram(uint32_t canport, uint32_t flssa, uint8_t lss) +{ + FDCAN_SIDFC(canport) = flssa << FDCAN_SIDFC_FLSSA_SHIFT + | lss << FDCAN_SIDFC_LSS_SHIFT; +} + +/** Initialize allocation of extended filter block in CAN message RAM. + * + * Allows specifying size of extended filtering block (in term of available filtering + * rules and filter base address within CAN message RAM. Note, that there are no limitations + * nor checking on address provided. It is possible to share whole filtering block or + * portion of it between multiple CAN interfaces. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] flesa extended filtering block start address offset in message RAM + * @param [in] lse amount of extended filters + */ +void fdcan_init_ext_filter_ram(uint32_t canport, uint32_t flesa, uint8_t lse) +{ + FDCAN_XIDFC(canport) = flesa << FDCAN_XIDFC_FLESA_SHIFT + | lse << FDCAN_XIDFC_LSE_SHIFT; +} + +/** Initialize allocation of FIFO block in CAN message RAM. + * + * Allows specifying size of FIFO block (in term of available messages in FIFO + * and FIFO base address within CAN message RAM. Note, that there are no limitations + * nor checking on address provided. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] fifo_id ID of fifo being configured + * @param [in] fxsa FIFO block start address offset in message RAM + * @param [in] fxs amount of entries allocated in FIFO + */ +void fdcan_init_fifo_ram(uint32_t canport, unsigned fifo_id, uint32_t fxsa, uint8_t fxs) +{ + FDCAN_RXFIC(canport, fifo_id) = (FDCAN_RXFIC(canport, fifo_id) + & ~( + (FDCAN_RXFIC_FIS_MASK << FDCAN_RXFIC_FIS_SHIFT) + | (FDCAN_RXFIC_FISA_MASK << FDCAN_RXFIC_FISA_SHIFT) + )) + | (fxs << FDCAN_RXFIC_FIS_SHIFT) + | (fxsa & (FDCAN_RXFIC_FISA_MASK << FDCAN_RXFIC_FISA_SHIFT)); +} + +/** Initialize allocation of transmit event block in CAN message RAM. + * + * Allows specifying size of transmit event block (in term of allocated events and block + * base address within CAN message RAM. Note, that there are no limitations + * nor checking on address provided. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] fifo_id ID of fifo being configured + * @param [in] fxsa FIFO block start address offset in message RAM + * @param [in] fxs amount of entries allocated in FIFO + */ +void fdcan_init_tx_event_ram(uint32_t canport, uint32_t tesa, uint8_t tes) +{ + FDCAN_TXEFC(canport) = (FDCAN_TXEFC(canport) + & ~( + (FDCAN_TXEFC_EFS_MASK << FDCAN_TXEFC_EFS_SHIFT) + | (FDCAN_TXEFC_EFSA_MASK << FDCAN_TXEFC_EFSA_SHIFT) + )) + | (tes << FDCAN_TXEFC_EFS_SHIFT) + | (tesa & (FDCAN_TXEFC_EFSA_MASK << FDCAN_TXEFC_EFSA_SHIFT)); +} + +/** Initialize allocation of transmit queue block in CAN message RAM. + * + * Allows specifying size of transmit queue block (in term of allocated buffers and block + * base address within CAN message RAM. Note, that there are no limitations + * nor checking on address provided. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] fifo_id ID of fifo being configured + * @param [in] fxsa FIFO block start address offset in message RAM + * @param [in] fxs amount of entries allocated in FIFO + */ +void fdcan_init_tx_buffer_ram(uint32_t canport, uint32_t tbsa, uint8_t tbs) +{ + FDCAN_TXBC(canport) = (FDCAN_TXBC(canport) + & ~( + (FDCAN_TXBC_TFQS_MASK << FDCAN_TXBC_TFQS_SHIFT) + | (FDCAN_TXBC_TBSA_MASK << FDCAN_TXBC_TBSA_SHIFT) + )) + | (tbs << FDCAN_TXBC_TFQS_SHIFT) + | (tbsa & (FDCAN_TXBC_TBSA_MASK << FDCAN_TXBC_TBSA_SHIFT)); +} + +/** Initialize size of data fields in reception buffers. + * + * Configures maximum size of message payload, which can be stored in different + * reception buffers. Each buffer can have maximum payload size configured independently. + * Buffers can only be configured to sizes which are valid sizes of FDCAN payload. Sizes smaller + * than 8 are automatically padded to 8. + * @note If you change these values, then content of reception buffers is invalidated. You may + * also want to recalculate base addresses of objects in message RAM as their size might have + * changed. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] rxbuf maximum storable payload size of dedicated RX buffer + * @param [in] rxfifo0 maximum storable payload size of RX FIFO 0 + * @param [in] rxfifo1 maximum storable payload size of RX FIFO 1 + * @returns operation return status. See @ref fdcan_error. + */ +int fdcan_set_rx_element_size(uint32_t canport, uint8_t rxbuf, uint8_t rxfifo0, uint8_t rxfifo1) +{ + unsigned rxbufdlc = fdcan_length_to_dlc(rxbuf); + unsigned rxfifo0dlc = fdcan_length_to_dlc(rxfifo0); + unsigned rxfifo1dlc = fdcan_length_to_dlc(rxfifo1); + + if (rxbufdlc == 0xFF || rxfifo0dlc == 0xFF || rxfifo1dlc == 0xFF) { + return FDCAN_E_INVALID; + } + + /* RXESC fields use format of FDCAN DLC, albeit using only + * three LSBs. DLC < 8 is always allocated as 8 bytes and is always + * encoded as 0. + */ + if (rxbufdlc <= 8) { + rxbufdlc = 0; + } else { + rxbufdlc &= ~(1 << 4); + } + + if (rxfifo0dlc <= 8) { + rxfifo0dlc = 0; + } else { + rxfifo0dlc &= ~(1 << 4); + } + + if (rxfifo1dlc <= 8) { + rxfifo1dlc = 0; + } else { + rxfifo1dlc &= ~(1 << 4); + } + + FDCAN_RXESC(canport) = rxbufdlc << FDCAN_RXESC_RBDS_SHIFT + | rxfifo1dlc << FDCAN_RXESC_F1DS_SHIFT + | rxfifo0dlc << FDCAN_RXESC_F0DS_SHIFT; + + return FDCAN_E_OK; +} + +/** Initialize size of data fields in transmit buffers. + * + * Configures maximum size of message payload, which can be stored either in dedicated + * transmit buffer or into transmit queue/FIFO. One size is applied both to transmit buffer + * and transmit queue / FIFO. Buffers can only be configured to sizes which are valid sizes + * of FDCAN payload. Sizes smaller than 8 are automatically padded to 8 bytes. + * @note If you change these values, then content of transmission buffers is invalidated. You may + * also want to recalculate base addresses of objects in message RAM as their size might have + * changed. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] txbuf maximum storable payload size of TX buffer / FIFO / queue + * @returns operation return status. See @ref fdcan_error. + */ +int fdcan_set_tx_element_size(uint32_t canport, uint8_t txbuf) +{ + unsigned txbufdlc = fdcan_length_to_dlc(txbuf); + + if (txbufdlc == 0xFF) { + return FDCAN_E_INVALID; + } + + if (txbufdlc <= 8) { + txbufdlc = 0; + } else { + txbufdlc &= ~(1 << 4); + } + + FDCAN_TXESC(canport) = txbufdlc << FDCAN_TXESC_TBDS_SHIFT; + + return FDCAN_E_OK; +} + +/** Configure amount of filters and initialize filtering block. + * + * This function allows to configure global amount of filters present. + * FDCAN block will only ever check as many filters as this function configures. + * Function will also clear all filter blocks to zero values. This function + * can be only called after @ref fdcan_init has already been called and + * @ref fdcan_start has not been called yet as registers holding filter + * count are write-protected unless FDCAN block is in INIT mode. It is possible + * to reconfigure filters (@ref fdcan_set_std_filter and @ref fdcan_set_ext_filter) + * after FDCAN block has already been started. + * + * This function is provided for source level compatibility with code written for + * STM32G4. As an alternative, you can use @ref fdcan_init_std_filter_ram() and + * @ref fdcan_init_ext_filter_ram() to have more control over filtering configuration. + * Note that if you do so, your code won't be compatible with STM32G4 controllers. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] std_filt requested amount of standard ID filter rules (0-28) + * @param [in] ext_filt requested amount of extended ID filter rules (0-8) + */ +void fdcan_init_filter(uint32_t canport, uint8_t std_filt, uint8_t ext_filt) +{ + struct fdcan_standard_filter *lfssa; + struct fdcan_extended_filter *lfesa; + + int can_id = FDCAN_BLOCK_ID(canport); + + int lfsofs = 0; + int lfeofs = 0; + int lfssize = std_filt * sizeof(struct fdcan_standard_filter); + int lfesize = ext_filt * sizeof(struct fdcan_extended_filter); + + if (can_id == 0) { + lfsofs = 0; + lfeofs = lfssize; + } else { + lfsofs = CAN_MSG_BASE + CAN_MSG_SIZE - lfssize; + lfeofs = lfsofs - lfesize; + } + + fdcan_init_std_filter_ram(canport, lfsofs, 28); + fdcan_init_ext_filter_ram(canport, lfeofs, 8); + + lfssa = fdcan_get_flssa_addr(canport); + lfesa = fdcan_get_flesa_addr(canport); + + /* Only perform initialization of message RAM if there are + * any filters required + */ + if (std_filt > 0) { + for (int q = 0; q < 28; ++q) { + lfssa[q].type_id1_conf_id2 = 0; + } + } + + if (ext_filt > 0) { + for (int q = 0; q < 8; ++q) { + lfesa[q].conf_id1 = 0; + lfesa[q].type_id2 = 0; + } + } +} + +/** Enable FDCAN operation after FDCAN block has been set up. + * + * This function will disable FDCAN configuration effectively + * allowing FDCAN to sync up with the bus. After calling this function + * it is not possible to reconfigure amount of filter rules, yet + * it is possible to configure rules themselves. FDCAN block operation + * state can be checked using @ref fdcan_get_init_state. + * + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] timeout Amount of empty busy loops, which routine should wait for FDCAN + * confirming that it left INIT mode. If set to 0, function will return + * immediately. + * @returns Operation error status. See @ref fdcan_error. + * @note If this function returns with timeout, it usually means that + * FDCAN_clk is not set up properly. + */ +int fdcan_start(uint32_t canport, uint32_t timeout) +{ + /* This block detects obviously invalid configuration of + * RX FIFOs and TX buffers. Such situation may happen + * if code originally targeted for STM32G4 is compiled for + * STM32H7. This code is not aware of H7 abilities and + * leaves this stuff unconfigured. We pick up here and + * assume, that the code wants the FDCAN to behave as if + * it was STM32G4. Therefore we will configure two three entry + * long RX FIFOs, three entry long TX event buffer and three + * entry long TX FIFO/queue here. + */ + if (FDCAN_RXFIFO_OFFSET(canport, 0) == 0 + && FDCAN_RXFIFO_OFFSET(canport, 1) == 0 + && FDCAN_TXBUF_OFFSET(canport) == 0 + && FDCAN_TXEVT_OFFSET(canport) == 0 + && FDCAN_RXESC(canport) == 0 + && FDCAN_TXESC(canport) == 0 + ) { + /* These sizes are fixed based on what G4 contains. */ + int fifo0_size = 3 * sizeof(struct fdcan_rx_fifo_element); + int fifo1_size = fifo0_size; + int txevt_size = 3 * sizeof(struct fdcan_tx_event_element); + int txbuf_size = 3 * sizeof(struct fdcan_tx_buffer_element); + + fdcan_set_rx_element_size(canport, 0, 64, 64); + fdcan_set_tx_element_size(canport, 64); + + /* At this point we simply assume that FLSSA and FLESA were + * set up by calling fdcan_init_filter(). It they weren't, + * there just won't be allocated any space for them. + * That's not a problem as after fdcan_start returns, it is + * not possible to configure filter amount anymore. + * + * Default approach is to configure CAN1 to occupy bottom + * of message RAM and CAN1 to occupy top of message RAM keeping + * large unused space in between. This ensures that even if someone + * starts playing with CAN1, "implicit" configuration of CAN2 done + * here won't break things magically. + */ + if (FDCAN_BLOCK_ID(canport) == 0) { + /* CAN1 will use bottom-up layout with + * FLSSA < FLESA < F0SA < F1SA < TXESA < TXBSA + * Rx buffer is not used. + */ + fdcan_init_fifo_ram(canport, 0, + FDCAN_LFESA_OFFSET(canport) + + FDCAN_LSE_COUNT(canport) * sizeof(struct fdcan_extended_filter), + 3); + fdcan_init_fifo_ram(canport, 1, + FDCAN_RXFIFO_OFFSET(canport, 0) + fifo0_size, 3); + fdcan_init_tx_event_ram(canport, + FDCAN_RXFIFO_OFFSET(canport, 1) + fifo1_size, 3); + fdcan_init_tx_buffer_ram(canport, + FDCAN_TXEVT_OFFSET(canport) + txevt_size, 3); + } else { + /* LFESA might be uninitialized. In such case + * we forge it's address at the end of MSG RAM + */ + int lfesa_offs = FDCAN_LFESA_OFFSET(canport); + if (lfesa_offs == 0) { + lfesa_offs = CAN_MSG_SIZE; + } + /* CAN2 will use top-down layout with + * TXBSA < TXESA < F1SA < F0SA < FLESA < FLSSA + * Rx buffer is not used. + * This arrangement should ensure that even if + * CAN1 was configured manually, CAN2 default + * configuration should not break CAN1. + */ + fdcan_init_fifo_ram(canport, 0, lfesa_offs - fifo0_size, 3); + fdcan_init_fifo_ram(canport, 1, + FDCAN_RXFIFO_OFFSET(canport, 0) - fifo1_size, 3); + fdcan_init_tx_event_ram(canport, + FDCAN_RXFIFO_OFFSET(canport, 1) - txevt_size, 3); + fdcan_init_tx_buffer_ram(canport, + FDCAN_TXEVT_OFFSET(canport) - txbuf_size, 3); + } + + } + /* Error here usually means, that FDCAN_clk is not set up + * correctly, or at all. This usually can't be seen above + * when INIT is set to 1, because default value for INIT is + * 1 as long as one has FDCAN_pclk configured properly. + **/ + if (fdcan_cccr_init_cfg(canport, false, timeout) != 0) { + return FDCAN_E_TIMEOUT; + } + + return FDCAN_E_OK; +} + +/** Configure FDCAN FIFO lock mode + * + * This function allows to choose between locked and overewrite mode of FIFOs. In locked mode, + * whenever FIFO is full and new frame arrives, which would normally been stored into given + * FIFO, then frame is dropped. If overwrite mode is active, then most recent message in FIFO + * is rewritten by frame just received. + * @param [in] canport FDCAN block base address. See @ref fdcan_block. + * @param [in] locked true activates locked mode, false activates overwrite mode + */ +void fdcan_set_fifo_locked_mode(uint32_t canport, bool locked) +{ + if (locked) { + FDCAN_RXF0C(canport) &= ~(FDCAN_RXF0C_F0OM); + FDCAN_RXF1C(canport) &= ~(FDCAN_RXF1C_F1OM); + } else { + FDCAN_RXF0C(canport) |= FDCAN_RXF0C_F0OM; + FDCAN_RXF1C(canport) |= FDCAN_RXF1C_F1OM; + } +} + From 504dc95d9ba1c2505a30d575371accfe49a69fb9 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 16 Apr 2021 12:38:31 +0000 Subject: [PATCH 097/206] stm32:fdcan: fix doxygen warnings Added some descriptions for missing parameters, (hopefully) clarified some along the way. Fixed all can related warnings in doxygen logs. Added doxgen tags where meaningful comments had been provided. Dropped redundant comment separators. --- include/libopencm3/stm32/fdcan.h | 114 ++++++++++++++-------------- include/libopencm3/stm32/g4/fdcan.h | 13 ++-- include/libopencm3/stm32/h7/fdcan.h | 45 ++++++----- lib/stm32/common/fdcan_common.c | 10 ++- lib/stm32/g4/fdcan.c | 1 - lib/stm32/h7/fdcan.c | 14 ++-- 6 files changed, 96 insertions(+), 101 deletions(-) diff --git a/include/libopencm3/stm32/fdcan.h b/include/libopencm3/stm32/fdcan.h index f59e9d1b..8b68a163 100644 --- a/include/libopencm3/stm32/fdcan.h +++ b/include/libopencm3/stm32/fdcan.h @@ -85,61 +85,61 @@ #define FDCAN_TXBC(can_base) MMIO32(can_base + 0x00C0) #define FDCAN_TXFQS(can_base) MMIO32(can_base + 0x00C4) -/* DAY[7:0]: FDCAN core revision date */ +/** DAY[7:0]: FDCAN core revision date */ #define FDCAN_CREL_DAY_SHIFT 0 #define FDCAN_CREL_DAY_MASK 0xFF -/* MON[7:0]: FDCAN core revision month */ +/** MON[7:0]: FDCAN core revision month */ #define FDCAN_CREL_MON_SHIFT 8 #define FDCAN_CREL_MON_MASK 0xFF -/* YEAR[3:0]: FDCAN core revision year */ +/** YEAR[3:0]: FDCAN core revision year */ #define FDCAN_CREL_YEAR_SHIFT 16 #define FDCAN_CREL_YEAR_MASK 0xF -/* SUBSTEP[3:0]: FDCAN core release sub stepping */ +/** SUBSTEP[3:0]: FDCAN core release sub stepping */ #define FDCAN_CREL_SUBSTEP_SHIFT 20 #define FDCAN_CREL_SUBSTEP_MASK 0xF -/* STEP[3:0]: FDCAN core release stepping */ +/** STEP[3:0]: FDCAN core release stepping */ #define FDCAN_CREL_STEP_SHIFT 24 #define FDCAN_CREL_STEP_MASK 0xF -/* REL[3:0]: FDCAN core release number */ +/** REL[3:0]: FDCAN core release number */ #define FDCAN_CREL_REL_SHIFT 28 #define FDCAN_CREL_REL_MASK 0xF -/* DSJW[3:0]: Synchronization jump width */ +/** DSJW[3:0]: Synchronization jump width */ #define FDCAN_DBTP_DSJW_SHIFT 0 #define FDCAN_DBTP_DSJW_MASK 0xF -/* DTSEG2[3:0]: Data time segment after sample point */ +/** DTSEG2[3:0]: Data time segment after sample point */ #define FDCAN_DBTP_DTSEG2_SHIFT 4 #define FDCAN_DBTP_DTSEG2_MASK 0xF -/* DTSEG1[4:0]: Data time segment before sample point */ +/** DTSEG1[4:0]: Data time segment before sample point */ #define FDCAN_DBTP_DTSEG1_SHIFT 8 #define FDCAN_DBTP_DTSEG1_MASK 0x1F -/* DBRP[4:0]: Data bit rate prescaler */ +/** DBRP[4:0]: Data bit rate prescaler */ #define FDCAN_DBTP_DBRP_SHIFT 16 #define FDCAN_DBTP_DBRP_MASK 0x1F #define FDCAN_DBTP_TDC (1 << 23) #define FDCAN_TEST_LBCK (1 << 4) -/* TX[1:0]: Control of transmit pin */ +/** TX[1:0]: Control of transmit pin */ #define FDCAN_TEST_TX_SHIFT 5 #define FDCAN_TEST_TX_MASK 0x3 #define FDCAN_TEST_RX (1 << 7) -/* WDC[7:0]: RAM watchdog configuration */ +/** WDC[7:0]: RAM watchdog configuration */ #define FDCAN_RWD_WDC_SHIFT 0 #define FDCAN_RWD_WDC_MASK 0xFF -/* WDV[7:0]: RAM watchdog actual value */ +/** WDV[7:0]: RAM watchdog actual value */ #define FDCAN_RWD_WDV_SHIFT 7 #define FDCAN_RWD_WDV_MASK 0xFF @@ -173,74 +173,74 @@ */ #define FDCAN_CCCR_INIT_TIMEOUT 0x0000FFFF -/* NTSEG2[6:0]: Nominal timing segment after sample point length */ +/** NTSEG2[6:0]: Nominal timing segment after sample point length */ #define FDCAN_NBTP_NTSEG2_SHIFT 0 #define FDCAN_NBTP_NTSEG2_MASK 0x7F -/* NTSEG1[7:0]: Nominal timing segment before sample point length */ +/** NTSEG1[7:0]: Nominal timing segment before sample point length */ #define FDCAN_NBTP_NTSEG1_SHIFT 8 #define FDCAN_NBTP_NTSEG1_MASK 0xFF -/* NBRP[8:0]: Norminal timing bit rate prescaler */ +/** NBRP[8:0]: Norminal timing bit rate prescaler */ #define FDCAN_NBTP_NBRP_SHIFT 16 #define FDCAN_NBTP_NBRP_MASK 0x1FF -/* NSJW[6:0]: Norminal timing resynchronization jumb width*/ +/** NSJW[6:0]: Norminal timing resynchronization jumb width*/ #define FDCAN_NBTP_NSJW_SHIFT 25 #define FDCAN_NBTP_NSJW_MASK 0x7F -/* TSS[1:0]: Timestamp select */ +/** TSS[1:0]: Timestamp select */ #define FDCAN_TSCC_TSS_SHIFT 0 #define FDCAN_TSCC_TSS_MASK 0x3 -/* TCP[3:0]: Timestamp counter prescaler */ +/** TCP[3:0]: Timestamp counter prescaler */ #define FDCAN_TSCC_TCP_SHIFT 16 #define FDCAN_TSCC_TCP_MASK 0xF -/* TSC[15:0]: Timestamp counter value */ +/** TSC[15:0]: Timestamp counter value */ #define FDCAN_TSCV_TSC_SHIFT 0 #define FDCAN_TSCV_TSC_MASK 0xFFFF #define FDCAN_TOCC_ETOC (1 << 0) -/* TOS[1:0]: Timeout select */ +/** TOS[1:0]: Timeout select */ #define FDCAN_TOCC_TOS_SHIFT 1 #define FDCAN_TOCC_TOS_MASK 0x3 -/* TOP[15:0]: Timeout period */ +/** TOP[15:0]: Timeout period */ #define FDCAN_TOCC_TOP_SHIFT 16 #define FDCAN_TOCC_TOP_MASK 0xFFFF -/* TOC[15:0]: Timeout counter */ +/** TOC[15:0]: Timeout counter */ #define FDCAN_TOCV_TOC_SHIFT 0 #define FDCAN_TOCV_TOC_MASK 0xFFFF -/* TEC[7:0]: Transmit error counter */ +/** TEC[7:0]: Transmit error counter */ #define FDCAN_ECR_TEC_SHIFT 0 #define FDCAN_ECR_TEC_MASK 0xFF -/* REC[6:0]: Receive error counter */ +/** REC[6:0]: Receive error counter */ #define FDCAN_ECR_REC_SHIFT 8 #define FDCAN_ECR_REC_MASK 0x7F #define FDCAN_ECR_RP (1 << 15) -/* CEL[7:0]: CAN error logging */ +/** CEL[7:0]: CAN error logging */ #define FDCAN_ECR_CEL_SHIFT 16 #define FDCAN_ECR_CEL_MASK 0xFF -/* LEC[2:0]: Last error code */ +/** LEC[2:0]: Last error code */ #define FDCAN_PSR_LEC_SHIFT 0 #define FDCAN_PSR_LEC_MASK 0x7 -/* ACT[1:0]: CAN block activity */ +/** ACT[1:0]: CAN block activity */ #define FDCAN_PSR_ACT_SHIFT 3 #define FDCAN_PSR_ACT_MASK 0x3 #define FDCAN_PSR_EP (1 << 5) #define FDCAN_PSR_EW (1 << 6) #define FDCAN_PSR_BO (1 << 7) -/* DLEC[2:0]: Last error code in data section */ +/** DLEC[2:0]: Last error code in data section */ #define FDCAN_PSR_DLEC_SHIFT 8 #define FDCAN_PSR_DLEC_MASK 0x7 @@ -251,15 +251,15 @@ #define FDCAN_PSR_REDL (1 << 13) #define FDCAN_PSR_PXE (1 << 14) -/* TDCV[6:0]: Transmitter delay compensation value */ +/** TDCV[6:0]: Transmitter delay compensation value */ #define FDCAN_PSR_TDCV_SHIFT 16 #define FDCAN_PSR_TDCV_MASK 0x7F -/* TDCF[6:0]: Transmitter delay compensation filter window length */ +/** TDCF[6:0]: Transmitter delay compensation filter window length */ #define FDCAN_TDCR_TDCF_SHIFT 0 #define FDCAN_TDCR_TDCF_MASK 0x7F -/* TDCO[6:0]: Transmitter delay compensation offset */ +/** TDCO[6:0]: Transmitter delay compensation offset */ #define FDCAN_TDCR_TDCO_SHIFT 8 #define FDCAN_TDCR_TDCO_MASK 0x7F @@ -337,87 +337,87 @@ #define FDCAN_ILE_INT1 (1 << 1) -/* EIDM[28:0]: Extended ID mask for filtering */ +/** EIDM[28:0]: Extended ID mask for filtering */ #define FDCAN_XIDAM_EIDM_SHIFT 0 #define FDCAN_XIDAM_EIDM_MASK 0x1FFFFFFF -/* BIDX[2:0]: Buffer index */ +/** BIDX[2:0]: Buffer index */ #define FDCAN_HPMS_BIDX_SHIFT 0 #define FDCAN_HPMS_BIDX_MASK 0x7 -/* MSI[1:0]: Message storage indicator */ +/** MSI[1:0]: Message storage indicator */ #define FDCAN_HPMS_MSI_SHIFT 6 #define FDCAN_HPMS_MSI_MASK 0x3 -/* FIDX[4:0]: Filter index */ +/** FIDX[4:0]: Filter index */ #define FDCAN_HPMS_FIDX_SHIFT 8 #define FDCAN_HPMS_FIDX_MASK 0x1F #define FDCAN_HPMS_FLS (1 << 15) -/* Fill level of Rx FIFOs */ +/** Fill level of Rx FIFOs */ #define FDCAN_RXFIFO_FL_SHIFT 0 -/* Get index of Rx FIFOs */ +/** Get index of Rx FIFOs */ #define FDCAN_RXFIFO_GI_SHIFT 8 -/* Put index of Rx FIFOs */ +/** Put index of Rx FIFOs */ #define FDCAN_RXFIFO_PI_SHIFT 16 #define FDCAN_RXFIFO_FF (1 << 24) #define FDCAN_RXFIFO_RFL (1 << 25) -/* F0FL[3:0]: Fill level of Rx FIFO 0 */ +/** F0FL[3:0]: Fill level of Rx FIFO 0 */ #define FDCAN_RXF0S_F0FL_SHIFT FDCAN_RXFIFO_FL_SHIFT #define FDCAN_RXF0S_F0FL_MASK FDCAN_RXFIFO_FL_MASK -/* F0GI[1:0]: Get index of Rx FIFO 0 */ +/** F0GI[1:0]: Get index of Rx FIFO 0 */ #define FDCAN_RXF0S_F0GI_SHIFT FDCAN_RXFIFO_GI_SHIFT #define FDCAN_RXF0S_F0GI_MASK FDCAN_RXFIFO_GI_MASK -/* F0PI[1:0]: Put index of Rx FIFO 0 */ +/** F0PI[1:0]: Put index of Rx FIFO 0 */ #define FDCAN_RXF0S_F0PI_SHIFT FDCAN_RXFIFO_PI_SHIFT #define FDCAN_RXF0S_F0PI_MASK FDCAN_RXFIFO_PI_MASK #define FDCAN_RXF0S_F0F FDCAN_RXFIFO_FF #define FDCAN_RXF0S_RF0L FDCAN_RXFIFO_RFL -/* Rx FIFOs acknowledge index */ +/** Rx FIFOs acknowledge index */ #define FDCAN_RXFIFO_AI_SHIFT 0 -/* R0AI[2:0]: Rx FIFO 0 acknowledge index */ +/** R0AI[2:0]: Rx FIFO 0 acknowledge index */ #define FDCAN_RXF0A_R0AI_SHIFT FDCAN_RXFIFO_AI_SHIFT #define FDCAN_RXF0A_R0AI_MASK FDCAN_RXFIFO_AI_MASK -/* F1FL[3:1]: Fill level of Rx FIFO 1 */ +/** F1FL[3:1]: Fill level of Rx FIFO 1 */ #define FDCAN_RXF1S_F1FL_SHIFT FDCAN_RXFIFO_FL_SHIFT #define FDCAN_RXF1S_F1FL_MASK FDCAN_RXFIFO_FL_MASK -/* F1GI[1:1]: Get index of Rx FIFO 1 */ +/** F1GI[1:1]: Get index of Rx FIFO 1 */ #define FDCAN_RXF1S_F1GI_SHIFT FDCAN_RXFIFO_GI_SHIFT #define FDCAN_RXF1S_F1GI_MASK FDCAN_RXFIFO_GI_MASK -/* F1PI[1:1]: Put index of Rx FIFO 1 */ +/** F1PI[1:1]: Put index of Rx FIFO 1 */ #define FDCAN_RXF1S_F1PI_SHIFT FDCAN_RXFIFO_PI_SHIFT #define FDCAN_RXF1S_F1PI_MASK FDCAN_RXFIFO_PI_MASK #define FDCAN_RXF1S_F1F FDCAN_RXFIFO_FF #define FDCAN_RXF1S_RF1L FDCAN_RXFIFO_RFL -/* R1AI[2:0]: Rx FIFO 1 acknowledge index */ +/** R1AI[2:0]: Rx FIFO 1 acknowledge index */ #define FDCAN_RXF1A_R1AI_SHIFT FDCAN_RXFIFO_AI_SHIFT #define FDCAN_RXF1A_R1AI_MASK FDCAN_RXFIFO_AI_MASK #define FDCAN_TXBC_TFQM (1 << 24) -/* TFFL[2:0]: Tx FIFO free level */ +/** TFFL[2:0]: Tx FIFO free level */ #define FDCAN_TXFQS_TFFL_SHIFT 0 -/* TFGI[1:0]: Tx FIFO get index */ +/** TFGI[1:0]: Tx FIFO get index */ #define FDCAN_TXFQS_TFGI_SHIFT 8 -/* TFQPI[1:0]: Tx FIFO put index */ +/** TFQPI[1:0]: Tx FIFO put index */ #define FDCAN_TXFQS_TFQPI_SHIFT 16 #define FDCAN_TXFQS_TFQF (1 << 21) @@ -484,19 +484,19 @@ #define FDCAN_TXBCIE_CFIE2 (1 << 2) /**@}*/ -/* EFFL[2:0]: Event FIFO fill level*/ +/** EFFL[2:0]: Event FIFO fill level*/ #define FDCAN_TXEFS_EFFL_SHIFT 0 -/* EFG[1:0]: Event FIFO get index */ +/** EFG[1:0]: Event FIFO get index */ #define FDCAN_TXEFS_EFGI_SHIFT 8 -/* EFPI[1:0]: Event FIFO put index */ +/** EFPI[1:0]: Event FIFO put index */ #define FDCAN_TXEFS_EFPI_SHIFT 16 #define FDCAN_TXEFS_EFF (1 << 24) #define FDCAN_TXEFS_TEF (1 << 25) -/* EFAI[1:0]: Event FIFO acknowledge index */ +/** EFAI[1:0]: Event FIFO acknowledge index */ #define FDCAN_TXEFA_EFAI_SHIFT 0 #define FDCAN_TXEFA_EFAI_MASK 0x3 @@ -722,7 +722,6 @@ struct fdcan_tx_buffer_element { #define FDCAN_FIFO_RXTS_SHIFT 0 #define FDCAN_FIFO_RXTS_MASK 0xFFFF -/* --- FD-CAN error returns ------------------------------------------------- */ /** FDCAN error return values */ @@ -749,7 +748,6 @@ enum fdcan_error { /**@}*/ -/* --- FD-CAN functions ----------------------------------------------------- */ BEGIN_DECLS @@ -799,9 +797,11 @@ struct fdcan_extended_filter *fdcan_get_flesa_addr(uint32_t canport); struct fdcan_rx_fifo_element *fdcan_get_rxfifo_addr(uint32_t canport, unsigned fifo_id, unsigned element_id); +unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id); struct fdcan_tx_event_element *fdcan_get_txevt_addr(uint32_t canport); struct fdcan_tx_buffer_element *fdcan_get_txbuf_addr(uint32_t canport, unsigned element_id); +unsigned fdcan_get_txbuf_element_size(uint32_t canport); void fdcan_set_fifo_locked_mode(uint32_t canport, bool locked); uint32_t fdcan_length_to_dlc(uint8_t length); uint8_t fdcan_dlc_to_length(uint32_t dlc); diff --git a/include/libopencm3/stm32/g4/fdcan.h b/include/libopencm3/stm32/g4/fdcan.h index 4b94625b..d2aee962 100644 --- a/include/libopencm3/stm32/g4/fdcan.h +++ b/include/libopencm3/stm32/g4/fdcan.h @@ -63,21 +63,21 @@ LGPL License Terms @ref lgpl_license #define FDCAN_RXGFC_RRFE (1 << 0) #define FDCAN_RXGFC_RRFS (1 << 1) -/* ANFE[1:0]: Accept non-matching frames w/ extended ID */ +/** ANFE[1:0]: Accept non-matching frames w/ extended ID */ #define FDCAN_RXGFC_ANFE_SHIFT 2 #define FDCAN_RXGFC_ANFE_MASK 0x3 -/* ANFS[1:0]: Accept non-matching frames w/ standard ID */ +/** ANFS[1:0]: Accept non-matching frames w/ standard ID */ #define FDCAN_RXGFC_ANFS_SHIFT 4 #define FDCAN_RXGFC_ANFS_MASK 0x3 #define FDCAN_RXGFC_F1OM (1 << 8) #define FDCAN_RXGFC_F0OM (1 << 9) -/* LSS[4:0]: List size of standard ID filters */ +/** LSS[4:0]: List size of standard ID filters */ #define FDCAN_RXGFC_LSS_SHIFT 16 #define FDCAN_RXGFC_LSS_MASK 0x1F -/* LSE[3:0]: List size of extended ID filters */ +/** LSE[3:0]: List size of extended ID filters */ #define FDCAN_RXGFC_LSE_SHIFT 24 #define FDCAN_RXGFC_LSE_MASK 0xF @@ -124,9 +124,6 @@ LGPL License Terms @ref lgpl_license BEGIN_DECLS -unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id); -unsigned fdcan_get_txbuf_element_size(uint32_t canport); - END_DECLS - +/**@}*/ \ No newline at end of file diff --git a/include/libopencm3/stm32/h7/fdcan.h b/include/libopencm3/stm32/h7/fdcan.h index 0a5cbe7a..b2b2def2 100644 --- a/include/libopencm3/stm32/h7/fdcan.h +++ b/include/libopencm3/stm32/h7/fdcan.h @@ -104,49 +104,49 @@ LGPL License Terms @ref lgpl_license #define FDCAN_GFC_RRFE (1 << 0) #define FDCAN_GFC_RRFS (1 << 1) -/* ANFE[1:0]: Accept non-matching frames w/ extended ID */ +/** ANFE[1:0]: Accept non-matching frames w/ extended ID */ #define FDCAN_GFC_ANFE_SHIFT 2 #define FDCAN_GFC_ANFE_MASK 0x3 -/* ANFS[1:0]: Accept non-matching frames w/ standard ID */ +/** ANFS[1:0]: Accept non-matching frames w/ standard ID */ #define FDCAN_GFC_ANFS_SHIFT 4 #define FDCAN_GFC_ANFS_MASK 0x3 #define FDCAN_FXS_MASK 0xFF #define FDCAN_FXS_SHIFT 16 -/* Position of start address of relocatable object within register */ +/** Position of start address of relocatable object within register */ #define FDCAN_FXSA_MASK 0x3FFF #define FDCAN_FXSA_SHIFT 2 -/* LSS[7:0]: List size of standard ID filters */ +/** LSS[7:0]: List size of standard ID filters */ #define FDCAN_SIDFC_LSS_MASK FDCAN_FXS_MASK #define FDCAN_SIDFC_LSS_SHIFT FDCAN_FXS_SHIFT -/* LFSSA[13:0]: Filter List standard start address */ +/** LFSSA[13:0]: Filter List standard start address */ #define FDCAN_SIDFC_FLSSA_MASK FDCAN_FXSA_MASK #define FDCAN_SIDFC_FLSSA_SHIFT FDCAN_FXSA_SHIFT -/* LSE[7:0]: List size of extended ID filters */ +/** LSE[7:0]: List size of extended ID filters */ #define FDCAN_XIDFC_LSE_MASK FDCAN_FXS_MASK #define FDCAN_XIDFC_LSE_SHIFT FDCAN_FXS_SHIFT -/* LFSSA[7:0]: Filter List extended start address */ +/** LFSSA[7:0]: Filter List extended start address */ #define FDCAN_XIDFC_FLESA_MASK FDCAN_FXSA_MASK #define FDCAN_XIDFC_FLESA_SHIFT FDCAN_FXSA_SHIFT -/* TFQS[5:0]: Tx FIFO/Queue size */ +/** TFQS[5:0]: Tx FIFO/Queue size */ #define FDCAN_TXBC_TFQS_MASK 0x3F #define FDCAN_TXBC_TFQS_SHIFT 24 -/* TBSA[7:0]: Transmit buffer start address */ +/** TBSA[7:0]: Transmit buffer start address */ #define FDCAN_TXBC_TBSA_MASK FDCAN_FXSA_MASK #define FDCAN_TXBC_TBSA_SHIFT FDCAN_FXSA_SHIFT #define FDCAN_TXEFC_EFS_MASK 0x3F #define FDCAN_TXEFC_EFS_SHIFT 16 -/* EFSA[7:0]: (Transmit) event FIFO start address */ +/** EFSA[7:0]: (Transmit) event FIFO start address */ #define FDCAN_TXEFC_EFSA_MASK FDCAN_FXSA_MASK #define FDCAN_TXEFC_EFSA_SHIFT FDCAN_FXSA_SHIFT @@ -164,45 +164,45 @@ LGPL License Terms @ref lgpl_license #define FDCAN_RXF0C_F0OM FDCAN_RXFIC_FIOM -/* F0WM[6:0]: FIFO0 watermark mode */ +/** F0WM[6:0]: FIFO0 watermark mode */ #define FDCAN_RXF0C_F0WM_MASK FDCAN_RXFIC_FIWM_MASK #define FDCAN_RXF0C_F0WM_SHIFT FDCAN_RXFIC_FIWM_SHIFT -/* F0S[6:0]: FIFO0 size */ +/** F0S[6:0]: FIFO0 size */ #define FDCAN_RXF0C_F0S_MASK FDCAN_RXFIC_FIS_MASK #define FDCAN_RXF0C_F0S_SHIFT FDCAN_RXFIC_FIS_SHIFT -/* F0SA[13:0]: FIFO0 start address */ +/** F0SA[13:0]: FIFO0 start address */ #define FDCAN_RXF0C_F0SA_MASK FDCAN_RXFIC_FISA_MASK #define FDCAN_RXF0C_F0SA_SHIFT FDCAN_RXFIC_FISA_SHIFT #define FDCAN_RXF1C_F1OM FDCAN_RXFIC_FIOM -/* F1WM[6:0]: FIFO1 watermark mode */ +/** F1WM[6:0]: FIFO1 watermark mode */ #define FDCAN_RXF1C_F1WM_MASK FDCAN_RXFIC_FIWM_MASK #define FDCAN_RXF1C_F1WM_SHIFT FDCAN_RXFIC_FIWM_SHIFT -/* F1S[6:0]: FIFO1 size */ +/** F1S[6:0]: FIFO1 size */ #define FDCAN_RXF1C_F1S_MASK FDCAN_RXFIC_FIS_MASK #define FDCAN_RXF1C_F1S_SHIFT FDCAN_RXFIC_FIS_SHIFT -/* F1SA[13:0]: FIFO1 start address */ +/** F1SA[13:0]: FIFO1 start address */ #define FDCAN_RXF1C_F1SA_MASK FDCAN_RXFIC_FISA_MASK #define FDCAN_RXF1C_F1SA_SHIFT FDCAN_RXFIC_FISA_SHIFT -/* RBDS[3:0]: RX buffer data field size */ +/** RBDS[3:0]: RX buffer data field size */ #define FDCAN_RXESC_RBDS_MASK 0x7 #define FDCAN_RXESC_RBDS_SHIFT 8 -/* F0DS[3:0]: FIFO0 data field size */ +/** F0DS[3:0]: FIFO0 data field size */ #define FDCAN_RXESC_F0DS_MASK 0x7 #define FDCAN_RXESC_F0DS_SHIFT 0 -/* F1DS[3:0]: FIFO1 data field size */ +/** F1DS[3:0]: FIFO1 data field size */ #define FDCAN_RXESC_F1DS_MASK 0x7 #define FDCAN_RXESC_F1DS_SHIFT 4 -/* TBDS[3:0]: TX buffer data field size */ +/** TBDS[3:0]: TX buffer data field size */ #define FDCAN_TXESC_TBDS_MASK 0x7 #define FDCAN_TXESC_TBDS_SHIFT 0 @@ -220,7 +220,7 @@ LGPL License Terms @ref lgpl_license #define FDCAN_TXEFS_EFGI_MASK 0x1F #define FDCAN_TXEFS_EFPI_MASK 0x1F -/* PDIV[3:0]: Input clock divider */ +/** CDIV[3:0]: Input clock divider */ #define FDCAN_CCU_CCFG_CDIV_SHIFT 16 #define FDCAN_CCU_CCFG_CDIV_MASK 0xF @@ -248,10 +248,9 @@ void fdcan_init_ext_filter_ram(uint32_t canport, uint32_t flesa, uint8_t lse); void fdcan_init_fifo_ram(uint32_t canport, unsigned fifo_id, uint32_t fxsa, uint8_t fxs); void fdcan_init_tx_event_ram(uint32_t canport, uint32_t tesa, uint8_t tes); void fdcan_init_tx_buffer_ram(uint32_t canport, uint32_t tbsa, uint8_t tbs); -unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id); -unsigned fdcan_get_txbuf_element_size(uint32_t canport); int fdcan_set_rx_element_size(uint32_t canport, uint8_t rxbuf, uint8_t rxfifo0, uint8_t rxfifo1); int fdcan_set_tx_element_size(uint32_t canport, uint8_t txbuf); END_DECLS +/**@}*/ \ No newline at end of file diff --git a/lib/stm32/common/fdcan_common.c b/lib/stm32/common/fdcan_common.c index ef7eeab9..80245a0e 100644 --- a/lib/stm32/common/fdcan_common.c +++ b/lib/stm32/common/fdcan_common.c @@ -140,11 +140,12 @@ struct fdcan_extended_filter *fdcan_get_flesa_addr(uint32_t canport) return lfesa; } -/** Returns FIFO start address in message RAM +/** Returns a pointer to an RX FIFO element in message RAM * * @param [in] canport FDCAN block base address. See @ref fdcan_block. * @param [in] fifo_id ID of FIFO whose address is requested - * @returns Base address of FIFO block. + * @param [in] element_id the element number in the fifo we're requesting + * @returns a pointer to the individual element in the message ram */ struct fdcan_rx_fifo_element *fdcan_get_rxfifo_addr(uint32_t canport, unsigned fifo_id, unsigned element_id) @@ -168,10 +169,11 @@ struct fdcan_tx_event_element *fdcan_get_txevt_addr(uint32_t canport) return rxfifo; } -/** Returns transmit buffer start address in message RAM +/** Returns a pointer to an TX FIFO element in message RAM * * @param [in] canport FDCAN block base address. See @ref fdcan_block. - * @returns Base address of transmit buffer block. + * @param [in] element_id the element number in the fifo we're requesting + * @returns a pointer to the individual element in the message ram */ struct fdcan_tx_buffer_element *fdcan_get_txbuf_addr(uint32_t canport, unsigned element_id) { diff --git a/lib/stm32/g4/fdcan.c b/lib/stm32/g4/fdcan.c index b2193587..e9b05505 100644 --- a/lib/stm32/g4/fdcan.c +++ b/lib/stm32/g4/fdcan.c @@ -70,7 +70,6 @@ unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id) * as G4 has transmit buffer entries of fixed length. * * @param [in] canport FDCAN block base address. See @ref fdcan_block. Unused. - * @param [in] fifo_id ID of FIFO whole length is queried. Unused. * @returns Length of FIFO entry length covering frame header and frame payload. */ unsigned fdcan_get_txbuf_element_size(uint32_t canport) diff --git a/lib/stm32/h7/fdcan.c b/lib/stm32/h7/fdcan.c index fd0cad0e..d9a24cc4 100644 --- a/lib/stm32/h7/fdcan.c +++ b/lib/stm32/h7/fdcan.c @@ -89,7 +89,6 @@ unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id) * size. * * @param [in] canport FDCAN block base address. See @ref fdcan_block. - * @param [in] fifo_id ID of FIFO whole length is queried. * @returns Length of FIFO entry length covering frame header and frame payload. */ unsigned fdcan_get_txbuf_element_size(uint32_t canport) @@ -139,7 +138,7 @@ void fdcan_init_ext_filter_ram(uint32_t canport, uint32_t flesa, uint8_t lse) * @param [in] canport FDCAN block base address. See @ref fdcan_block. * @param [in] fifo_id ID of fifo being configured * @param [in] fxsa FIFO block start address offset in message RAM - * @param [in] fxs amount of entries allocated in FIFO + * @param [in] fxs number of elements to assign */ void fdcan_init_fifo_ram(uint32_t canport, unsigned fifo_id, uint32_t fxsa, uint8_t fxs) { @@ -158,9 +157,8 @@ void fdcan_init_fifo_ram(uint32_t canport, unsigned fifo_id, uint32_t fxsa, uint * base address within CAN message RAM. Note, that there are no limitations * nor checking on address provided. * @param [in] canport FDCAN block base address. See @ref fdcan_block. - * @param [in] fifo_id ID of fifo being configured - * @param [in] fxsa FIFO block start address offset in message RAM - * @param [in] fxs amount of entries allocated in FIFO + * @param [in] tesa block start address offset in message RAM + * @param [in] tes number of elements to assign */ void fdcan_init_tx_event_ram(uint32_t canport, uint32_t tesa, uint8_t tes) { @@ -179,9 +177,8 @@ void fdcan_init_tx_event_ram(uint32_t canport, uint32_t tesa, uint8_t tes) * base address within CAN message RAM. Note, that there are no limitations * nor checking on address provided. * @param [in] canport FDCAN block base address. See @ref fdcan_block. - * @param [in] fifo_id ID of fifo being configured - * @param [in] fxsa FIFO block start address offset in message RAM - * @param [in] fxs amount of entries allocated in FIFO + * @param [in] tbsa block start address offset in message RAM + * @param [in] tbs number of elements to assign */ void fdcan_init_tx_buffer_ram(uint32_t canport, uint32_t tbsa, uint8_t tbs) { @@ -471,3 +468,4 @@ void fdcan_set_fifo_locked_mode(uint32_t canport, bool locked) } } +/**@}*/ \ No newline at end of file From fe52fcdb1a3babc38ecbc8e2a463d7f98fab49e0 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Sat, 24 Apr 2021 19:09:33 +0200 Subject: [PATCH 098/206] stm32: Define FLASH_BASE and PERIPH_BASE for all families FLASH_BASE was already defined for some and PERIPH_BASE for all but one, but this makes these available for all families. Note that the value is identical for all familes (I doublechecked the more exotic ones such STM32H7), but it is still useful to have these defines to make code more readable and so that libopencm3 users can write portable code without having to check that these are identical on all STM32 families. --- include/libopencm3/stm32/f2/memorymap.h | 1 + include/libopencm3/stm32/f3/memorymap.h | 1 + include/libopencm3/stm32/f4/memorymap.h | 1 + include/libopencm3/stm32/f7/memorymap.h | 1 + include/libopencm3/stm32/g0/memorymap.h | 1 + include/libopencm3/stm32/g4/memorymap.h | 2 ++ include/libopencm3/stm32/h7/memorymap.h | 1 + include/libopencm3/stm32/l0/memorymap.h | 1 + include/libopencm3/stm32/l1/memorymap.h | 1 + include/libopencm3/stm32/l4/memorymap.h | 1 + 10 files changed, 11 insertions(+) diff --git a/include/libopencm3/stm32/f2/memorymap.h b/include/libopencm3/stm32/f2/memorymap.h index 4f47a32f..6cb0ca93 100644 --- a/include/libopencm3/stm32/f2/memorymap.h +++ b/include/libopencm3/stm32/f2/memorymap.h @@ -25,6 +25,7 @@ /* --- STM32F20x specific peripheral definitions --------------------------- */ /* Memory map for all busses */ +#define FLASH_BASE (0x08000000U) #define PERIPH_BASE (0x40000000U) #define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) #define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) diff --git a/include/libopencm3/stm32/f3/memorymap.h b/include/libopencm3/stm32/f3/memorymap.h index 877cd8dc..b9708272 100644 --- a/include/libopencm3/stm32/f3/memorymap.h +++ b/include/libopencm3/stm32/f3/memorymap.h @@ -27,6 +27,7 @@ /* --- STM32F3 specific peripheral definitions ----------------------------- */ /* Memory map for all busses */ +#define FLASH_BASE (0x08000000U) #define PERIPH_BASE (0x40000000U) #define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) #define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) diff --git a/include/libopencm3/stm32/f4/memorymap.h b/include/libopencm3/stm32/f4/memorymap.h index 6b96ac01..be78f548 100644 --- a/include/libopencm3/stm32/f4/memorymap.h +++ b/include/libopencm3/stm32/f4/memorymap.h @@ -25,6 +25,7 @@ /* --- STM32F4 specific peripheral definitions ----------------------------- */ /* Memory map for all busses */ +#define FLASH_BASE (0x08000000U) #define PERIPH_BASE (0x40000000U) #define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) #define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) diff --git a/include/libopencm3/stm32/f7/memorymap.h b/include/libopencm3/stm32/f7/memorymap.h index b7bd1be4..47663bae 100644 --- a/include/libopencm3/stm32/f7/memorymap.h +++ b/include/libopencm3/stm32/f7/memorymap.h @@ -23,6 +23,7 @@ /* --- STM32F7 specific peripheral definitions ----------------------------- */ /* Memory map for all busses */ +#define FLASH_BASE (0x08000000U) #define PERIPH_BASE (0x40000000U) #define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) #define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) diff --git a/include/libopencm3/stm32/g0/memorymap.h b/include/libopencm3/stm32/g0/memorymap.h index ebe342b7..1bf07989 100644 --- a/include/libopencm3/stm32/g0/memorymap.h +++ b/include/libopencm3/stm32/g0/memorymap.h @@ -20,6 +20,7 @@ #include +#define FLASH_BASE (0x08000000U) #define PERIPH_BASE (0x40000000U) #define IOPORT_BASE (0x50000000U) #define INFO_BASE (0x1fff7500U) diff --git a/include/libopencm3/stm32/g4/memorymap.h b/include/libopencm3/stm32/g4/memorymap.h index 56a16617..7da6e578 100644 --- a/include/libopencm3/stm32/g4/memorymap.h +++ b/include/libopencm3/stm32/g4/memorymap.h @@ -20,6 +20,8 @@ #include +#define FLASH_BASE (0x08000000U) +#define PERIPH_BASE (0x40000000U) #define INFO_BASE (0x1fff0000U) #define PERIPH_BASE_APB1 (0x40000000U) #define PERIPH_BASE_APB2 (0x40010000U) diff --git a/include/libopencm3/stm32/h7/memorymap.h b/include/libopencm3/stm32/h7/memorymap.h index 875b28e3..112b3bca 100644 --- a/include/libopencm3/stm32/h7/memorymap.h +++ b/include/libopencm3/stm32/h7/memorymap.h @@ -23,6 +23,7 @@ /* --- STM32H7 specific peripheral definitions ----------------------------- */ /* Memory map for all busses */ +#define FLASH_BASE 0x08000000U #define PERIPH_BASE 0x40000000U #define PERIPH_BASE_APB1 0x40000000U #define PERIPH_BASE_APB2 0x40010000U diff --git a/include/libopencm3/stm32/l0/memorymap.h b/include/libopencm3/stm32/l0/memorymap.h index e384c5c2..1bde26eb 100644 --- a/include/libopencm3/stm32/l0/memorymap.h +++ b/include/libopencm3/stm32/l0/memorymap.h @@ -23,6 +23,7 @@ /* --- STM32 specific peripheral definitions ------------------------------- */ /* Memory map for all busses */ +#define FLASH_BASE (0x08000000U) #define PERIPH_BASE (0x40000000U) #define IOPORT_BASE (0x50000000U) #define INFO_BASE (0x1ff80000U) diff --git a/include/libopencm3/stm32/l1/memorymap.h b/include/libopencm3/stm32/l1/memorymap.h index 88974e2b..15a0cc91 100644 --- a/include/libopencm3/stm32/l1/memorymap.h +++ b/include/libopencm3/stm32/l1/memorymap.h @@ -26,6 +26,7 @@ /* --- STM32 specific peripheral definitions ------------------------------- */ /* Memory map for all busses */ +#define FLASH_BASE (0x08000000U) #define PERIPH_BASE (0x40000000U) #define INFO_BASE (0x1ff00000U) #define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) diff --git a/include/libopencm3/stm32/l4/memorymap.h b/include/libopencm3/stm32/l4/memorymap.h index 5cd17ffd..c2ac47e1 100644 --- a/include/libopencm3/stm32/l4/memorymap.h +++ b/include/libopencm3/stm32/l4/memorymap.h @@ -23,6 +23,7 @@ /* --- STM32 specific peripheral definitions ------------------------------- */ /* Memory map for all busses */ +#define FLASH_BASE (0x08000000U) #define PERIPH_BASE (0x40000000U) #define FMC1_BANK_BASE (0x60000000U) #define FMC3_BANK_BASE (0x80000000U) From 4f71527881434a540c506e68b846dbd2728eec8e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 28 Apr 2021 10:34:47 +0000 Subject: [PATCH 099/206] stm32l0: add missing base addresses for usart4/5, gpioe Reported-by: massic@irc Fixes: 623fabca5fd when we initially added these extra periphs --- include/libopencm3/stm32/l0/gpio.h | 1 + include/libopencm3/stm32/l0/memorymap.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/libopencm3/stm32/l0/gpio.h b/include/libopencm3/stm32/l0/gpio.h index da2f420d..785116ae 100644 --- a/include/libopencm3/stm32/l0/gpio.h +++ b/include/libopencm3/stm32/l0/gpio.h @@ -46,6 +46,7 @@ #define GPIOB_BRR GPIO_BRR(GPIOB) #define GPIOC_BRR GPIO_BRR(GPIOC) #define GPIOD_BRR GPIO_BRR(GPIOD) +#define GPIOE_BRR GPIO_BRR(GPIOE) #define GPIOH_BRR GPIO_BRR(GPIOH) /*****************************************************************************/ diff --git a/include/libopencm3/stm32/l0/memorymap.h b/include/libopencm3/stm32/l0/memorymap.h index 1bde26eb..e9a775bf 100644 --- a/include/libopencm3/stm32/l0/memorymap.h +++ b/include/libopencm3/stm32/l0/memorymap.h @@ -45,6 +45,8 @@ #define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) #define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) #define LPUART1_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) @@ -80,6 +82,7 @@ #define GPIO_PORT_B_BASE (IOPORT_BASE + 0x00400) #define GPIO_PORT_C_BASE (IOPORT_BASE + 0x00800) #define GPIO_PORT_D_BASE (IOPORT_BASE + 0x00c00) +#define GPIO_PORT_E_BASE (IOPORT_BASE + 0x01000) #define GPIO_PORT_H_BASE (IOPORT_BASE + 0x01C00) /* Device Electronic Signature */ From 44928416eacb4c8d7774b1385c7f38fb226d080b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 28 Apr 2021 14:54:19 +0000 Subject: [PATCH 100/206] include: opencmsis: fix typo, add missing entries libopencmsis is effectively unmaintained, but we can fix little things I guess. Reported-by: https://github.com/libopencm3/libopencm3/pull/1332 --- include/libopencmsis/dispatch/irqhandlers.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/libopencmsis/dispatch/irqhandlers.h b/include/libopencmsis/dispatch/irqhandlers.h index e8ac859f..907b2474 100644 --- a/include/libopencmsis/dispatch/irqhandlers.h +++ b/include/libopencmsis/dispatch/irqhandlers.h @@ -17,7 +17,11 @@ #elif defined(STM32L4) # include #elif defined(STM32G0) -# include +# include +#elif defined(STM32G4) +# include +#elif defined(STM32H7) +# include #elif defined(GD32F1X0) # include From 777505a9b4b6984279a443bf5d7b8b332e4e1268 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 26 May 2021 09:56:22 +0000 Subject: [PATCH 101/206] stm32f3: rtc: fix missing top level include. Fixes: https://github.com/libopencm3/libopencm3/issues/1341 --- include/libopencm3/stm32/rtc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/libopencm3/stm32/rtc.h b/include/libopencm3/stm32/rtc.h index d6ab18a7..53118d3c 100644 --- a/include/libopencm3/stm32/rtc.h +++ b/include/libopencm3/stm32/rtc.h @@ -26,6 +26,8 @@ # include #elif defined(STM32F2) # include +#elif defined(STM32F3) +# include #elif defined(STM32F4) # include #elif defined(STM32L0) From 3b89fc5999874c49f6f5be65bbd5e75f7d77469c Mon Sep 17 00:00:00 2001 From: Piotr Esden-Tempski Date: Thu, 27 May 2021 15:50:45 -0700 Subject: [PATCH 102/206] Updated IRC channel info to libera.chat. The IRC channel moved networks to libera.chat. See you there! :) --- .travis.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7323ee10..376814fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,5 +13,5 @@ addons: notifications: irc: channels: - - "chat.freenode.net#libopencm3" + - "irc.libera.chat#libopencm3" use_notice: true diff --git a/README.md b/README.md index 6fbfbf9c..cbb5c9c3 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ Community --------- * Our [![Gitter channel](https://badges.gitter.im/libopencm3/discuss.svg)](https://gitter.im/libopencm3/discuss) - * Our IRC channel on the freenode IRC network is called #libopencm3 + * Our IRC channel on the libera.chat IRC network is called #libopencm3 Mailing lists ------------- From 1033131eb76f7694e5a490600624b64c4725551a Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Tue, 11 May 2021 11:41:30 +0200 Subject: [PATCH 103/206] Fix #1328: Make error return codes negative values Fix the bug where certain functions were returning meaningful return and/or error code, where positive values of error codes were interfering with meaningful return value. Error codes now have negative values as it was originally intended but never implemented. --- include/libopencm3/stm32/fdcan.h | 34 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/include/libopencm3/stm32/fdcan.h b/include/libopencm3/stm32/fdcan.h index 8b68a163..96c6432f 100644 --- a/include/libopencm3/stm32/fdcan.h +++ b/include/libopencm3/stm32/fdcan.h @@ -723,28 +723,30 @@ struct fdcan_tx_buffer_element { #define FDCAN_FIFO_RXTS_MASK 0xFFFF -/** FDCAN error return values +/** @defgroup fdcan_error FDCAN error return values + * @{ */ -enum fdcan_error { - /** No error. Operation finished successfully */ - FDCAN_E_OK, - /** Value provided was out of range */ - FDCAN_E_OUTOFRANGE, +/** No error. Operation finished successfully */ +#define FDCAN_E_OK 0 - /** Timeout waiting for FDCAN block to accept INIT bit change */ - FDCAN_E_TIMEOUT, +/** Value provided was out of range */ +#define FDCAN_E_OUTOFRANGE -1 - /** Value provided was invalid (FIFO index, FDCAN block base address, length, etc.) */ - FDCAN_E_INVALID, +/** Timeout waiting for FDCAN block to accept INIT bit change */ +#define FDCAN_E_TIMEOUT -2 - /** Device is busy: Transmit buffer is full, unable to queue additional message or device - * is outside of INIT mode and cannot perform desired operation. */ - FDCAN_E_BUSY, +/** Value provided was invalid (FIFO index, FDCAN block base address, length, etc.) */ +#define FDCAN_E_INVALID -3 - /** Receive buffer is empty, unable to read any new message */ - FDCAN_E_NOTAVAIL -}; +/** Device is busy: Transmit buffer is full, unable to queue additional message or device + * is outside of INIT mode and cannot perform desired operation. */ +#define FDCAN_E_BUSY -4 + +/** Receive buffer is empty, unable to read any new message */ +#define FDCAN_E_NOTAVAIL -5 + +/**@}*/ /**@}*/ From 9478931d69ee3921ed86b87873057e71a70b3d96 Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Wed, 12 May 2021 11:10:23 +0200 Subject: [PATCH 104/206] Fix FDCAN incorrect FIFO acknowledgment Fix incorrect way of acknowledging FIFO processing. Old code ORed old value of register with index of FIFO buffer just processed, which generated invalid value for acknowledge. This caused FIFO to repeatedly returning same content. Both fdcan_receive() and fdcan_release_fifo were affected. --- lib/stm32/common/fdcan_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stm32/common/fdcan_common.c b/lib/stm32/common/fdcan_common.c index 80245a0e..be582e82 100644 --- a/lib/stm32/common/fdcan_common.c +++ b/lib/stm32/common/fdcan_common.c @@ -609,7 +609,7 @@ int fdcan_receive(uint32_t canport, uint8_t fifo_id, bool release, uint32_t *id, } if (release) { - FDCAN_RXFIA(canport, fifo_id) |= get_index << FDCAN_RXFIFO_AI_SHIFT; + FDCAN_RXFIA(canport, fifo_id) = get_index << FDCAN_RXFIFO_AI_SHIFT; } return FDCAN_E_OK; From e9c68ff9e817ecc735c7b19ec939168359cc2db0 Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Tue, 18 May 2021 15:34:04 +0200 Subject: [PATCH 105/206] Fix STM32H7 FDCAN FIFO acknowledgment process Fix FDCAN FIFO acknowledge register definition to make it correct for H7 MCUs. Previous definition contained hardcoded offset instead of using MCU-specific macro. Fix incorrect decoding of buffer element size. During decoding, value returned was erratically set to 7 instead of setting 4th LSB. Buffer element size was then always reported as 15 bytes. --- include/libopencm3/stm32/fdcan.h | 4 +++- lib/stm32/h7/fdcan.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/libopencm3/stm32/fdcan.h b/include/libopencm3/stm32/fdcan.h index 96c6432f..b724fbd2 100644 --- a/include/libopencm3/stm32/fdcan.h +++ b/include/libopencm3/stm32/fdcan.h @@ -78,7 +78,9 @@ * @param can_base FDCAN block base address @ref fdcan_block * @param fifo_id ID of FIFO, 0 or 1 */ -#define FDCAN_RXFIA(can_base, fifo_id) MMIO32(can_base + 0x0094 + (FDCAN_RXFI_OFFSET * fifo_id)) +#define FDCAN_RXFIA(can_base, fifo_id) \ + MMIO32(can_base + FDCAN_RXFIA_BASE + (FDCAN_RXFI_OFFSET * fifo_id)) + #define FDCAN_RXF0A(can_base) FDCAN_RXFIA(can_base, 0) #define FDCAN_RXF1A(can_base) FDCAN_RXFIA(can_base, 1) diff --git a/lib/stm32/h7/fdcan.c b/lib/stm32/h7/fdcan.c index d9a24cc4..eb428777 100644 --- a/lib/stm32/h7/fdcan.c +++ b/lib/stm32/h7/fdcan.c @@ -79,7 +79,7 @@ unsigned fdcan_get_fifo_element_size(uint32_t canport, unsigned fifo_id) } /* Mask is unshifted and at this point, element_size is unshifted too */ - return 8 + fdcan_dlc_to_length((element_size & FDCAN_RXESC_F0DS_MASK) | 0x7); + return 8 + fdcan_dlc_to_length((element_size & FDCAN_RXESC_F0DS_MASK) | 0x8); } /** Returns actual size of transmit entry in transmit queue/FIFO for given CAN port. @@ -95,7 +95,7 @@ unsigned fdcan_get_txbuf_element_size(uint32_t canport) { unsigned element_size; element_size = (FDCAN_TXESC(canport) >> FDCAN_TXESC_TBDS_SHIFT) & FDCAN_TXESC_TBDS_MASK; - return 8 + fdcan_dlc_to_length((element_size & FDCAN_TXESC_TBDS_MASK) | 0x7); + return 8 + fdcan_dlc_to_length((element_size & FDCAN_TXESC_TBDS_MASK) | 0x8); } /** Initialize allocation of standard filter block in CAN message RAM. @@ -468,4 +468,4 @@ void fdcan_set_fifo_locked_mode(uint32_t canport, bool locked) } } -/**@}*/ \ No newline at end of file +/**@}*/ From 3ab83bc07869dbb3291a721fdb9dc2b1c64a0ddf Mon Sep 17 00:00:00 2001 From: Stephen Holdaway Date: Tue, 29 Jun 2021 23:40:23 +1200 Subject: [PATCH 106/206] stm32g0: Support DAC Nothing extra needed to be defined here - this might've just been missed when adding STM32G0 support. Tested and works well on an STM32G051. Registers in `stm32/common/dac_common_v1.h` match the STM32G0x1 reference manual. --- include/libopencm3/stm32/dac.h | 2 ++ include/libopencm3/stm32/g0/dac.h | 41 +++++++++++++++++++++++++++++++ lib/stm32/g0/Makefile | 1 + 3 files changed, 44 insertions(+) create mode 100644 include/libopencm3/stm32/g0/dac.h diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h index a3efb12e..dacb7dfa 100644 --- a/include/libopencm3/stm32/dac.h +++ b/include/libopencm3/stm32/dac.h @@ -36,6 +36,8 @@ # include #elif defined(STM32L4) # include +#elif defined(STM32G0) +# include #elif defined(STM32G4) # include #elif defined(STM32H7) diff --git a/include/libopencm3/stm32/g0/dac.h b/include/libopencm3/stm32/g0/dac.h new file mode 100644 index 00000000..1726d4ad --- /dev/null +++ b/include/libopencm3/stm32/g0/dac.h @@ -0,0 +1,41 @@ +/** @defgroup dac_defines DAC Defines + * + * @brief Defined Constants and Types for the STM32G0xx Digital-to-Analog Converter + * + * @ingroup STM32G0xx_defines + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DAC_H +#define LIBOPENCM3_DAC_H + +#include + +/**@{*/ + +/** @defgroup dac_reg_base DAC register base addresses +@{*/ +#define DAC1 DAC_BASE +/**@}*/ + +/**@}*/ + +#endif + diff --git a/lib/stm32/g0/Makefile b/lib/stm32/g0/Makefile index b302aeea..710f379c 100644 --- a/lib/stm32/g0/Makefile +++ b/lib/stm32/g0/Makefile @@ -35,6 +35,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs OBJS += adc.o adc_common_v2.o OBJS += crc_common_all.o +OBJS += dac_common_all.o dac_common_v1.o OBJS += desig_common_all.o desig_common_v1.o OBJS += dma_common_l1f013.o OBJS += dmamux.o From 6f9f40a7e4f6c072940da1f52d498d998341cdf5 Mon Sep 17 00:00:00 2001 From: Stephen Holdaway Date: Tue, 29 Jun 2021 23:48:44 +1200 Subject: [PATCH 107/206] devices.data: add STM32G05x and STM32G06x parts with 18K RAM --- ld/devices.data | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ld/devices.data b/ld/devices.data index 12c61fff..ae54efec 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -243,6 +243,8 @@ stm32w108cc stm32w ROM=256K RAM=16K stm32g0[43]1?4* stm32g0 ROM=16K RAM=8K stm32g0[43][01]?6* stm32g0 ROM=32K RAM=8K stm32g0[43][01]?8* stm32g0 ROM=64K RAM=8K +stm32g0[56][01]?6* stm32g0 ROM=32K RAM=18K +stm32g0[56][01]?8* stm32g0 ROM=64K RAM=18K stm32g0[78]1?8* stm32g0 ROM=64K RAM=36K stm32g0[78][01]?b* stm32g0 ROM=128K RAM=36K stm32g0[BC]1?c* stm32g0 ROM=256K RAM=128K From 12da5bbd9e7a2fbd6a5728f58b526b5348eeb467 Mon Sep 17 00:00:00 2001 From: weycen76 <22557692+weycen76@users.noreply.github.com> Date: Fri, 30 Apr 2021 20:33:47 +0800 Subject: [PATCH 108/206] stm32:iwdg: reset counter after changing period. Fix the bug that the iwdg counter is not refreshed after the configurationis complete, if this counter is not refreshed after the configuration is completed, the first iwdg counting period will be as long as 26 seconds. Fixes: https://github.com/libopencm3/libopencm3/pull/1333 Reviewed-by: Karl Palsson --- lib/stm32/common/iwdg_common_all.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/stm32/common/iwdg_common_all.c b/lib/stm32/common/iwdg_common_all.c index 44b3b9b3..84268ef9 100644 --- a/lib/stm32/common/iwdg_common_all.c +++ b/lib/stm32/common/iwdg_common_all.c @@ -108,6 +108,9 @@ void iwdg_set_period_ms(uint32_t period) while (iwdg_reload_busy()); IWDG_KR = IWDG_KR_UNLOCK; IWDG_RLR = count & COUNT_MASK; + + /* Refresh counter after configuration is complete */ + iwdg_reset(); } /*---------------------------------------------------------------------------*/ From eb52a1a1fb7ad26fbcfb2ba9126cf47e8da46423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20L=C3=B6vqvist?= Date: Sat, 10 Jul 2021 21:46:14 +0200 Subject: [PATCH 109/206] stm32f1: gpio: Fixed misleading comments on AFIO remaps Added some explantory text to some of the remap options. --- include/libopencm3/stm32/f1/gpio.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/include/libopencm3/stm32/f1/gpio.h b/include/libopencm3/stm32/f1/gpio.h index e8b42506..1db76431 100644 --- a/include/libopencm3/stm32/f1/gpio.h +++ b/include/libopencm3/stm32/f1/gpio.h @@ -916,7 +916,16 @@ Line Devices only /** TIM9 remapping */ #define AFIO_MAPR2_TIM9_REMAP (1 << 5) -/** TIM1_DMA channel 1/2 remapping */ +/** TIM1_DMA channel remapping */ +/* +0: + TIM1_CH1 DMA - DMA1 Channel 2 + TIM1_CH2 DMA - DMA1 CHannel 3 +1: + TIM1_CH1 DMA - DMA1 Channel 6 + TIM1_CH2 DMA - DMA1 Channel 6 + +*/ #define AFIO_MAPR2_TIM1_DMA_REMAP (1 << 4) /** CEC remapping (PB8 vs PB10) */ @@ -925,11 +934,11 @@ Line Devices only /** TIM17 remapping (PB9 vs PB7) */ #define AFIO_MAPR2_TIM17_REMAP (1 << 2) -/** TIM16 remapping (PB8 vs PB6) */ +/** TIM16 remapping (PB8 vs PA6) */ #define AFIO_MAPR2_TIM16_REMAP (1 << 1) -/** TIM15 remapping channels 1/2 */ -#define AFIO_MAPR1_TIM16_REMAP (1 << 0) +/** TIM15 remapping (PA2, PA3 vs PB14, PB15) */ +#define AFIO_MAPR2_TIM15_REMAP (1 << 0) /**@}*/ From 2483e2e358f1a0d6526c63aa0b5ef2dd3358039e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 17 Jul 2021 23:04:53 +0000 Subject: [PATCH 110/206] stm32f1:gpio: docs: clarify more AF remaps --- include/libopencm3/stm32/f1/gpio.h | 37 +++++++++++------------------- 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/include/libopencm3/stm32/f1/gpio.h b/include/libopencm3/stm32/f1/gpio.h index 1db76431..4e997e03 100644 --- a/include/libopencm3/stm32/f1/gpio.h +++ b/include/libopencm3/stm32/f1/gpio.h @@ -896,48 +896,37 @@ Line Devices only /** The NADV is disconnected from its allocated pin */ #define AFIO_MAPR2_FSMC_NADV_DISCONNECT (1 << 10) -/* TIM14_REMAP: */ -/** TIM14 remapping */ +/** TIM14 CH1 remapping (Clear: PA7 vs Set: PF9 */ #define AFIO_MAPR2_TIM14_REMAP (1 << 9) -/* TIM13_REMAP: */ -/** TIM13 remapping */ +/** TIM13 CH1 remapping (Clear: PA6 vs Set: PF8 */ #define AFIO_MAPR2_TIM13_REMAP (1 << 8) -/* TIM11_REMAP: */ -/** TIM11 remapping */ +/** TIM11 CH1 remapping (Clear: PB7 vs Set: PF7 */ #define AFIO_MAPR2_TIM11_REMAP (1 << 7) -/* TIM10_REMAP: */ -/** TIM10 remapping */ +/** TIM10 CH1 remapping (Clear: PB8 vs Set: PF6 */ #define AFIO_MAPR2_TIM10_REMAP (1 << 6) -/* TIM9_REMAP: */ -/** TIM9 remapping */ +/** TIM9 Ch1/2 remapping (Clear: PA2,PA3 vs Set: PE5,PE6 */ #define AFIO_MAPR2_TIM9_REMAP (1 << 5) -/** TIM1_DMA channel remapping */ -/* -0: - TIM1_CH1 DMA - DMA1 Channel 2 - TIM1_CH2 DMA - DMA1 CHannel 3 -1: - TIM1_CH1 DMA - DMA1 Channel 6 - TIM1_CH2 DMA - DMA1 Channel 6 - -*/ +/** TIM1_DMA channel remapping + * Clear: CH1->DMA1-ch2, CH2->DM1-ch3 + * Set: CH1->DMA1-ch6, CH2->DMA1-ch6 + */ #define AFIO_MAPR2_TIM1_DMA_REMAP (1 << 4) -/** CEC remapping (PB8 vs PB10) */ +/** CEC remapping (Clear: PB8 vs Set: PB10) */ #define AFIO_MAPR2_CEC_REMAP (1 << 3) -/** TIM17 remapping (PB9 vs PB7) */ +/** TIM17 remapping (Clear: PB9 vs Set: PB7) */ #define AFIO_MAPR2_TIM17_REMAP (1 << 2) -/** TIM16 remapping (PB8 vs PA6) */ +/** TIM16 remapping (Clear: PB8 vs Set: PA6) */ #define AFIO_MAPR2_TIM16_REMAP (1 << 1) -/** TIM15 remapping (PA2, PA3 vs PB14, PB15) */ +/** TIM15 remapping (Clear: PA2, PA3 vs Set: PB14, PB15) */ #define AFIO_MAPR2_TIM15_REMAP (1 << 0) /**@}*/ From 470a1394a838fe308d886f6880b7054bab4aa5eb Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 31 Jul 2021 21:45:53 +0000 Subject: [PATCH 111/206] doc: stm32: timer: switch f1/other example Reported in: https://github.com/libopencm3/libopencm3/issues/1353 Fixes: d8d63b3184 (wrongly assumed existing example was for f1) Signed-off-by: Karl Palsson --- lib/stm32/common/timer_common_all.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/stm32/common/timer_common_all.c b/lib/stm32/common/timer_common_all.c index 30671ad1..285f8bcf 100644 --- a/lib/stm32/common/timer_common_all.c +++ b/lib/stm32/common/timer_common_all.c @@ -52,10 +52,10 @@ alternate function push-pull output where the PWM output will appear. rcc_periph_clock_enable(RCC_GPIOA); // for F1.... - gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO8); - // For anyone else rcc_periph_clock_enable(RCC_AFIO); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8); + // For anyone else + gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO8); // End of family specific rcc_periph_clock_enable(RCC_TIM1); From 6763681c260cf280487d70ca0d1996a8b79fff30 Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Sat, 17 Jul 2021 19:07:47 -0400 Subject: [PATCH 112/206] STM32: Fixed ltdc_setup_windowing helper --- .../libopencm3/stm32/common/ltdc_common_f47.h | 9 ++++- lib/stm32/common/ltdc_common_f47.c | 33 +++++++++++-------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/include/libopencm3/stm32/common/ltdc_common_f47.h b/include/libopencm3/stm32/common/ltdc_common_f47.h index d938d6cc..4ac58098 100644 --- a/include/libopencm3/stm32/common/ltdc_common_f47.h +++ b/include/libopencm3/stm32/common/ltdc_common_f47.h @@ -109,9 +109,15 @@ #define LTDC_L1CLUTWR LTDC_LxCLUTWR(LTDC_LAYER_1) #define LTDC_L2CLUTWR LTDC_LxCLUTWR(LTDC_LAYER_2) +/* LTDC layer base addresses (for API parameters) */ +/** @defgroup ltdc_layer_num LTDC Layer Number +@ingroup STM32F4xx_ltdc_defines +@{*/ #define LTDC_LAYER_1 1 #define LTDC_LAYER_2 2 +/**@}*/ + /* --- LTDC_SSCR values ---------------------------------------------------- */ @@ -500,7 +506,8 @@ void ltdc_set_tft_sync_timings( void ltdc_setup_windowing( uint8_t layer_number, uint16_t h_back_porch, uint16_t v_back_porch, - uint16_t active_width, uint16_t active_height + uint16_t h_sync, uint16_t v_sync, + uint16_t width, uint16_t height ); diff --git a/lib/stm32/common/ltdc_common_f47.c b/lib/stm32/common/ltdc_common_f47.c index 3255f356..4ea9f216 100644 --- a/lib/stm32/common/ltdc_common_f47.c +++ b/lib/stm32/common/ltdc_common_f47.c @@ -67,20 +67,25 @@ void ltdc_set_tft_sync_timings(uint16_t sync_width, uint16_t sync_height, LTDC_TWCR = (w << 16) | (h << 0); } -void ltdc_setup_windowing(uint8_t layer_number, - uint16_t h_back_porch, uint16_t v_back_porch, - uint16_t active_width, uint16_t active_height) -{ - active_width += h_back_porch - 1; - active_height += v_back_porch - 1; - /*assert((h_back_porch & 0xfff == h_back_porch) && - (v_back_porch & 0xfff == v_back_porch) && - (active_width & 0xfff == active_width) && - (active_height & 0xfff == active_height));*/ - LTDC_LxWHPCR(layer_number) = (active_width << 16) | - (h_back_porch << 0); - LTDC_LxWVPCR(layer_number) = (active_height << 16) | - (v_back_porch << 0); +/*---------------------------------------------------------------------------*/ +/** @brief LTDC Windowing Setup +@param[in] layer_number unsigned int8. @ref ltdc_layer_num +@param[in] h_back_porch unsigned int16. Horizontal Back Porch +@param[in] v_back_porch unsigned int16. Vertical Back Porch +@param[in] h_sync unsigned int16. Horizontal Sync +@param[in] v_sync unsigned int16. Vertical Sync +@param[in] width unsigned int16. Width of the screen (e.g. LCD is 320x240, width +would be 320) +@param[in] height unsigned int16. Height of the screen (e.g. LCD is 320x240, +height would be 240) +*/ +void ltdc_setup_windowing(uint8_t layer_number, uint16_t h_back_porch, + uint16_t v_back_porch, uint16_t h_sync, + uint16_t v_sync, uint16_t width, uint16_t height) { + LTDC_LxWHPCR(layer_number) = (h_back_porch + width + h_sync - 1) << LTDC_LxWHPCR_WHSPPOS_SHIFT | + (h_sync + h_back_porch) << LTDC_LxWHPCR_WHSTPOS_SHIFT; + LTDC_LxWVPCR(layer_number) = (v_back_porch + height + v_sync - 1) << LTDC_LxWVPCR_WVSPPOS_SHIFT | + (v_back_porch + v_sync) << LTDC_LxWVPCR_WVSTPOS_SHIFT; } /**@}*/ From f5813a547a48802c55e6a8fa93b48b44c0a7d269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20B=C3=B8rresen?= Date: Sat, 25 Sep 2021 12:54:50 +0200 Subject: [PATCH 113/206] stm32f4: rcc: F411: support Full speed with usb. F411 parts, found on "black pill" boards support 100MHz operation, but only 96MHz with USB. Provide default clock structures for this common max speed. Reviewed-by: Karl Palsson --- include/libopencm3/stm32/f4/rcc.h | 1 + lib/stm32/f4/rcc.c | 80 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/include/libopencm3/stm32/f4/rcc.h b/include/libopencm3/stm32/f4/rcc.h index 977cd38a..b2f6fb30 100644 --- a/include/libopencm3/stm32/f4/rcc.h +++ b/include/libopencm3/stm32/f4/rcc.h @@ -796,6 +796,7 @@ extern uint32_t rcc_apb2_frequency; enum rcc_clock_3v3 { RCC_CLOCK_3V3_84MHZ, + RCC_CLOCK_3V3_96MHZ, RCC_CLOCK_3V3_168MHZ, RCC_CLOCK_3V3_180MHZ, RCC_CLOCK_3V3_END diff --git a/lib/stm32/f4/rcc.c b/lib/stm32/f4/rcc.c index 6b4da4ac..99c77fa7 100644 --- a/lib/stm32/f4/rcc.c +++ b/lib/stm32/f4/rcc.c @@ -67,6 +67,22 @@ const struct rcc_clock_scale rcc_hsi_configs[RCC_CLOCK_3V3_END] = { .apb1_frequency = 42000000, .apb2_frequency = 84000000, }, + { /* 96MHz */ + .pllm = 8, + .plln = 96, + .pllp = 2, + .pllq = 4, + .pllr = 0, + .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 96000000, + .apb1_frequency = 48000000, + .apb2_frequency = 96000000 + }, { /* 168MHz */ .pllm = 16, .plln = 336, @@ -121,6 +137,22 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .apb1_frequency = 42000000, .apb2_frequency = 84000000, }, + { /* 96MHz */ + .pllm = 4, + .plln = 96, + .pllp = 2, + .pllq = 4, + .pllr = 0, + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 96000000, + .apb1_frequency = 48000000, + .apb2_frequency = 96000000 + }, { /* 168MHz */ .pllm = 8, .plln = 336, @@ -175,6 +207,22 @@ const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { .apb1_frequency = 42000000, .apb2_frequency = 84000000, }, + { /* 96MHz */ + .pllm = 6, + .plln = 96, + .pllp = 2, + .pllq = 4, + .pllr = 0, + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 96000000, + .apb1_frequency = 48000000, + .apb2_frequency = 96000000 + }, { /* 168MHz */ .pllm = 12, .plln = 336, @@ -229,6 +277,22 @@ const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { .apb1_frequency = 42000000, .apb2_frequency = 84000000, }, + { /* 96MHz */ + .pllm = 8, + .plln = 96, + .pllp = 2, + .pllq = 4, + .pllr = 0, + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 96000000, + .apb1_frequency = 48000000, + .apb2_frequency = 96000000 + }, { /* 168MHz */ .pllm = 16, .plln = 336, @@ -283,6 +347,22 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { .apb1_frequency = 42000000, .apb2_frequency = 84000000, }, + { /* 96MHz */ + .pllm = 25, + .plln = 192, + .pllp = 2, + .pllq = 4, + .pllr = 0, + .pll_source = RCC_CFGR_PLLSRC_HSE_CLK, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_2, + .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, + .ahb_frequency = 96000000, + .apb1_frequency = 48000000, + .apb2_frequency = 96000000 + }, { /* 168MHz */ .pllm = 25, .plln = 336, From 9fb39ed743a259792903c98ccc45504b4d7b5b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luna=20Gr=C3=A4fje?= Date: Wed, 3 Nov 2021 16:04:29 +0100 Subject: [PATCH 114/206] stm32l4: define CAN2 address and RCC bits --- include/libopencm3/stm32/l4/memorymap.h | 1 + include/libopencm3/stm32/l4/rcc.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/libopencm3/stm32/l4/memorymap.h b/include/libopencm3/stm32/l4/memorymap.h index c2ac47e1..c087e5b5 100644 --- a/include/libopencm3/stm32/l4/memorymap.h +++ b/include/libopencm3/stm32/l4/memorymap.h @@ -59,6 +59,7 @@ #define I2C3_BASE (PERIPH_BASE_APB1 + 0x5c00) #define CRS_BASE (PERIPH_BASE_APB1 + 0x6000) #define BX_CAN1_BASE (PERIPH_BASE_APB1 + 0x6400) +#define BX_CAN2_BASE (PERIPH_BASE_APB1 + 0x6800) #define USB_DEV_FS_BASE (PERIPH_BASE_APB1 + 0x6800) #define USB_PMA_BASE (PERIPH_BASE_APB1 + 0x6c00) #define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) diff --git a/include/libopencm3/stm32/l4/rcc.h b/include/libopencm3/stm32/l4/rcc.h index 09edc71e..a2bf7559 100644 --- a/include/libopencm3/stm32/l4/rcc.h +++ b/include/libopencm3/stm32/l4/rcc.h @@ -363,6 +363,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_APB1RSTR1_OPAMPRST (1 << 30) #define RCC_APB1RSTR1_DAC1RST (1 << 29) #define RCC_APB1RSTR1_PWRRST (1 << 28) +#define RCC_APB1RSTR1_CAN2RST (1 << 26) #define RCC_APB1RSTR1_CAN1RST (1 << 25) #define RCC_APB1RSTR1_I2C3RST (1 << 23) #define RCC_APB1RSTR1_I2C2RST (1 << 22) @@ -466,6 +467,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_APB1ENR1_OPAMPEN (1 << 30) #define RCC_APB1ENR1_DAC1EN (1 << 29) #define RCC_APB1ENR1_PWREN (1 << 28) +#define RCC_APB1ENR1_CAN2EN (1 << 26) #define RCC_APB1ENR1_CAN1EN (1 << 25) #define RCC_APB1ENR1_I2C3EN (1 << 23) #define RCC_APB1ENR1_I2C2EN (1 << 22) @@ -554,6 +556,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_APB1SMENR1_OPAMPSMEN (1 << 30) #define RCC_APB1SMENR1_DAC1SMEN (1 << 29) #define RCC_APB1SMENR1_PWRSMEN (1 << 28) +#define RCC_APB1SMENR1_CAN2SMEN (1 << 26) #define RCC_APB1SMENR1_CAN1SMEN (1 << 25) #define RCC_APB1SMENR1_I2C3SMEN (1 << 23) #define RCC_APB1SMENR1_I2C2SMEN (1 << 22) @@ -778,6 +781,7 @@ enum rcc_periph_clken { RCC_DAC1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 29), RCC_PWR = _REG_BIT(RCC_APB1ENR1_OFFSET, 28), RCC_USB = _REG_BIT(RCC_APB1ENR1_OFFSET, 26), + RCC_CAN2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 26), RCC_CAN1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 25), RCC_CRS = _REG_BIT(RCC_APB1ENR1_OFFSET, 24), RCC_I2C3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 23), @@ -849,6 +853,7 @@ enum rcc_periph_clken { SCC_OPAMP = _REG_BIT(RCC_APB1ENR1_OFFSET, 30), SCC_DAC1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 29), SCC_PWR = _REG_BIT(RCC_APB1ENR1_OFFSET, 28), + SCC_CAN2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 26), SCC_CAN1 = _REG_BIT(RCC_APB1ENR1_OFFSET, 25), SCC_I2C3 = _REG_BIT(RCC_APB1ENR1_OFFSET, 23), SCC_I2C2 = _REG_BIT(RCC_APB1ENR1_OFFSET, 22), @@ -920,6 +925,7 @@ enum rcc_periph_rst { RST_DAC1 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 29), RST_PWR = _REG_BIT(RCC_APB1RSTR1_OFFSET, 28), RST_USB = _REG_BIT(RCC_APB1RSTR1_OFFSET, 26), + RST_CAN2 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 26), RST_CAN1 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 25), RST_CRS = _REG_BIT(RCC_APB1RSTR1_OFFSET, 24), RST_I2C3 = _REG_BIT(RCC_APB1RSTR1_OFFSET, 23), From 474ca02a60301b6ed20ab4f395878536259de681 Mon Sep 17 00:00:00 2001 From: Chris Chronopoulos Date: Tue, 9 Nov 2021 00:25:20 -0800 Subject: [PATCH 115/206] devices.data: add samd09?13* and samd21?18* --- ld/devices.data | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ld/devices.data b/ld/devices.data index ae54efec..10441320 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -286,9 +286,13 @@ sam3x4e* sam3xnfc ROM=256K RAM=32K RAM1=32K sam3x8c* sam3x ROM=512K RAM=64K RAM1=32K sam3x8e* sam3xnfc ROM=512K RAM=64K RAM1=32K +samd09?13* samd ROM=8K RAM=4K + samd10?13* samd ROM=8K RAM=4K samd10?14* samd ROM=16K RAM=4K +samd21?18* samd ROM=256K RAM=32K + ################################################################################ # the SAM4 chips From aab1a67344dd5c0b1559684c72b8952341cb625a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 9 Nov 2021 10:12:53 +0000 Subject: [PATCH 116/206] devices.data: add more samd10 / samd20 / samd21 devices Fill out the product lines more fully. --- ld/devices.data | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ld/devices.data b/ld/devices.data index 10441320..e9f04264 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -287,11 +287,16 @@ sam3x8c* sam3x ROM=512K RAM=64K RAM1=32K sam3x8e* sam3xnfc ROM=512K RAM=64K RAM1=32K samd09?13* samd ROM=8K RAM=4K +samd09?14* samd ROM=16K RAM=4K samd10?13* samd ROM=8K RAM=4K -samd10?14* samd ROM=16K RAM=4K +samd1[01]?14* samd ROM=16K RAM=4K -samd21?18* samd ROM=256K RAM=32K +samd2[01]?14* samd ROM=16K RAM=2K +samd2[01]?15* samd ROM=32K RAM=4K +samd2[01]?16* samd ROM=64K RAM=8K +samd2[01]?17* samd ROM=128K RAM=16K +samd2[01]?18* samd ROM=256K RAM=32K ################################################################################ # the SAM4 chips From 3e480eecaeaa013bf329231543fa729d61d57484 Mon Sep 17 00:00:00 2001 From: Dima Barsky Date: Wed, 10 Nov 2021 16:08:20 +0000 Subject: [PATCH 117/206] stm32f4: pwr: add missing bits Extra bits have these names per RM0430 at least. Reviewed-by: Karl Palsson --- include/libopencm3/stm32/f4/pwr.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/f4/pwr.h b/include/libopencm3/stm32/f4/pwr.h index 63f1015f..ba7fcf63 100644 --- a/include/libopencm3/stm32/f4/pwr.h +++ b/include/libopencm3/stm32/f4/pwr.h @@ -49,7 +49,16 @@ LGPL License Terms @ref lgpl_license #define PWR_CR_VOS_SHIFT 14 #define PWR_CR_VOS_MASK 0x3 -/* Bits [13:10]: Reserved */ +/* ADCDC1: Masks extra flash accesses by prefetch (see AN4073) */ +#define PWR_CR_ADCDC1 (1 << 13) + +/* Bit 12: Reserved */ + +/* Bit 11: Main regulator Low Voltage in Deep Sleep */ +#define PWR_CR_MRLVDS (1 << 11) + +/* Bit 10: Low-power regulator Low Voltage in Deep Sleep */ +#define PWR_CR_LPLVDS (1 << 10) /* FPDS: Flash power down in stop mode */ #define PWR_CR_FPDS (1 << 9) From ed2aada3e8c84d085f4f3451a9b9cdf36b893d62 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 10 Nov 2021 20:36:29 +0000 Subject: [PATCH 118/206] doc:stm32f4:pwr: link more doxygen f4 extensions weren't being included in generated documentation. --- include/libopencm3/stm32/f4/pwr.h | 32 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/include/libopencm3/stm32/f4/pwr.h b/include/libopencm3/stm32/f4/pwr.h index ba7fcf63..d4b02593 100644 --- a/include/libopencm3/stm32/f4/pwr.h +++ b/include/libopencm3/stm32/f4/pwr.h @@ -40,44 +40,38 @@ LGPL License Terms @ref lgpl_license * This file extends the common STM32 version with definitions only * applicable to the STM32F4 series of devices. */ +/** @addtogroup pwr_defines + * @{*/ /* --- PWR_CR values ------------------------------------------------------- */ -/* Bits [31:16]: Reserved */ - -/* VOS: Regulator voltage scaling output selection */ +/** VOS: Regulator voltage scaling output selection */ #define PWR_CR_VOS_SHIFT 14 #define PWR_CR_VOS_MASK 0x3 -/* ADCDC1: Masks extra flash accesses by prefetch (see AN4073) */ +/** ADCDC1: Masks extra flash accesses by prefetch (see AN4073) */ #define PWR_CR_ADCDC1 (1 << 13) -/* Bit 12: Reserved */ - -/* Bit 11: Main regulator Low Voltage in Deep Sleep */ +/** MRLVDS/MRUDS: Main regulator Low Voltage / Under drive in Deep Sleep */ #define PWR_CR_MRLVDS (1 << 11) +#define PWR_CR_MRUDS PWR_CR_MRLVDS -/* Bit 10: Low-power regulator Low Voltage in Deep Sleep */ +/** LPLVDS/LPUDS: Low-power regulator Low Voltage / Under drive in Deep Sleep */ #define PWR_CR_LPLVDS (1 << 10) +#define PWR_CR_LPUDS PWR_CR_LPLVDS -/* FPDS: Flash power down in stop mode */ +/** FPDS: Flash power down in stop mode */ #define PWR_CR_FPDS (1 << 9) /* --- PWR_CSR values ------------------------------------------------------ */ -/* Bits [31:15]: Reserved */ - -/* VOSRDY: Regulator voltage scaling output selection ready bit */ +/** VOSRDY: Regulator voltage scaling output selection ready bit */ #define PWR_CSR_VOSRDY (1 << 14) -/* Bits [13:10]: Reserved */ - -/* BRE: Backup regulator enable */ +/** BRE: Backup regulator enable */ #define PWR_CSR_BRE (1 << 9) -/* Bits [7:4]: Reserved */ - -/* BRR: Backup regulator ready */ +/** BRR: Backup regulator ready */ #define PWR_CSR_BRR (1 << 3) /* --- Function prototypes ------------------------------------------------- */ @@ -94,4 +88,6 @@ void pwr_set_vos_scale(enum pwr_vos_scale scale); END_DECLS +/**@}*/ + #endif From 34eb368b29a314b3e40fefba89def96a32de7748 Mon Sep 17 00:00:00 2001 From: Voronov Alexander Date: Tue, 29 Dec 2020 19:17:21 +0500 Subject: [PATCH 119/206] README: added info about partial build --- Makefile | 4 +++- README.md | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 20f878fa..c4e161b0 100644 --- a/Makefile +++ b/Makefile @@ -124,5 +124,7 @@ genlinktests.clean: printf " TEST FAIL : $*\n"; \ fi; +list-targets: + @echo $(TARGETS) -.PHONY: build lib $(LIB_DIRS) doc clean generatedheaders cleanheaders stylecheck genlinktests genlinktests.clean +.PHONY: build lib $(LIB_DIRS) doc clean generatedheaders cleanheaders stylecheck genlinktests genlinktests.clean list-targets diff --git a/README.md b/README.md index cbb5c9c3..8d86e7c0 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,14 @@ For a more verbose build you can use $ make V=1 +You can reduce the build time by specifying a particular MCU series + + $ make TARGETS='stm32/f1 stm32/f4' + +Supported targets can be listed using: + + $ make list-targets + Fine-tuning the build --------------------- From 8f016208ea68c75e3356d54ed183b96222f01dcc Mon Sep 17 00:00:00 2001 From: Voronov Alexander Date: Tue, 29 Dec 2020 19:17:21 +0500 Subject: [PATCH 120/206] README: remove white space at end of line --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8d86e7c0..e3b6ab00 100644 --- a/README.md +++ b/README.md @@ -124,13 +124,13 @@ them as environment variables, for example: If the Cortex-M core supports a hard float ABI, it will be compiled with the best floating-point support by default. In cases where this is not desired, the behavior can be specified by setting `FP_FLAGS`. - + Currently, M4F cores default to `-mfloat-abi=hard -mfpu=fpv4-sp-d16`, and M7 cores defaults to double precision `-mfloat-abi=hard -mfpu=fpv5-d16` if available, and single precision `-mfloat-abi=hard -mfpu=fpv5-sp-d16` otherwise. Other architectures use no FP flags, in otherwords, traditional softfp. - - You may find which FP_FLAGS you can use in a particular architecture in the readme.txt + + You may find which FP_FLAGS you can use in a particular architecture in the readme.txt file shipped with the gcc-arm-embedded package. Examples: From c36a4538b0e8a3f29bc52126ca4fb6331c9f6bd6 Mon Sep 17 00:00:00 2001 From: Will Gallia Date: Wed, 1 Dec 2021 22:38:30 +0000 Subject: [PATCH 121/206] stm32: fix typo for auto baud rate request bit in USART_RQR --- include/libopencm3/stm32/common/usart_common_v2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/common/usart_common_v2.h b/include/libopencm3/stm32/common/usart_common_v2.h index b0bcea7f..964c5e78 100644 --- a/include/libopencm3/stm32/common/usart_common_v2.h +++ b/include/libopencm3/stm32/common/usart_common_v2.h @@ -478,7 +478,7 @@ #define USART_RQR_SBKRQ (1 << 1) /** ABRRQ: Auto baud rate request */ -#define USART_RQR_ABKRQ (1 << 0) +#define USART_RQR_ABRRQ (1 << 0) /**@}*/ From 213a6b4244260ccb280923142e56ca13eb2e381c Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Fri, 19 Nov 2021 11:06:27 +0100 Subject: [PATCH 122/206] Initial merge of Nordic Semi nRF51/52 from Unicore MX back into Libopencm3 * merged: nrf tree from unicore-mx * fixed: small changes to make merged code play with rest of locm3 again * added: linker script generator defines for nRF51/52 stubs * added: doxygen support This removes code and changes names and styles where relevant to be more inline with normal libopencm3. NRF52x library is built for hardfloat, M4F by default. The M4 no float variants are less common, and if needed, the library can be built manually for those variants. Unless some very common boards show up using those parts, we don't need an extra library build. Reviewed-by: Karl Palsson Tested-by: Karl Palsson --- Makefile | 1 + README.md | 1 + doc/nrf51/doxy.custom | 1 + doc/nrf52/doxy.custom | 1 + include/libopencm3/dispatch/nvic.h | 6 + include/libopencm3/nrf/51/clock.h | 56 ++++ include/libopencm3/nrf/51/doc-nrf51.h | 32 +++ include/libopencm3/nrf/51/ficr.h | 73 +++++ include/libopencm3/nrf/51/gpio.h | 37 +++ include/libopencm3/nrf/51/i2c.h | 40 +++ include/libopencm3/nrf/51/irq.json | 33 +++ include/libopencm3/nrf/51/memorymap.h | 26 ++ include/libopencm3/nrf/51/periph.h | 28 ++ include/libopencm3/nrf/51/power.h | 40 +++ include/libopencm3/nrf/51/ppi.h | 39 +++ include/libopencm3/nrf/51/radio.h | 52 ++++ include/libopencm3/nrf/51/rtc.h | 40 +++ include/libopencm3/nrf/51/timer.h | 40 +++ include/libopencm3/nrf/51/uart.h | 39 +++ include/libopencm3/nrf/51/uicr.h | 40 +++ include/libopencm3/nrf/52/clock.h | 45 +++ include/libopencm3/nrf/52/doc-nrf52.h | 32 +++ include/libopencm3/nrf/52/ficr.h | 39 +++ include/libopencm3/nrf/52/gpio.h | 37 +++ include/libopencm3/nrf/52/i2c.h | 40 +++ include/libopencm3/nrf/52/irq.json | 35 +++ include/libopencm3/nrf/52/memorymap.h | 28 ++ include/libopencm3/nrf/52/periph.h | 28 ++ include/libopencm3/nrf/52/power.h | 40 +++ include/libopencm3/nrf/52/ppi.h | 39 +++ include/libopencm3/nrf/52/radio.h | 40 +++ include/libopencm3/nrf/52/rtc.h | 40 +++ include/libopencm3/nrf/52/timer.h | 51 ++++ include/libopencm3/nrf/52/uart.h | 39 +++ include/libopencm3/nrf/52/uicr.h | 40 +++ include/libopencm3/nrf/clock.h | 30 ++ include/libopencm3/nrf/common/clock.h | 98 +++++++ include/libopencm3/nrf/common/ficr.h | 52 ++++ include/libopencm3/nrf/common/gpio.h | 236 ++++++++++++++++ include/libopencm3/nrf/common/i2c.h | 128 +++++++++ include/libopencm3/nrf/common/memorymap.h | 97 +++++++ include/libopencm3/nrf/common/periph.h | 148 ++++++++++ include/libopencm3/nrf/common/power.h | 106 +++++++ include/libopencm3/nrf/common/ppi.h | 147 ++++++++++ include/libopencm3/nrf/common/radio.h | 325 ++++++++++++++++++++++ include/libopencm3/nrf/common/rtc.h | 85 ++++++ include/libopencm3/nrf/common/timer.h | 120 ++++++++ include/libopencm3/nrf/common/uart.h | 150 ++++++++++ include/libopencm3/nrf/common/uicr.h | 53 ++++ include/libopencm3/nrf/ficr.h | 38 +++ include/libopencm3/nrf/gpio.h | 40 +++ include/libopencm3/nrf/i2c.h | 37 +++ include/libopencm3/nrf/memorymap.h | 30 ++ include/libopencm3/nrf/periph.h | 30 ++ include/libopencm3/nrf/power.h | 37 +++ include/libopencm3/nrf/ppi.h | 37 +++ include/libopencm3/nrf/radio.h | 37 +++ include/libopencm3/nrf/rtc.h | 37 +++ include/libopencm3/nrf/timer.h | 37 +++ include/libopencm3/nrf/uart.h | 37 +++ include/libopencm3/nrf/uicr.h | 37 +++ ld/devices.data | 24 ++ lib/dispatch/vector_nvic.c | 5 + lib/nrf/51/Makefile | 50 ++++ lib/nrf/51/clock.c | 45 +++ lib/nrf/51/radio.c | 66 +++++ lib/nrf/52/Makefile | 50 ++++ lib/nrf/common/clock_common.c | 83 ++++++ lib/nrf/common/gpio.c | 208 ++++++++++++++ lib/nrf/common/i2c.c | 184 ++++++++++++ lib/nrf/common/ppi.c | 145 ++++++++++ lib/nrf/common/radio_common.c | 250 +++++++++++++++++ lib/nrf/common/rtc.c | 116 ++++++++ lib/nrf/common/timer.c | 147 ++++++++++ lib/nrf/common/uart.c | 171 ++++++++++++ 75 files changed, 4951 insertions(+) create mode 100644 doc/nrf51/doxy.custom create mode 100644 doc/nrf52/doxy.custom create mode 100644 include/libopencm3/nrf/51/clock.h create mode 100644 include/libopencm3/nrf/51/doc-nrf51.h create mode 100644 include/libopencm3/nrf/51/ficr.h create mode 100644 include/libopencm3/nrf/51/gpio.h create mode 100644 include/libopencm3/nrf/51/i2c.h create mode 100644 include/libopencm3/nrf/51/irq.json create mode 100644 include/libopencm3/nrf/51/memorymap.h create mode 100644 include/libopencm3/nrf/51/periph.h create mode 100644 include/libopencm3/nrf/51/power.h create mode 100644 include/libopencm3/nrf/51/ppi.h create mode 100644 include/libopencm3/nrf/51/radio.h create mode 100644 include/libopencm3/nrf/51/rtc.h create mode 100644 include/libopencm3/nrf/51/timer.h create mode 100644 include/libopencm3/nrf/51/uart.h create mode 100644 include/libopencm3/nrf/51/uicr.h create mode 100644 include/libopencm3/nrf/52/clock.h create mode 100644 include/libopencm3/nrf/52/doc-nrf52.h create mode 100644 include/libopencm3/nrf/52/ficr.h create mode 100644 include/libopencm3/nrf/52/gpio.h create mode 100644 include/libopencm3/nrf/52/i2c.h create mode 100644 include/libopencm3/nrf/52/irq.json create mode 100644 include/libopencm3/nrf/52/memorymap.h create mode 100644 include/libopencm3/nrf/52/periph.h create mode 100644 include/libopencm3/nrf/52/power.h create mode 100644 include/libopencm3/nrf/52/ppi.h create mode 100644 include/libopencm3/nrf/52/radio.h create mode 100644 include/libopencm3/nrf/52/rtc.h create mode 100644 include/libopencm3/nrf/52/timer.h create mode 100644 include/libopencm3/nrf/52/uart.h create mode 100644 include/libopencm3/nrf/52/uicr.h create mode 100644 include/libopencm3/nrf/clock.h create mode 100644 include/libopencm3/nrf/common/clock.h create mode 100644 include/libopencm3/nrf/common/ficr.h create mode 100644 include/libopencm3/nrf/common/gpio.h create mode 100644 include/libopencm3/nrf/common/i2c.h create mode 100644 include/libopencm3/nrf/common/memorymap.h create mode 100644 include/libopencm3/nrf/common/periph.h create mode 100644 include/libopencm3/nrf/common/power.h create mode 100644 include/libopencm3/nrf/common/ppi.h create mode 100644 include/libopencm3/nrf/common/radio.h create mode 100644 include/libopencm3/nrf/common/rtc.h create mode 100644 include/libopencm3/nrf/common/timer.h create mode 100644 include/libopencm3/nrf/common/uart.h create mode 100644 include/libopencm3/nrf/common/uicr.h create mode 100644 include/libopencm3/nrf/ficr.h create mode 100644 include/libopencm3/nrf/gpio.h create mode 100644 include/libopencm3/nrf/i2c.h create mode 100644 include/libopencm3/nrf/memorymap.h create mode 100644 include/libopencm3/nrf/periph.h create mode 100644 include/libopencm3/nrf/power.h create mode 100644 include/libopencm3/nrf/ppi.h create mode 100644 include/libopencm3/nrf/radio.h create mode 100644 include/libopencm3/nrf/rtc.h create mode 100644 include/libopencm3/nrf/timer.h create mode 100644 include/libopencm3/nrf/uart.h create mode 100644 include/libopencm3/nrf/uicr.h create mode 100644 lib/nrf/51/Makefile create mode 100644 lib/nrf/51/clock.c create mode 100644 lib/nrf/51/radio.c create mode 100644 lib/nrf/52/Makefile create mode 100644 lib/nrf/common/clock_common.c create mode 100644 lib/nrf/common/gpio.c create mode 100644 lib/nrf/common/i2c.c create mode 100644 lib/nrf/common/ppi.c create mode 100644 lib/nrf/common/radio_common.c create mode 100644 lib/nrf/common/rtc.c create mode 100644 lib/nrf/common/timer.c create mode 100644 lib/nrf/common/uart.c diff --git a/Makefile b/Makefile index c4e161b0..6de524a6 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ TARGETS ?= stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/f7 \ lm3s lm4f msp432/e4 \ efm32/tg efm32/g efm32/lg efm32/gg efm32/hg efm32/wg \ efm32/ezr32wg \ + nrf/51 nrf/52 \ sam/3a sam/3n sam/3s sam/3u sam/3x sam/4l \ sam/d \ vf6xx \ diff --git a/README.md b/README.md index e3b6ab00..906d8ab1 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ Currently (at least partly) supported microcontrollers: - Freescale Vybrid VF6xx - Qorvo (formerly ActiveSemi) PAC55XX - Synwit SWM050 + - Nordic NRF51x and NRF52x The library is written completely from scratch based on the vendor datasheets, programming manuals, and application notes. The code is meant to be used diff --git a/doc/nrf51/doxy.custom b/doc/nrf51/doxy.custom new file mode 100644 index 00000000..4789a761 --- /dev/null +++ b/doc/nrf51/doxy.custom @@ -0,0 +1 @@ +PREDEFINED += __ARM_ARCH_7EM__ diff --git a/doc/nrf52/doxy.custom b/doc/nrf52/doxy.custom new file mode 100644 index 00000000..4789a761 --- /dev/null +++ b/doc/nrf52/doxy.custom @@ -0,0 +1 @@ +PREDEFINED += __ARM_ARCH_7EM__ diff --git a/include/libopencm3/dispatch/nvic.h b/include/libopencm3/dispatch/nvic.h index b4589dd6..ce62c2b0 100644 --- a/include/libopencm3/dispatch/nvic.h +++ b/include/libopencm3/dispatch/nvic.h @@ -76,6 +76,12 @@ #elif defined(MSP432E4) # include +#elif defined(NRF51) +# include + +#elif defined(NRF52) +# include + #elif defined(VF6XX) # include diff --git a/include/libopencm3/nrf/51/clock.h b/include/libopencm3/nrf/51/clock.h new file mode 100644 index 00000000..fe3acbef --- /dev/null +++ b/include/libopencm3/nrf/51/clock.h @@ -0,0 +1,56 @@ +/** @defgroup clock_defines CLOCK Defines + * + * @brief Defined Constants and Types for the NRF51xx Clock control + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include + +#include +#include +#include + +/* Clock registers */ +#define CLOCK_XTALFREQ MMIO32(CLOCK_BASE + 0x550) + +#define CLOCK_PCLK 16000000 + +enum clock_xtal_freq { + CLOCK_XTAL_FREQ_32MHZ, + CLOCK_XTAL_FREQ_16MHZ = 0xff, +}; + +BEGIN_DECLS + +void clock_set_xtal_freq(enum clock_xtal_freq freq); + +END_DECLS + diff --git a/include/libopencm3/nrf/51/doc-nrf51.h b/include/libopencm3/nrf/51/doc-nrf51.h new file mode 100644 index 00000000..ff964093 --- /dev/null +++ b/include/libopencm3/nrf/51/doc-nrf51.h @@ -0,0 +1,32 @@ +/** @page libopencm3 NRF51 + +@version 1.0.0 + +@date April 2020 + +API documentation for Nordic Semiconductor NRF51 Cortex M0 series + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup peripheral_apis Peripheral APIs + * APIs for device peripherals + */ + +/** @defgroup NRF51xx NRF51xx +Libraries for Nordic Semiconductor NRF51xx series. + +@version 1.0.0 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup NRF51xx_defines NRF51xx Defines + +@brief Defined Constants and Types for the NRF51xx series + +@version 1.0.0 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/include/libopencm3/nrf/51/ficr.h b/include/libopencm3/nrf/51/ficr.h new file mode 100644 index 00000000..ab2abe60 --- /dev/null +++ b/include/libopencm3/nrf/51/ficr.h @@ -0,0 +1,73 @@ +/** @defgroup ficr_defines FICR Defines + * + * @brief Defined Constants and Types for the NRF51xx Factory information + * configuration registers + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Deprecated by Nordic */ +#define FICR_CLENR0 MMIO32(FICR_BASE + 0x028) +/* Deprecated by Nordic */ +#define FICR_PPFC MMIO32(FICR_BASE + 0x02C) + +#define FICR_NUMRAMBLOCK MMIO32(FICR_BASE + 0x034) +#define FICR_SIZERAMBLOCKS MMIO32(FICR_BASE + 0x038) + +/* Deprecated by Nordic */ +#define FICR_SIZERAMBLOCK(n) MMIO32(FICR_BASE + 0x038 + 0x4 * (n)) + +#define FICR_CONFIGID MMIO32(FICR_BASE + 0x05C) + +#define FICR_OVERRIDEEN MMIO32(FICR_BASE + 0x0AC) + +/* Override values for Nordic Semi proprietary NRF 1Mbit mode */ +#define FICR_NRF_1MBIT(n) MMIO32(FICR_BASE + 0x0B0 + 0x4 * (n)) +#define FICR_NRF_1MBIT0 FICR_NRF_1MBIT(0) +#define FICR_NRF_1MBIT1 FICR_NRF_1MBIT(1) +#define FICR_NRF_1MBIT2 FICR_NRF_1MBIT(2) +#define FICR_NRF_1MBIT3 FICR_NRF_1MBIT(3) +#define FICR_NRF_1MBIT4 FICR_NRF_1MBIT(4) + +/* Override values for BLE 1Mbit mode */ +#define FICR_BLE_1MBIT(n) MMIO32(FICR_BASE + 0x0EC + 0x4 * (n)) +#define FICR_BLE_1MBIT0 FICR_BLE_1MBIT(0) +#define FICR_BLE_1MBIT1 FICR_BLE_1MBIT(1) +#define FICR_BLE_1MBIT2 FICR_BLE_1MBIT(2) +#define FICR_BLE_1MBIT3 FICR_BLE_1MBIT(3) +#define FICR_BLE_1MBIT4 FICR_BLE_1MBIT(4) + +#define FICR_OVERRIDEEN_NRF_1MBIT (1 << 0) +#define FICR_OVERRIDEEN_BLE_1MBIT (1 << 3) + diff --git a/include/libopencm3/nrf/51/gpio.h b/include/libopencm3/nrf/51/gpio.h new file mode 100644 index 00000000..df9cb3e2 --- /dev/null +++ b/include/libopencm3/nrf/51/gpio.h @@ -0,0 +1,37 @@ +/** @defgroup gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the NRF51xx General Purpose I/O + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include + + diff --git a/include/libopencm3/nrf/51/i2c.h b/include/libopencm3/nrf/51/i2c.h new file mode 100644 index 00000000..11baaf65 --- /dev/null +++ b/include/libopencm3/nrf/51/i2c.h @@ -0,0 +1,40 @@ +/** @defgroup i2c_defines I2C Defines + * + * @brief Defined Constants and Types for the NRF51xx I2C + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + + diff --git a/include/libopencm3/nrf/51/irq.json b/include/libopencm3/nrf/51/irq.json new file mode 100644 index 00000000..19d95556 --- /dev/null +++ b/include/libopencm3/nrf/51/irq.json @@ -0,0 +1,33 @@ +{ + "irqs": [ + "power_clock", + "radio", + "uart0", + "spi0_twi0", + "spi1_twi1", + "reserved0", + "gpiote", + "adc", + "timer0", + "timer1", + "timer2", + "rtc0", + "temp", + "rng", + "ecb", + "ccm_aar", + "wdt", + "rtc1", + "qdec", + "lpcomp", + "swi0", + "swi1", + "swi2", + "swi3", + "swi4", + "swi5" + ], + "partname_humanreadable": "Nordic Semi NRF51 series", + "partname_doxygen": "NRF51", + "includeguard": "LIBOPENCM3_NRF51_NVIC_H" +} diff --git a/include/libopencm3/nrf/51/memorymap.h b/include/libopencm3/nrf/51/memorymap.h new file mode 100644 index 00000000..2fc02026 --- /dev/null +++ b/include/libopencm3/nrf/51/memorymap.h @@ -0,0 +1,26 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include + + diff --git a/include/libopencm3/nrf/51/periph.h b/include/libopencm3/nrf/51/periph.h new file mode 100644 index 00000000..05195421 --- /dev/null +++ b/include/libopencm3/nrf/51/periph.h @@ -0,0 +1,28 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +#include + diff --git a/include/libopencm3/nrf/51/power.h b/include/libopencm3/nrf/51/power.h new file mode 100644 index 00000000..3d42e343 --- /dev/null +++ b/include/libopencm3/nrf/51/power.h @@ -0,0 +1,40 @@ +/** @defgroup power_defines POWER Defines + * + * @brief Defined Constants and Types for the NRF51xx Power control + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + + diff --git a/include/libopencm3/nrf/51/ppi.h b/include/libopencm3/nrf/51/ppi.h new file mode 100644 index 00000000..bdac298c --- /dev/null +++ b/include/libopencm3/nrf/51/ppi.h @@ -0,0 +1,39 @@ +/** @defgroup ppi_defines PPI Defines + * + * @brief Defined Constants and Types for the NRF51xx Programmable peripheral + * interconnect + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + diff --git a/include/libopencm3/nrf/51/radio.h b/include/libopencm3/nrf/51/radio.h new file mode 100644 index 00000000..7c275fa2 --- /dev/null +++ b/include/libopencm3/nrf/51/radio.h @@ -0,0 +1,52 @@ +/** @defgroup radio_defines RADIO Defines + * + * @brief Defined Constants and Types for the NRF51xx 2.4GHz radio + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + +enum radio_mode { + RADIO_MODE_NRF_1MBIT, + RADIO_MODE_NRF_2MBIT, + RADIO_MODE_NRF_250KBIT, + RADIO_MODE_BLE_1MBIT, +}; + +BEGIN_DECLS + +void radio_set_mode(enum radio_mode mode); + +END_DECLS + diff --git a/include/libopencm3/nrf/51/rtc.h b/include/libopencm3/nrf/51/rtc.h new file mode 100644 index 00000000..7bcb799b --- /dev/null +++ b/include/libopencm3/nrf/51/rtc.h @@ -0,0 +1,40 @@ +/** @defgroup rtc_defines RTC Defines + * + * @brief Defined Constants and Types for the NRF51xx Realtime clock + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +#include + diff --git a/include/libopencm3/nrf/51/timer.h b/include/libopencm3/nrf/51/timer.h new file mode 100644 index 00000000..dd6d0c12 --- /dev/null +++ b/include/libopencm3/nrf/51/timer.h @@ -0,0 +1,40 @@ +/** @defgroup timer_defines TIMER Defines + * + * @brief Defined Constants and Types for the NRF51xx Timer + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + + diff --git a/include/libopencm3/nrf/51/uart.h b/include/libopencm3/nrf/51/uart.h new file mode 100644 index 00000000..62137f4f --- /dev/null +++ b/include/libopencm3/nrf/51/uart.h @@ -0,0 +1,39 @@ +/** @defgroup uart_defines UART Defines + * + * @brief Defined Constants and Types for the NRF51xx UART + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + diff --git a/include/libopencm3/nrf/51/uicr.h b/include/libopencm3/nrf/51/uicr.h new file mode 100644 index 00000000..9a5c6e75 --- /dev/null +++ b/include/libopencm3/nrf/51/uicr.h @@ -0,0 +1,40 @@ +/** @defgroup uicr_defines UICR Defines + * + * @brief Defined Constants and Types for the NRF51xx User information configuraton + * registers + * + * @ingroup NRF51xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + + diff --git a/include/libopencm3/nrf/52/clock.h b/include/libopencm3/nrf/52/clock.h new file mode 100644 index 00000000..2e432d11 --- /dev/null +++ b/include/libopencm3/nrf/52/clock.h @@ -0,0 +1,45 @@ +/** @defgroup clock_defines CLOCK Defines + * + * @brief Defined Constants and Types for the NRF52xx Clock control + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include + +#include +#include +#include + +/* Clock registers */ +#define CLOCK_TRACECONFIG MMIO32(CLOCK_BASE + 0x55C) + +#define CLOCK_PCLK 32000000 + diff --git a/include/libopencm3/nrf/52/doc-nrf52.h b/include/libopencm3/nrf/52/doc-nrf52.h new file mode 100644 index 00000000..4a7f9de3 --- /dev/null +++ b/include/libopencm3/nrf/52/doc-nrf52.h @@ -0,0 +1,32 @@ +/** @page libopencm3 NRF52 + +@version 1.0.0 + +@date November 2021 + +API documentation for Nordic Semiconductor nRF52 Cortex M4 series + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup peripheral_apis Peripheral APIs + * APIs for device peripherals + */ + +/** @defgroup NRF52xx NRF52xx +Libraries for Nordic Semiconductor NRF52xx series. + +@version 1.0.0 + +LGPL License Terms @ref lgpl_license +*/ + +/** @defgroup NRF52xx_defines NRF52xx Defines + +@brief Defined Constants and Types for the NRF52xx series + +@version 1.0.0 + +LGPL License Terms @ref lgpl_license +*/ + diff --git a/include/libopencm3/nrf/52/ficr.h b/include/libopencm3/nrf/52/ficr.h new file mode 100644 index 00000000..7b30b7ba --- /dev/null +++ b/include/libopencm3/nrf/52/ficr.h @@ -0,0 +1,39 @@ +/** @defgroup ficr_defines FICR Defines + * + * @brief Defined Constants and Types for the NRF52xx Factory information + * configuration registers + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + diff --git a/include/libopencm3/nrf/52/gpio.h b/include/libopencm3/nrf/52/gpio.h new file mode 100644 index 00000000..b0297b02 --- /dev/null +++ b/include/libopencm3/nrf/52/gpio.h @@ -0,0 +1,37 @@ +/** @defgroup gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the NRF52xx General Purpose I/O + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include + + diff --git a/include/libopencm3/nrf/52/i2c.h b/include/libopencm3/nrf/52/i2c.h new file mode 100644 index 00000000..3341c59a --- /dev/null +++ b/include/libopencm3/nrf/52/i2c.h @@ -0,0 +1,40 @@ +/** @defgroup i2c_defines I2C Defines + * + * @brief Defined Constants and Types for the NRF52xx I2C + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + + diff --git a/include/libopencm3/nrf/52/irq.json b/include/libopencm3/nrf/52/irq.json new file mode 100644 index 00000000..63dbc309 --- /dev/null +++ b/include/libopencm3/nrf/52/irq.json @@ -0,0 +1,35 @@ +{ + "irqs": [ + "power_clock", + "radio", + "uart0", + "spi0_twi0", + "spi1_twi1", + "reserved0", + "gpiote", + "adc", + "timer0", + "timer1", + "timer2", + "timer3", + "timer4", + "rtc0", + "temp", + "rng", + "ecb", + "ccm_aar", + "wdt", + "rtc1", + "qdec", + "lpcomp", + "swi0", + "swi1", + "swi2", + "swi3", + "swi4", + "swi5" + ], + "partname_humanreadable": "Nordic Semi NRF52 series", + "partname_doxygen": "NRF52", + "includeguard": "LIBOPENCM3_NRF52_NVIC_H" +} diff --git a/include/libopencm3/nrf/52/memorymap.h b/include/libopencm3/nrf/52/memorymap.h new file mode 100644 index 00000000..680a8892 --- /dev/null +++ b/include/libopencm3/nrf/52/memorymap.h @@ -0,0 +1,28 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include + +#define TIMER3_BASE (APB_BASE + 0x1A000) +#define TIMER4_BASE (APB_BASE + 0x1B000) + diff --git a/include/libopencm3/nrf/52/periph.h b/include/libopencm3/nrf/52/periph.h new file mode 100644 index 00000000..05195421 --- /dev/null +++ b/include/libopencm3/nrf/52/periph.h @@ -0,0 +1,28 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +#include + diff --git a/include/libopencm3/nrf/52/power.h b/include/libopencm3/nrf/52/power.h new file mode 100644 index 00000000..0b1fc8f2 --- /dev/null +++ b/include/libopencm3/nrf/52/power.h @@ -0,0 +1,40 @@ +/** @defgroup power_defines POWER Defines + * + * @brief Defined Constants and Types for the NRF52xx Power control + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + + diff --git a/include/libopencm3/nrf/52/ppi.h b/include/libopencm3/nrf/52/ppi.h new file mode 100644 index 00000000..261172d1 --- /dev/null +++ b/include/libopencm3/nrf/52/ppi.h @@ -0,0 +1,39 @@ +/** @defgroup ppi_defines PPI Defines + * + * @brief Defined Constants and Types for the NRF52xx Programmable peripheral + * interconnect + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + diff --git a/include/libopencm3/nrf/52/radio.h b/include/libopencm3/nrf/52/radio.h new file mode 100644 index 00000000..0d5e2362 --- /dev/null +++ b/include/libopencm3/nrf/52/radio.h @@ -0,0 +1,40 @@ +/** @defgroup radio_defines RADIO Defines + * + * @brief Defined Constants and Types for the NRF52xx 2.4GHz radio + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + + diff --git a/include/libopencm3/nrf/52/rtc.h b/include/libopencm3/nrf/52/rtc.h new file mode 100644 index 00000000..940f3f89 --- /dev/null +++ b/include/libopencm3/nrf/52/rtc.h @@ -0,0 +1,40 @@ +/** @defgroup rtc_defines RTC Defines + * + * @brief Defined Constants and Types for the NRF52xx Realtime clock + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +#include + diff --git a/include/libopencm3/nrf/52/timer.h b/include/libopencm3/nrf/52/timer.h new file mode 100644 index 00000000..56832143 --- /dev/null +++ b/include/libopencm3/nrf/52/timer.h @@ -0,0 +1,51 @@ +/** @defgroup timer_defines TIMER Defines + * + * @brief Defined Constants and Types for the NRF52xx Timer + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + +/**@{*/ +/* Timer/Counter */ +/** @addtogroup timer_block TIMER instances + * @{ + */ +#define TIMER4 TIMER4_BASE +#define TIMER3 TIMER3_BASE + +/**@}*/ + +/**@}*/ + diff --git a/include/libopencm3/nrf/52/uart.h b/include/libopencm3/nrf/52/uart.h new file mode 100644 index 00000000..2dd0f897 --- /dev/null +++ b/include/libopencm3/nrf/52/uart.h @@ -0,0 +1,39 @@ +/** @defgroup uart_defines UART Defines + * + * @brief Defined Constants and Types for the NRF52xx UART + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + diff --git a/include/libopencm3/nrf/52/uicr.h b/include/libopencm3/nrf/52/uicr.h new file mode 100644 index 00000000..906b909f --- /dev/null +++ b/include/libopencm3/nrf/52/uicr.h @@ -0,0 +1,40 @@ +/** @defgroup uicr_defines UICR Defines + * + * @brief Defined Constants and Types for the NRF52xx User information configuraton + * registers + * + * @ingroup NRF52xx_defines + * + * @version 1.0.0 + * + * @date Nov 2021 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + + diff --git a/include/libopencm3/nrf/clock.h b/include/libopencm3/nrf/clock.h new file mode 100644 index 00000000..28c7bb08 --- /dev/null +++ b/include/libopencm3/nrf/clock.h @@ -0,0 +1,30 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/common/clock.h b/include/libopencm3/nrf/common/clock.h new file mode 100644 index 00000000..ff81f409 --- /dev/null +++ b/include/libopencm3/nrf/common/clock.h @@ -0,0 +1,98 @@ +/** @addtogroup clock_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include + +#include +#include +/**@{*/ + +/* Clock tasks */ +#define CLOCK_TASK_HFCLKSTART MMIO32(CLOCK_BASE + 0x000) +#define CLOCK_TASK_HFCLKSTOP MMIO32(CLOCK_BASE + 0x004) +#define CLOCK_TASK_LFCLKSTART MMIO32(CLOCK_BASE + 0x008) +#define CLOCK_TASK_LFCLKSTOP MMIO32(CLOCK_BASE + 0x00C) +#define CLOCK_TASK_CAL MMIO32(CLOCK_BASE + 0x010) +#define CLOCK_TASK_CTSTART MMIO32(CLOCK_BASE + 0x014) +#define CLOCK_TASK_CTSTOP MMIO32(CLOCK_BASE + 0x018) + +/* Clock events */ +#define CLOCK_EVENT_HFCLKSTARTED MMIO32(CLOCK_BASE + 0x100) +#define CLOCK_EVENT_LFCLKSTARTED MMIO32(CLOCK_BASE + 0x104) +#define CLOCK_EVENT_DONE MMIO32(CLOCK_BASE + 0x10C) +#define CLOCK_EVENT_CTTO MMIO32(CLOCK_BASE + 0x110) + +/* Clock registers */ +#define CLOCK_INTENSET MMIO32(CLOCK_BASE + 0x304) +#define CLOCK_INTENCLR MMIO32(CLOCK_BASE + 0x308) +#define CLOCK_HFCLKRUN MMIO32(CLOCK_BASE + 0x408) +#define CLOCK_HFCLKSTAT MMIO32(CLOCK_BASE + 0x40C) +#define CLOCK_LFCLKRUN MMIO32(CLOCK_BASE + 0x414) +#define CLOCK_LFCLKSTAT MMIO32(CLOCK_BASE + 0x418) +#define CLOCK_LFCLKSRCCOPY MMIO32(CLOCK_BASE + 0x41C) +#define CLOCK_LFCLKSRC MMIO32(CLOCK_BASE + 0x518) +#define CLOCK_CTIV MMIO32(CLOCK_BASE + 0x538) + +/* Register contents */ +#define CLOCK_INTEN_HFCLKSTARTED (1 << 0) +#define CLOCK_INTEN_LFCLKSTARTED (1 << 1) +#define CLOCK_INTEN_DONE (1 << 3) +#define CLOCK_INTEN_CTTO (1 << 4) + +#define CLOCK_HFCLKRUN_STATUS (1 << 0) + +#define CLOCK_HFCLKSTAT_SRC (1 << 0) +#define CLOCK_HFCLKSTAT_STATE (1 << 16) + +#define CLOCK_LFCLKRUN_STATUS (1 << 0) + +#define CLOCK_LFCLK_SRC_SHIFT (0) +#define CLOCK_LFCLK_SRC_MASK (3 << CLOCK_LFCLKSTAT_SRC_SHIFT) +#define CLOCK_LFCLK_SRC_MASKED(V) (((V) << CLOCK_LFCLKSTAT_SRC_SHIFT) & CLOCK_LFCLKSTAT_SRC_MASK) + +#define CLOCK_LFCLKSTAT_STATE (1 << 16) + +enum clock_lfclk_src { + CLOCK_LFCLK_SRC_RC, + CLOCK_LFCLK_SRC_XTAL, + CLOCK_LFCLK_SRC_SYNTH, +}; +/**@}*/ + +BEGIN_DECLS + +void clock_start_lfclk(bool wait); +void clock_stop_lfclk(void); +void clock_start_hfclk(bool wait); +void clock_stop_hfclk(void); +void clock_set_lfclk_src(enum clock_lfclk_src lfclk_src); + +END_DECLS + + diff --git a/include/libopencm3/nrf/common/ficr.h b/include/libopencm3/nrf/common/ficr.h new file mode 100644 index 00000000..542c3dde --- /dev/null +++ b/include/libopencm3/nrf/common/ficr.h @@ -0,0 +1,52 @@ +/** @addtogroup ficr_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +/**@{*/ + +/* Factory Information Configuration Register */ + +#define FICR_CODEPAGESIZE MMIO32(FICR_BASE + 0x010) +#define FICR_CODESIZE MMIO32(FICR_BASE + 0x014) + +#define FICR_DEVICEID0 MMIO32(FICR_BASE + 0x060) +#define FICR_DEVICEID1 MMIO32(FICR_BASE + 0x064) + +/* Encryption Root */ +#define FICR_ER(n) MMIO32(FICR_BASE + 0x080 + 0x4 * (n)) +/* Identity Root */ +#define FICR_IR(n) MMIO32(FICR_BASE + 0x090 + 0x4 * (n)) +#define FICR_DEVICEADDRTYPE MMIO32(FICR_BASE + 0x0A0) +#define FICR_DEVICEADDR0 MMIO32(FICR_BASE + 0x0A4) +#define FICR_DEVICEADDR1 MMIO32(FICR_BASE + 0x0A8) + + +/**@}*/ + diff --git a/include/libopencm3/nrf/common/gpio.h b/include/libopencm3/nrf/common/gpio.h new file mode 100644 index 00000000..8d8b4832 --- /dev/null +++ b/include/libopencm3/nrf/common/gpio.h @@ -0,0 +1,236 @@ +/** @addtogroup gpio_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +/**@{*/ + +/** @addtogroup gpio_port_id GPIO ports + * @{ + */ +/** GPIO port */ +#define GPIO (GPIO_BASE) + +/**@}*/ + +#define GPIO_OUT MMIO32(GPIO_BASE + 0x504) +#define GPIO_OUTSET MMIO32(GPIO_BASE + 0x508) +#define GPIO_OUTCLR MMIO32(GPIO_BASE + 0x50C) + +#define GPIO_IN MMIO32(GPIO_BASE + 0x510) + +#define GPIO_DIR MMIO32(GPIO_BASE + 0x514) +#define GPIO_DIRSET MMIO32(GPIO_BASE + 0x518) +#define GPIO_DIRCLR MMIO32(GPIO_BASE + 0x51C) + +#define GPIO_PIN_CNF(N) MMIO32(GPIO_BASE + 0x700 + 0x4 * (N)) + + +/* Pin mode (CPIO_CNF[1:0] - combines direction and analog/digital */ + +#define GPIO_CNF_MODE_MASK 2 +#define GPIO_CNF_MODE_SHIFT 0 + +/* Pin mode (MODE[1:0]) values */ +/** @defgroup gpio_mode GPIO Pin Mode +@ingroup gpio_defines +@{*/ +#define GPIO_MODE_INPUT 0 +#define GPIO_MODE_OUTPUT 1 +#define GPIO_MODE_ANALOG 2 +/**@}*/ + +#define GPIO_CNF_PUPD_MASK 2 +#define GPIO_CNF_PUPD_SHIFT 2 + +/** @defgroup gpio_pupd GPIO Output Pin Pullup +@ingroup gpio_defines +@{*/ +#define GPIO_PUPD_NONE 0x0 +#define GPIO_PUPD_PULLDOWN 0x1 +#define GPIO_PUPD_PULLUP 0x2 +/**@}*/ + +#define GPIO_CNF_DRIVE_SHIFT 8 +#define GPIO_CNF_DRIVE_MASK 7 + +/** @addtogroup gpio_drive GPIO drive configuration + * @{ */ + +/** Standard 0, standard 1 */ +#define GPIO_CNF_DRIVE_S0S1 0 + +/** High drive 0, standard 1 */ +#define GPIO_CNF_DRIVE_H0S1 1 + +/** Standard 0, high drive 1 */ +#define GPIO_CNF_DRIVE_S0H1 2 + +/** High drive 0, high drive 1 */ +#define GPIO_CNF_DRIVE_H0H1 3 + +/** Disconnect 0, standard 1 (wired-or connections) */ +#define GPIO_CNF_DRIVE_D0S1 4 + +/** Disconnect 0, high drive 1 (wired-or connections) */ +#define GPIO_CNF_DRIVE_D0H1 5 + +/** Standard 0, disconnect 1 (wired-and connections) */ +#define GPIO_CNF_DRIVE_S0D1 6 + +/** High drive 0, disconnect 1 (wired-and connections) */ +#define GPIO_CNF_DRIVE_H0D1 7 + +/**@}*/ + +#define GPIO_CNF_SENSE_SHIFT 16 +#define GPIO_CNF_SENSE_MASK 3 + +/** @addtogroup gpio_sense GPIO sensing mechanism + * @{ */ + +/** Pin sensing is disabled */ +#define GPIO_CNF_SENSE_DISABLE 0 + +/** Pin sensing is active for high level */ +#define GPIO_CNF_SENSE_HIGH 2 + +/** Pin sensing is active for low level */ +#define GPIO_CNF_SENSE_LOW 3 + +/**@}*/ + +/* GPIO Tasks and Events (GPIOTE) */ +#define GPIO_TASK_OUT(n) MMIO32(GPIOTE_BASE + 0x4 * (n)) +#define GPIO_EVENT_IN(n) MMIO32(GPIOTE_BASE + 0x100 + 0x4 * (n)) + +#define GPIO_EVENT_PORT MMIO32(GPIOTE_BASE + 0x17C) + +#define GPIO_INTEN MMIO32(GPIOTE_BASE + 0x300) +#define GPIO_INTENSET MMIO32(GPIOTE_BASE + 0x304) +#define GPIO_INTENCLR MMIO32(GPIOTE_BASE + 0x308) + +#define GPIO_TE_CONFIG(n) MMIO32(GPIOTE_BASE + 0x510 + 0x4 * (n)) + +/* Register Details */ +#define GPIO_INTEN_IN(n) (1 << (n)) + +#define GPIO_INTEN_PORT (1 << 31) + +/* TODO: clean this up */ + +#define GPIO_TE_CONFIG_MODE_SHIFT 0 +#define GPIO_TE_CONFIG_MODE_MASK 3 + +#define GPIO_TE_CONFIG_PSEL_SHIFT 8 +#define GPIO_TE_CONFIG_PSEL_MASK 0x1f + +#define GPIO_TE_CONFIG_POLARITY_SHIFT 16 +#define GPIO_TE_CONFIG_POLARITY_MASK 3 + +#define GPIO_TE_CONFIG_OUTINIT (1 << 20) + +#define GPIO_TE_MODE_DISABLED 0 +#define GPIO_TE_MODE_EVENT 1 +#define GPIO_TE_MODE_TASK 3 + +#define GPIO_TE_POLARITY_NONE 0 +#define GPIO_TE_POLARITY_LO_TO_HI 1 +#define GPIO_TE_POLARITY_HI_TO_LO 2 +#define GPIO_TE_POLARITY_TOGGLE 3 + +#define GPIO_TE_OUTINIT_LOW 0 +#define GPIO_TE_OUTINIT_HIGH 1 + +/* GPIO number definitions (for convenience) */ +/** @defgroup gpio_pin_id GPIO Pin Identifiers +@ingroup gpio_defines + +@{*/ +#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 GPIO16 (1 << 16) +#define GPIO17 (1 << 17) +#define GPIO18 (1 << 18) +#define GPIO19 (1 << 19) +#define GPIO20 (1 << 20) +#define GPIO21 (1 << 21) +#define GPIO22 (1 << 22) +#define GPIO23 (1 << 23) +#define GPIO24 (1 << 24) +#define GPIO25 (1 << 25) +#define GPIO26 (1 << 26) +#define GPIO27 (1 << 27) +#define GPIO28 (1 << 28) +#define GPIO29 (1 << 29) +#define GPIO30 (1 << 30) +#define GPIO31 (1 << 31) +#define GPIO_ALL 0xffffffff +/**@}*/ + +/**@}*/ +BEGIN_DECLS + +void gpio_set(uint32_t gpioport, uint32_t gpios); +void gpio_clear(uint32_t gpioport, uint32_t gpios); +uint32_t gpio_get(uint32_t gpioport, uint32_t gpios); +void gpio_toggle(uint32_t gpioport, uint32_t gpios); + +void gpio_mode_setup(uint32_t gpioport, uint32_t mode, uint32_t pull_up_down, + uint32_t gpios); + +void gpio_set_options(uint32_t gpioport, uint32_t drive, uint32_t sense, + uint32_t gpios); + +void gpio_configure_task(uint8_t task_num, + uint8_t pin_num, uint8_t polarity, uint32_t init); + +void gpio_configure_event(uint8_t event_num, uint8_t pin_num, uint8_t polarity); + +void gpio_enable_interrupts(uint32_t mask); +void gpio_disable_interrupts(uint32_t mask); +void gpio_clear_interrupts(void); + +END_DECLS + + diff --git a/include/libopencm3/nrf/common/i2c.h b/include/libopencm3/nrf/common/i2c.h new file mode 100644 index 00000000..26c3c601 --- /dev/null +++ b/include/libopencm3/nrf/common/i2c.h @@ -0,0 +1,128 @@ +/** @addtogroup i2c_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +/**@{*/ + +/* I2C bus */ +/** @addtogroup i2c_block I2C instances + * @{ + */ + +#define I2C0 I2C0_BASE +#define I2C1 I2C1_BASE + +/**@}*/ + +/* Tasks */ + +#define I2C_TASK_STARTRX(i2c) MMIO32((i2c) + 0x000) +#define I2C_TASK_STARTTX(i2c) MMIO32((i2c) + 0x008) +#define I2C_TASK_STOP(i2c) MMIO32((i2c) + 0x014) +#define I2C_TASK_SUSPEND(i2c) MMIO32((i2c) + 0x01c) +#define I2C_TASK_RESUME(i2c) MMIO32((i2c) + 0x020) +/* Events */ + +#define I2C_EVENT_STOPPED(i2c) MMIO32((i2c) + 0x104) +#define I2C_EVENT_RXDREADY(i2c) MMIO32((i2c) + 0x108) +#define I2C_EVENT_TXDSENT(i2c) MMIO32((i2c) + 0x11c) +#define I2C_EVENT_ERROR(i2c) MMIO32((i2c) + 0x124) +#define I2C_EVENT_BB(i2c) MMIO32((i2c) + 0x138) +#define I2C_EVENT_SUSPENDED(i2c) MMIO32((i2c) + 0x148) +/* Registers */ + +#define I2C_SHORTS(i2c) MMIO32((i2c) + 0x200) +#define I2C_INTEN(i2c) MMIO32((i2c) + 0x300) +#define I2C_INTENSET(i2c) MMIO32((i2c) + 0x304) +#define I2C_INTENCLR(i2c) MMIO32((i2c) + 0x308) +#define I2C_ERRORSRC(i2c) MMIO32((i2c) + 0x4c4) +#define I2C_ENABLE(i2c) MMIO32((i2c) + 0x500) +#define I2C_PSELSCL(i2c) MMIO32((i2c) + 0x508) +#define I2C_PSELSDA(i2c) MMIO32((i2c) + 0x50c) +#define I2C_RXD(i2c) MMIO32((i2c) + 0x518) +#define I2C_TXD(i2c) MMIO32((i2c) + 0x51c) +#define I2C_FREQUENCY(i2c) MMIO32((i2c) + 0x524) +#define I2C_ADDRESS(i2c) MMIO32((i2c) + 0x588) + +/* Register Contents */ + +/** @addtogroup i2c_shorts I2C event -> task shortcuts + * @{ + */ +#define I2C_SHORTS_BB_SUSPEND (1 << 0) +#define I2C_SHORTS_BB_STOP (1 << 1) + +/**@}*/ + +/** @addtogroup i2c_interrupts I2C interrupts + * @{ + */ +#define I2C_INTEN_STOPPED (1 << 1) +#define I2C_INTEN_RXDREADY (1 << 2) +#define I2C_INTEN_TXDSENT (1 << 7) +#define I2C_INTEN_ERROR (1 << 9) +#define I2C_INTEN_BB (1 << 14) + +/**@}*/ + +#define I2C_ERRORSRC_OVERRUN (1 << 0) +#define I2C_ERRORSRC_ANACK (1 << 1) +#define I2C_ERRORSRC_DNACK (1 << 2) + +#define I2C_ENABLE_VALUE (5) + +#define I2C_FREQUENCY_100K (0x01980000) +#define I2C_FREQUENCY_250K (0x04000000) +#define I2C_FREQUENCY_400K (0x06680000) + +#define I2C_PSEL_OFF (0xffffffff) + +/**@}*/ + +BEGIN_DECLS + +void i2c_enable(uint32_t i2c); +void i2c_disable(uint32_t i2c); +void i2c_start_tx(uint32_t i2c, uint8_t data); +void i2c_start_rx(uint32_t i2c); +void i2c_send_stop(uint32_t i2c); +void i2c_set_fast_mode(uint32_t i2c); +void i2c_set_standard_mode(uint32_t i2c); +void i2c_set_frequency(uint32_t i2c, uint32_t freq); +void i2c_send_data(uint32_t i2c, uint8_t data); +uint8_t i2c_get_data(uint32_t i2c); +void i2c_select_pins(uint32_t i2c, uint32_t scl_pin, uint32_t sda_pin); +void i2c_set_address(uint32_t i2c, uint8_t addr); +void i2c_resume(uint32_t i2c); + +END_DECLS + + diff --git a/include/libopencm3/nrf/common/memorymap.h b/include/libopencm3/nrf/common/memorymap.h new file mode 100644 index 00000000..61c719a7 --- /dev/null +++ b/include/libopencm3/nrf/common/memorymap.h @@ -0,0 +1,97 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include + +/* Factory Information Configuration Registers */ +#define FICR_BASE (0x10000000U) + +/* User Information Configuration Registers */ +#define UICR_BASE (0x10001000U) + +#define APB_BASE (0x40000000U) +#define AHB_BASE (0x50000000U) +#define PPB_BASE (0xE0000000U) + + +#define CLOCK_BASE (APB_BASE) + +/* Power Control */ +#define POWER_BASE (APB_BASE) + +/* 2.4 GHz Radio */ +#define RADIO_BASE (APB_BASE + 0x1000) + +#define UART0_BASE (APB_BASE + 0x2000) + +#define SPI0_BASE (APB_BASE + 0x3000) +#define TWI0_BASE (APB_BASE + 0x3000) +#define I2C0_BASE (APB_BASE + 0x3000) + +#define SPI1_BASE (APB_BASE + 0x4000) +#define SPIS1_BASE (APB_BASE + 0x4000) +#define TWI1_BASE (APB_BASE + 0x4000) +#define I2C1_BASE (APB_BASE + 0x4000) + +#define GPIOTE_BASE (APB_BASE + 0x6000) + +#define ADC_BASE (APB_BASE + 0x7000) + +#define TIMER0_BASE (APB_BASE + 0x8000) +#define TIMER1_BASE (APB_BASE + 0x9000) +#define TIMER2_BASE (APB_BASE + 0xA000) + +#define RTC0_BASE (APB_BASE + 0xB000) + +#define TEMP_BASE (APB_BASE + 0xC000) + +#define RNG_BASE (APB_BASE + 0xD000) + +/* AES ECB Mode Encryption */ +#define ECB_BASE (APB_BASE + 0xE000) + +/* Accelerated Address Resolver */ +#define AAR_BASE (APB_BASE + 0xF000) + +/* AES CCM Mode Encryption */ +#define CCM_BASE (APB_BASE + 0xF000) + +#define WDT_BASE (APB_BASE + 0x10000) +#define RTC1_BASE (APB_BASE + 0x11000) +#define QDEC_BASE (APB_BASE + 0x12000) +#define LPCOMP_BASE (APB_BASE + 0x13000) +#define SWI0_BASE (APB_BASE + 0x14000) +#define SWI1_BASE (APB_BASE + 0x15000) +#define SWI2_BASE (APB_BASE + 0x16000) +#define SWI3_BASE (APB_BASE + 0x17000) +#define SWI4_BASE (APB_BASE + 0x18000) +#define SWI5_BASE (APB_BASE + 0x19000) + +/* Non-Volatile Memory Controller */ +#define NVMC_BASE (APB_BASE + 0x1E000) +#define PPI_BASE (APB_BASE + 0x1F000) +#define RTC2_BASE (APB_BASE + 0x24000) + +#define GPIO_BASE (AHB_BASE) + +#define NVMC_BASE (APB_BASE + 0x1E000) + diff --git a/include/libopencm3/nrf/common/periph.h b/include/libopencm3/nrf/common/periph.h new file mode 100644 index 00000000..60b3119b --- /dev/null +++ b/include/libopencm3/nrf/common/periph.h @@ -0,0 +1,148 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Common Peripheral Interface. + * The implementation only applies to peripherals on APB + * bus, which for this part excludes only GPIO. + */ + +/* Peripheral IDs + * + * For peripherals on the APB bus there is a direct relationship between its ID + * and its base address. A peripheral with base address 0x40000000 is therefore + * assigned ID=0, and a peripheral with base address 0x40001000 is assigned + * ID=1. The peripheral with base address 0x4001F000 is assigned ID=31 + */ + +#define PERIPH_CLOCK_ID (0x00) +#define PERIPH_POWER_ID (0x00) +#define PERIPH_MPU_ID (0x00) +#define PERIPH_RADIO_ID (0x01) +#define PERIPH_UART_ID (0x02) +#define PERIPH_SPI0_ID (0x03) +#define PERIPH_TWI0_ID (0x03) +#define PERIPH_I2C0_ID (0x03) +#define PERIPH_SPI1_ID (0x04) +#define PERIPH_SPIS1_ID (0x04) +#define PERIPH_TWI1_ID (0x04) +#define PERIPH_I2C1_ID (0x04) +#define PERIPH_GPIOTE_ID (0x06) +#define PERIPH_ADC_ID (0x07) +#define PERIPH_TIMER0_ID (0x08) +#define PERIPH_TIMER1_ID (0x09) +#define PERIPH_TIMER2_ID (0x0a) +#define PERIPH_RTC0_ID (0x0b) +#define PERIPH_TEMP_ID (0x0c) +#define PERIPH_RNG_ID (0x0d) +#define PERIPH_ECB_ID (0x0e) +#define PERIPH_AAR_ID (0x0f) +#define PERIPH_CCM_ID (0x0f) +#define PERIPH_WDT_ID (0x10) +#define PERIPH_RTC1_ID (0x11) +#define PERIPH_QDEC_ID (0x12) +#define PERIPH_LPCOMP_ID (0x13) +#define PERIPH_SWI0_ID (0x14) +#define PERIPH_SWI1_ID (0x15) +#define PERIPH_SWI2_ID (0x16) +#define PERIPH_SWI3_ID (0x17) +#define PERIPH_SWI4_ID (0x18) +#define PERIPH_SWI5_ID (0x19) +#define PERIPH_NVMC_ID (0x1e) +#define PERIPH_PPI_ID (0x1f) + +#define PERIPH_BASE_FROM_ID(periph_id) (ABP_BASE + 0x1000 * (periph_id)) +#define PERIPH_ID_FROM_BASE(base) (((base) - APB_BASE) >> 12) +#define PERIPH_BASE_FROM_REG(reg) (((uint32_t) &(reg)) & 0xfffff000) + +/* + * Tasks are used to trigger actions in a peripheral, for example, to start a + * particular behavior. A peripheral can implement multiple tasks with each + * task having a separate register in that peripheral's task register group. + * + * A task is triggered when firmware writes a '1' to the task register or when + * the peripheral itself, or another peripheral, toggles the corresponding task + * signal. + */ + +/** Starting address of all the tasks in the peripheral. */ +#define PERIPH_TASK_OFFSET (0x000) + +/* + * Events are used to notify peripherals and the CPU about events that have + * happened, for example, a state change in a peripheral. A peripheral may + * generate multiple events with each event having a separate register in that + * peripheral’s event register group. An event is generated when the + * peripheral itself toggles the corresponding event signal, whereupon the + * event register is updated to reflect that the event has been generated. + */ + +/** Starting address of all the events in the peripheral. */ +#define PERIPH_EVENT_OFFSET (0x100) + +#define PERIPH_TRIGGER_TASK(task) (task) = (1) + +/* All peripherals on the APB bus support interrupts. A peripheral only + * occupies one interrupt, and the interrupt number follows the peripheral ID, + * for example, the peripheral with ID=4 is connected to interrupt number 4 in + * the Nested Vector Interrupt Controller (NVIC). + */ + +#define PERIPH_ENABLE_IRQ(base) nvic_enable_irq(periph_id_from_base(base)) +#define PERIPH_DISABLE_IRQ(base) nvic_disable_irq(periph_id_from_base(base)) + +/* Common regisgers. Not all peripherals have these registers, but when they + * are present, they are at this offset. + */ +#define PERIPH_SHORTS_OFFSET (0x200) +#define PERIPH_INTEN_OFFSET (0x300) +#define PERIPH_INTENSET_OFFSET (0x304) +#define PERIPH_INTENCLR_OFFSET (0x308) + +#define _PERIPH_SHORTS(base) MMIO32((base) + PERIPH_SHORTS_OFFSET) +#define _PERIPH_INTEN(base) MMIO32((base) + PERIPH_INTEN_OFFSET) +#define _PERIPH_INTENSET(base) MMIO32((base) + PERIPH_INTENSET_OFFSET) +#define _PERIPH_INTENCLR(base) MMIO32((base) + PERIPH_INTENCLR_OFFSET) + +/* TODO: convert these to functions */ +#define periph_enable_shorts(base, shorts) periph_shorts(base) |= (shorts) +#define periph_disable_shorts(base, shorts) periph_shorts(base) &= (~(shorts)) +#define periph_clear_shorts(base) periph_shorts(base) = (0) + +#define periph_enable_interrupts(base, mask) periph_intenset(base) |= (mask) +#define periph_disable_interrupts(base, mask) periph_intenclr(base) = (mask) +#define periph_clear_interrupts(base) periph_intenclr(base) = (0xffffffff) + +/** Mark the signal as not connected to any pin. */ +#define GPIO_UNCONNECTED 0xFFFFFFFFU + +/** This is an approximation of log2. As used here, works correctly + * only for single bit set, which should be the case when used to. + * convert above GPIOxy macros to pin numbers as needed for PSEL + * registers of peripherals. + */ +#define __GPIO2PIN(x) (31 - __builtin_clz((uint32_t) (x))) + + diff --git a/include/libopencm3/nrf/common/power.h b/include/libopencm3/nrf/common/power.h new file mode 100644 index 00000000..61bfff27 --- /dev/null +++ b/include/libopencm3/nrf/common/power.h @@ -0,0 +1,106 @@ +/** @addtogroup power_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +/**@{*/ + +/* Tasks */ +#define POWER_TASK_CONSTLAT MMIO32(POWER_BASE + 0x078) +#define POWER_TASK_LOWPWR MMIO32(POWER_BASE + 0x07C) + +/* Events */ +#define POWER_EVENT_POFWARN MMIO32(POWER_BASE + 0x108) + +/* Registers */ +#define POWER_INTENSET _PERIPH_INTENSET(POWER_BASE) +#define POWER_INTENCLR _PERIPH_INTENCLR(POWER_BASE) +#define POWER_RESETREAS MMIO32(POWER_BASE + 0x400) +#define POWER_RAMSTATUS MMIO32(POWER_BASE + 0x428) +#define POWER_SYSTEMOFF MMIO32(POWER_BASE + 0x500) +#define POWER_POFCON MMIO32(POWER_BASE + 0x510) +#define POWER_GPREGRET MMIO32(POWER_BASE + 0x51C) +#define POWER_RAMON MMIO32(POWER_BASE + 0x524) +#define POWER_RESET MMIO32(POWER_BASE + 0x544) +#define POWER_RAMONB MMIO32(POWER_BASE + 0x554) +#define POWER_DCDCEN MMIO32(POWER_BASE + 0x578) + +/* Register Contents */ +#define POWER_INTEN_POFWARN (1 << 2) + +#define POWER_RESETREAS_RESETPIN (1 << 0) +#define POWER_RESETREAS_DOG (1 << 1) +#define POWER_RESETREAS_SREQ (1 << 2) +#define POWER_RESETREAS_LOCKUP (1 << 3) + +#define POWER_RESETREAS_OFF (1 << 16) +#define POWER_RESETREAS_LPCOMP (1 << 17) +#define POWER_RESETREAS_DIF (1 << 18) + +#define POWER_RAMSTATUS_RAMBLOCK(n) (1 << (n)) +#define POWER_RAMSTATUS_RAMBLOCK0 POWER_RAMSTATUS_RAMBLOCK(0) +#define POWER_RAMSTATUS_RAMBLOCK1 POWER_RAMSTATUS_RAMBLOCK(1) +#define POWER_RAMSTATUS_RAMBLOCK2 POWER_RAMSTATUS_RAMBLOCK(2) +#define POWER_RAMSTATUS_RAMBLOCK3 POWER_RAMSTATUS_RAMBLOCK(3) + +#define POWER_SYSTEMOFF_SYSTEMOFF (1 << 0) + +#define POWER_POFCON_POF (1 << 0) +#define POWER_POFCON_THRESHOLD_SHIFT (1) +#define POWER_POFCON_THRESHOLD_MASK (3 << POWER_POFCON_THRESHOLD_SHIFT) +#define POWER_POFCON_THRESHOLD_MASKED(V) (((V) << POWER_POFCON_THRESHOLD_SHIFT) \ + & POWER_POFCON_THRESHOLD_MASK) + +#define POWER_RAMON_ONRAM0 (1 << 0) +#define POWER_RAMON_ONRAM1 (1 << 1) + +#define POWER_RAMON_OFFRAM0 (1 << 16) +#define POWER_RAMON_OFFRAM1 (1 << 17) + +#define POWER_RAMONB_ONRAM2 (1 << 2) +#define POWER_RAMONB_ONRAM3 (3 << 3) + +#define POWER_RAMONB_OFFRAM2 (1 << 16) +#define POWER_RAMONB_OFFRAM3 (3 << 37) + +#define POWER_RESET_RESET (1 << 0) + +#define POWER_DCDCEN_DCDCEN (1 << 0) + + +enum power_pofcon_threshold { + POWER_POFCON_THRESHOLD_V21, + POWER_POFCON_THRESHOLD_V23, + POWER_POFCON_THRESHOLD_V25, + POWER_POFCON_THRESHOLD_V27, +}; + +/**@}*/ + diff --git a/include/libopencm3/nrf/common/ppi.h b/include/libopencm3/nrf/common/ppi.h new file mode 100644 index 00000000..c5bbc725 --- /dev/null +++ b/include/libopencm3/nrf/common/ppi.h @@ -0,0 +1,147 @@ +/** @addtogroup ppi_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +/**@{*/ + +/* Programmable Peripheral Interconnect */ + +/* Tasks */ + +#define PPI_TASK_CHG_EN(n) MMIO32(PPI_BASE + 0x8 * (n)) +#define PPI_TASK_CHG_DIS(n) MMIO32(PPI_BASE + 0x8 * (n) + 0x4) + +/* Registers */ + +#define PPI_CHEN MMIO32(PPI_BASE + 0x500) +#define PPI_CHENSET MMIO32(PPI_BASE + 0x504) +#define PPI_CHENCLR MMIO32(PPI_BASE + 0x508) + +/* Event End Point n = 0 .. 15 */ +#define PPI_CH_EEP(n) MMIO32(PPI_BASE + 0x510 + 0x8 * (n)) +/* Task End Point n = 0 .. 15 */ +#define PPI_CH_TEP(n) MMIO32(PPI_BASE + 0x514 + 0x8 * (n)) + +/* Channel Groups */ +#define PPI_CHG(n) MMIO32(PPI_BASE + 0x800 + 0x4 * (n)) + +#define PPI_CH(n) (1 << (n)) +/** @addtogroup PPI Channel identifiers + * @{ + */ +#define PPI_CH0 (1 << 0) +#define PPI_CH1 (1 << 1) +#define PPI_CH2 (1 << 2) +#define PPI_CH3 (1 << 3) +#define PPI_CH4 (1 << 4) +#define PPI_CH5 (1 << 5) +#define PPI_CH6 (1 << 6) +#define PPI_CH7 (1 << 7) +#define PPI_CH8 (1 << 8) +#define PPI_CH9 (1 << 9) +#define PPI_CH10 (1 << 10) +#define PPI_CH11 (1 << 11) +#define PPI_CH12 (1 << 12) +#define PPI_CH13 (1 << 13) +#define PPI_CH14 (1 << 14) +#define PPI_CH15 (1 << 15) +/* Channels 16-19 are reserved */ +#define PPI_CH20 (1 << 20) +#define PPI_CH21 (1 << 21) +#define PPI_CH22 (1 << 22) +#define PPI_CH23 (1 << 23) +#define PPI_CH24 (1 << 24) +#define PPI_CH25 (1 << 25) +#define PPI_CH26 (1 << 26) +#define PPI_CH27 (1 << 27) +#define PPI_CH28 (1 << 28) +#define PPI_CH29 (1 << 29) +#define PPI_CH30 (1 << 30) +#define PPI_CH31 (1 << 31) + +/**@}*/ + +#define PPI_MAX_PROG_CHANNEL (15) + +/* Preprogrammed channels */ +/* TIMER0->EVENTS_COMPARE0 -- RADIO->TASKS_TXEN */ +#define PPI_CH_TMR0CC0_RADIOTXEN PPI_CH20 + +/* TIMER0->EVENTS_COMPARE0 -- RADIO->TASKS_RXEN */ +#define PPI_CH_TMR0CC0_RADIORXEN PPI_CH21 + +/* TIMER0->EVENTS_COMPARE1 -- RADIO->TASKS_DISABLE */ +#define PPI_CH_TMR0CC1_RADIODIS PPI_CH22 + +/* RADIO->EVENTS_BCMATCH -- AAR->TASKS_START */ +#define PPI_CH_RADIOBCMATCH_AARSTART PPI_CH23 + +/* RADIO->EVENTS_READY -- CCM->TASKS_KSGEN */ +#define PPI_CH_RADIOREADY_CCMKSGEN PPI_CH24 + +/* RADIO->EVENTS_ADDRESS -- CCM->TASKS_CRYPT */ +#define PPI_CH_RADIOADDR_CCMCRYPT PPI_CH25 + +/* RADIO->EVENTS_ADDRESS -- TIMER0->TASKS_CAPTURE1 */ +#define PPI_CH_RADIOADDR_TMR0CAPT1 PPI_CH26 + +/* RADIO->EVENTS_END -- TIMER0->TASKS_CAPTURE2 */ +#define PPI_CH_RADIOEND_TMR0CAPT2 PPI_CH27 + +/* RTC0->EVENTS_COMPARE[0] -- RADIO->TASKS_TXEN */ +#define PPI_CH_RTC0CC0_RADIOTXEN PPI_CH28 + +/* RTC0->EVENTS_COMPARE[0] -- RADIO->TASKS_RXEN */ +#define PPI_CH_RTC0CC0_RADIORXEN PPI_CH29 + +/* RTC0->EVENTS_COMPARE[0] -- TIMER0->TASKS_CLEAR */ +#define PPI_CH_RTC0CC0_TMR0CLEAR PPI_CH30 + +/* RTC0->EVENTS_COMPARE[0] -- TIMER0->TASKS_START */ +#define PPI_CH_RTC0CC0_TMR0START PPI_CH31 +/**@}*/ + +BEGIN_DECLS + +void ppi_configure_channel(uint8_t chan_num, uint32_t eep, uint32_t tep); +void ppi_enable_channels(uint32_t channels); +void ppi_disable_channels(uint32_t channels); + +void ppi_set_group(uint8_t group, uint32_t channels); +void ppi_enable_group(uint8_t group); +void ppi_disable_group(uint8_t group); + +/* Simpler API, that requires the client to store channel map. */ +uint8_t ppi_add_channel(uint32_t *chan_map, uint32_t eep, uint32_t tep, bool enable); +void ppi_remove_channel(uint32_t *chan_map, uint8_t chan_num); + +END_DECLS + + diff --git a/include/libopencm3/nrf/common/radio.h b/include/libopencm3/nrf/common/radio.h new file mode 100644 index 00000000..b8ab5bbb --- /dev/null +++ b/include/libopencm3/nrf/common/radio.h @@ -0,0 +1,325 @@ +/** @addtogroup radio_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +/**@{*/ + +/* 2.4 GHz Radio */ + +/* Tasks */ + +#define RADIO_TASK_TXEN MMIO32(RADIO_BASE + 0x000) +#define RADIO_TASK_RXEN MMIO32(RADIO_BASE + 0x004) +#define RADIO_TASK_START MMIO32(RADIO_BASE + 0x008) +#define RADIO_TASK_STOP MMIO32(RADIO_BASE + 0x00C) +#define RADIO_TASK_DISABLE MMIO32(RADIO_BASE + 0x010) +#define RADIO_TASK_RSSISTART MMIO32(RADIO_BASE + 0x014) +#define RADIO_TASK_RSSISTOP MMIO32(RADIO_BASE + 0x018) +#define RADIO_TASK_BCSTART MMIO32(RADIO_BASE + 0x01C) +#define RADIO_TASK_BCSTOP MMIO32(RADIO_BASE + 0x020) + +/* Events */ + +#define RADIO_EVENT_READY MMIO32(RADIO_BASE + 0x100) +#define RADIO_EVENT_ADDRESS MMIO32(RADIO_BASE + 0x104) +#define RADIO_EVENT_PAYLOAD MMIO32(RADIO_BASE + 0x108) +#define RADIO_EVENT_END MMIO32(RADIO_BASE + 0x10C) +#define RADIO_EVENT_DISABLED MMIO32(RADIO_BASE + 0x110) +#define RADIO_EVENT_DEVMATCH MMIO32(RADIO_BASE + 0x114) +#define RADIO_EVENT_DEVMISS MMIO32(RADIO_BASE + 0x118) +#define RADIO_EVENT_RSSIEND MMIO32(RADIO_BASE + 0x11C) + +/* Registers */ + +#define RADIO_SHORTS _PERIPH_SHORTS(RADIO_BASE) +#define RADIO_INTENSET _PERIPH_INTENSET(RADIO_BASE) +#define RADIO_INTENCLR _PERIPH_INTENCLR(RADIO_BASE) +#define RADIO_CRCSTATUS MMIO32(RADIO_BASE + 0x400) +#define RADIO_RXMATCH MMIO32(RADIO_BASE + 0x408) +#define RADIO_RXCRC MMIO32(RADIO_BASE + 0x40C) +#define RADIO_DAI MMIO32(RADIO_BASE + 0x410) +#define RADIO_PACKETPTR MMIO32(RADIO_BASE + 0x504) +#define RADIO_FREQUENCY MMIO32(RADIO_BASE + 0x508) +#define RADIO_TXPOWER MMIO32(RADIO_BASE + 0x50C) +#define RADIO_MODE MMIO32(RADIO_BASE + 0x510) +#define RADIO_PCNF0 MMIO32(RADIO_BASE + 0x514) +#define RADIO_PCNF1 MMIO32(RADIO_BASE + 0x518) +#define RADIO_BASE0 MMIO32(RADIO_BASE + 0x51C) +#define RADIO_BASE1 MMIO32(RADIO_BASE + 0x520) +#define RADIO_PREFIX0 MMIO32(RADIO_BASE + 0x524) +#define RADIO_PREFIX1 MMIO32(RADIO_BASE + 0x528) +#define RADIO_TXADDRESS MMIO32(RADIO_BASE + 0x52C) +#define RADIO_RXADDRESSES MMIO32(RADIO_BASE + 0x530) +#define RADIO_CRCCNF MMIO32(RADIO_BASE + 0x534) +#define RADIO_CRCPOLY MMIO32(RADIO_BASE + 0x538) +#define RADIO_CRCINIT MMIO32(RADIO_BASE + 0x53C) +#define RADIO_TEST MMIO32(RADIO_BASE + 0x540) +#define RADIO_TIFS MMIO32(RADIO_BASE + 0x544) +#define RADIO_RSSISAMPLE MMIO32(RADIO_BASE + 0x548) +#define RADIO_STATE MMIO32(RADIO_BASE + 0x550) +#define RADIO_DATAWHITEIV MMIO32(RADIO_BASE + 0x554) +#define RADIO_BCC MMIO32(RADIO_BASE + 0x560) + +/* Device Address Base segment */ +#define RADIO_DAB(n) MMIO32(RADIO_BASE + 0x600 + 0x4 * (n)) +/* Device Address Prefix segment */ +#define RADIO_DAP(n) MMIO32(RADIO_BASE + 0x620 + 0x4 * (n)) +#define RADIO_DACNF MMIO32(RADIO_BASE + 0x640) + +/* Override Registers */ +#define RADIO_OVERRIDE(n) MMIO32(RADIO_BASE + 0x724 + 0x4 * (n)) +#define RADIO_POWER MMIO32(RADIO_BASE + 0xFFC) + +/* Register Details */ + +/** @addtogroup radio_shorts Radio event -> task shortcuts + * @{ + */ +#define RADIO_SHORTS_READY_START (1 << 0) +#define RADIO_SHORTS_END_DISABLE (1 << 1) +#define RADIO_SHORTS_DISABLED_TXEN (1 << 2) +#define RADIO_SHORTS_DISABLED_RXEN (1 << 3) +#define RADIO_SHORTS_ADDRESS_RSSISTART (1 << 4) +#define RADIO_SHORTS_END_START (1 << 5) +#define RADIO_SHORTS_ADDRESS_BCSTART (1 << 6) +#define RADIO_SHORTS_DISABLED_RSSISTOP (1 << 8) + +/**@}*/ + +/** @addtogroup radio_inten Radio interrupts + * @{ + */ +#define RADIO_INTEN_READY (1 << 0) +#define RADIO_INTEN_ADDRESS (1 << 1) +#define RADIO_INTEN_PAYLOAD (1 << 2) +#define RADIO_INTEN_END (1 << 3) +#define RADIO_INTEN_DISABLED (1 << 4) +#define RADIO_INTEN_DEVMATCH (1 << 5) +#define RADIO_INTEN_DEVMISS (1 << 6) +#define RADIO_INTEN_RSSIEND (1 << 7) +#define RADIO_INTEN_BCMATCH (1 << 10) + +/**@}*/ + +#define RADIO_PCNF0_LFLEN_SHIFT (0) +#define RADIO_PCNF0_LFLEN_MASK (0xf << RADIO_PCNF0_LFLEN_SHIFT) +#define RADIO_PCNF0_LFLEN_MASKED(V) (((V) << RADIO_PCNF0_LFLEN_SHIFT) \ + & RADIO_PCNF0_LFLEN_MASK) + +#define RADIO_PCNF0_S0LEN_SHIFT (8) +#define RADIO_PCNF0_S0LEN_MASK (1 << RADIO_PCNF0_S0LEN_SHIFT) +#define RADIO_PCNF0_S0LEN_MASKED(V) (((V) << RADIO_PCNF0_S0LEN_SHIFT) \ + & RADIO_PCNF0_S0LEN_MASK) + +#define RADIO_PCNF0_S1LEN_SHIFT (16) +#define RADIO_PCNF0_S1LEN_MASK (0xf << RADIO_PCNF0_S1LEN_SHIFT) +#define RADIO_PCNF0_S1LEN_MASKED(V) (((V) << RADIO_PCNF0_S1LEN_SHIFT) & \ + RADIO_PCNF0_S1LEN_MASK) + +#define RADIO_PCNF1_MAXLEN_SHIFT (0) +#define RADIO_PCNF1_MAXLEN_MASK (0xff << RADIO_PCNF1_MAXLEN_SHIFT) +#define RADIO_PCNF1_MAXLEN_MASKED(V) (((V) << RADIO_PCNF1_MAXLEN_SHIFT) & \ + RADIO_PCNF1_MAXLEN_MASK) + +#define RADIO_PCNF1_STATLEN_SHIFT (8) +#define RADIO_PCNF1_STATLEN_MASK (0xff << RADIO_PCNF1_STATLEN_SHIFT) +#define RADIO_PCNF1_STATLEN_MASKED(V) (((V) << RADIO_PCNF1_STATLEN_SHIFT) & \ + RADIO_PCNF1_STATLEN_MASK) + +#define RADIO_PCNF1_BALEN_SHIFT (16) +#define RADIO_PCNF1_BALEN_MASK (7 << RADIO_PCNF1_BALEN_SHIFT) +#define RADIO_PCNF1_BALEN_MASKED(V) (((V) << RADIO_PCNF1_BALEN_SHIFT) & \ + RADIO_PCNF1_BALEN_MASK) + +#define RADIO_PCNF1_ENDIAN_BIG (1 << 24) +#define RADIO_PCNF1_WHITEEN (1 << 25) + +#define RADIO_PREFIX0_AP0_SHIFT (0) +#define RADIO_PREFIX0_AP0_MASK (0xff << RADIO_PREFIX0_AP0_SHIFT) +#define RADIO_PREFIX0_AP0_MASKED(V) (((V) << RADIO_PREFIX0_AP0_SHIFT) & \ + RADIO_PREFIX0_AP0_MASK) + +#define RADIO_PREFIX0_AP1_SHIFT (8) +#define RADIO_PREFIX0_AP1_MASK (0xff << RADIO_PREFIX0_AP1_SHIFT) +#define RADIO_PREFIX0_AP1_MASKED(V) (((V) << RADIO_PREFIX0_AP1_SHIFT) & \ + RADIO_PREFIX0_AP1_MASK) + +#define RADIO_PREFIX0_AP2_SHIFT (16) +#define RADIO_PREFIX0_AP2_MASK (0xff << RADIO_PREFIX0_AP2_SHIFT) +#define RADIO_PREFIX0_AP2_MASKED(V) (((V) << RADIO_PREFIX0_AP2_SHIFT) & \ + RADIO_PREFIX0_AP2_MASK) + +#define RADIO_PREFIX0_AP3_SHIFT (24) +#define RADIO_PREFIX0_AP3_MASK (0xff << RADIO_PREFIX0_AP3_SHIFT) +#define RADIO_PREFIX0_AP3_MASKED(V) (((V) << RADIO_PREFIX0_AP3_SHIFT) & \ + RADIO_PREFIX0_AP3_MASK) + +#define RADIO_PREFIX1_AP4_SHIFT (0) +#define RADIO_PREFIX1_AP4_MASK (0xff << RADIO_PREFIX1_AP4_SHIFT) +#define RADIO_PREFIX1_AP4_MASKED(V) (((V) << RADIO_PREFIX1_AP4_SHIFT) & \ + RADIO_PREFIX1_AP4_MASK) + +#define RADIO_PREFIX1_AP5_SHIFT (8) +#define RADIO_PREFIX1_AP5_MASK (0xff << RADIO_PREFIX1_AP5_SHIFT) +#define RADIO_PREFIX1_AP5_MASKED(V) (((V) << RADIO_PREFIX1_AP5_SHIFT) & \ + RADIO_PREFIX1_AP5_MASK) + +#define RADIO_PREFIX1_AP6_SHIFT (16) +#define RADIO_PREFIX1_AP6_MASK (0xff << RADIO_PREFIX1_AP6_SHIFT) +#define RADIO_PREFIX1_AP6_MASKED(V) (((V) << RADIO_PREFIX1_AP6_SHIFT) & \ + RADIO_PREFIX1_AP6_MASK) + +#define RADIO_PREFIX1_AP7_SHIFT (24) +#define RADIO_PREFIX1_AP7_MASK (0xff << RADIO_PREFIX1_AP7_SHIFT) +#define RADIO_PREFIX1_AP7_MASKED(V) (((V) << RADIO_PREFIX1_AP7_SHIFT) & \ + RADIO_PREFIX1_AP7_MASK) + +#define RADIO_PREFIX_AP(n) ((n) < 4 ? RADIO_PREFIX0 : RADIO_PREFIX1) +#define RADIO_PREFIX_AP_SHIFT(n) (8 * (n & 3)) +#define RADIO_PREFIX_AP_MASK(n) (0xff << RADIO_PREFIX_AP_SHIFT(n)) +#define RADIO_PREFIX_AP_MASKED(n, V) (((V) << RADIO_PREFIX_AP_SHIFT(n)) & \ + RADIO_PREFIX_AP_MASK(n)) + +/* TODO: Get rid of this */ +#define RADIO_PREFIX_AP_SET(n, V) if ((n) < 4) {\ + RADIO_PREFIX0 = (V); } \ + else {\ + RADIO_PREFIX1 = (V); } + +#define RADIO_TXADDRESSES_ADDR0 (1 << 0) +#define RADIO_TXADDRESSES_ADDR1 (1 << 1) +#define RADIO_TXADDRESSES_ADDR2 (1 << 2) +#define RADIO_TXADDRESSES_ADDR3 (1 << 3) +#define RADIO_TXADDRESSES_ADDR4 (1 << 4) +#define RADIO_TXADDRESSES_ADDR5 (1 << 5) +#define RADIO_TXADDRESSES_ADDR6 (1 << 6) +#define RADIO_TXADDRESSES_ADDR7 (1 << 7) +#define RADIO_TXADDRESSES_ADDR(n) (1 << (n)) + +#define RADIO_CRCCNF_LEN_SHIFT (0) +#define RADIO_CRCCNF_LEN_MASK (3 << RADIO_CRCCNF_LEN_SHIFT) +#define RADIO_CRCCNF_LEN_MASKED(V) (((V) << RADIO_CRCCNF_LEN_SHIFT) & \ + RADIO_CRCCNF_LEN_MASK) + +#define RADIO_CRCCNF_SKIPADDR (1 << 8) + +#define RADIO_TEST_CONSTCARRIER (1 << 0) +#define RADIO_TEST_PLLLOCK (1 << 1) + +#define RADIO_DACNF_ENA(n) (1 << (n)) +#define RADIO_DACNF_ENA0 RADIO_DACNF_ENA(0) +#define RADIO_DACNF_ENA1 RADIO_DACNF_ENA(1) +#define RADIO_DACNF_ENA2 RADIO_DACNF_ENA(2) +#define RADIO_DACNF_ENA3 RADIO_DACNF_ENA(3) +#define RADIO_DACNF_ENA4 RADIO_DACNF_ENA(4) +#define RADIO_DACNF_ENA5 RADIO_DACNF_ENA(5) +#define RADIO_DACNF_ENA6 RADIO_DACNF_ENA(6) +#define RADIO_DACNF_ENA7 RADIO_DACNF_ENA(7) + +#define RADIO_DACNF_TXADD(n) (1 << ((n) + 8)) +#define RADIO_DACNF_TXADD0 RADIO_DACNF_TXADD(0) +#define RADIO_DACNF_TXADD1 RADIO_DACNF_TXADD(1) +#define RADIO_DACNF_TXADD2 RADIO_DACNF_TXADD(2) +#define RADIO_DACNF_TXADD3 RADIO_DACNF_TXADD(3) +#define RADIO_DACNF_TXADD4 RADIO_DACNF_TXADD(4) +#define RADIO_DACNF_TXADD5 RADIO_DACNF_TXADD(5) +#define RADIO_DACNF_TXADD6 RADIO_DACNF_TXADD(6) +#define RADIO_DACNF_TXADD7 RADIO_DACNF_TXADD(7) + +/* Override 4 register has special bit and the override value is masked. */ +#define RADIO_OVERRIDE4_ENABLE (1 << 31) +#define RADIO_OVERRIDE4_OVERRIDE_MASK (0x0fffffff) + +#define RADIO_POWER_ENABLED (1) +#define RADIO_POWER_DISABLED (0) + +/* Bluetooth Low Energy parameters */ +#define RADIO_BLE_TIFS (150) +#define RADIO_BLE_CRCLEN (3) +#define RADIO_BLE_CRCPOLY (0x65B) +#define RADIO_BLE_CRCINIT (0x555555) + +enum radio_txpower { + RADIO_TXPOWER_POS_4DBM = 0x4, + RADIO_TXPOWER_0DBM = 0, + RADIO_TXPOWER_NEG_4DBM = 0xFC, + RADIO_TXPOWER_NEG_8DBM = 0xF8, + RADIO_TXPOWER_NEG_12DBM = 0xF4, + RADIO_TXPOWER_NEG_16DBM = 0xF0, + RADIO_TXPOWER_NEG_20DBM = 0xEC, + RADIO_TXPOWER_NEG_30DBM = 0xD8, +}; + +enum radio_state { + RADIO_STATE_DISABLED, + RADIO_STATE_RXRU, + RADIO_STATE_RXIDLE, + RADIO_STATE_RX, + RADIO_STATE_RXDISABLE, + RADIO_STATE_TXRU = 9, + RADIO_STATE_TXIDLE, + RADIO_STATE_TX, + RADIO_STATE_TXDISABLE, +}; + +/**@}*/ + +BEGIN_DECLS + +void radio_configure_ble(void); +void radio_disable_crc(void); +void radio_disable(void); +void radio_enable(void); +void radio_set_crclen(uint8_t crc_len); +void radio_set_lsbfirst(void); +void radio_set_msbfirst(void); +void radio_set_txpower(enum radio_txpower txpower); +void radio_disable_whitening(void); +void radio_enable_whitening(void); +void radio_configure_packet(uint8_t lf_len_bits, uint8_t s0_len_bytes, uint8_t s1_len_bits); +void radio_set_balen(uint8_t ba_len); +void radio_set_frequency(uint8_t freq); +void radio_set_datawhiteiv(uint8_t iv); +void radio_set_addr(uint8_t addr_index, uint32_t base, uint8_t prefix); +void radio_set_tx_address(uint8_t addr_index); +void radio_set_packet_ptr(uint8_t *packet_ptr); +void radio_enable_shorts(uint16_t shorts); +void radio_disable_shorts(uint16_t shorts); +void radio_clear_shorts(void); +void radio_enable_tx(void); +void radio_enable_rx(void); +void radio_set_maxlen(uint8_t maxlen); +void radio_set_crc_skipaddr(bool is_skip_addr); + +END_DECLS + + + diff --git a/include/libopencm3/nrf/common/rtc.h b/include/libopencm3/nrf/common/rtc.h new file mode 100644 index 00000000..8ce9636e --- /dev/null +++ b/include/libopencm3/nrf/common/rtc.h @@ -0,0 +1,85 @@ +/** @addtogroup rtc_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include +/**@{*/ + +/* Only two RTCs on this device. */ +/** @addtogroup rtc_block RTC instances + * @{ + */ +#define RTC0 RTC0_BASE +#define RTC1 RTC1_BASE + +/**@}*/ + +/* Tasks */ +#define RTC_TASK_START(rtc) MMIO32((rtc) + 0x000) +#define RTC_TASK_STOP(rtc) MMIO32((rtc) + 0x004) +#define RTC_TASK_CLEAR(rtc) MMIO32((rtc) + 0x008) +#define RTC_TASK_TRIGOVRFLW(rtc) MMIO32((rtc) + 0x00C) + +/* Events */ +#define RTC_EVENT_TICK(rtc) MMIO32((rtc) + 0x100) +#define RTC_EVENT_OVRFLW(rtc) MMIO32((rtc) + 0x104) +#define RTC_EVENT_COMPARE(rtc, i) MMIO32((rtc) + 0x140 + 0x4 * (i)) + +/* Registers */ +#define RTC_INTEN(rtc) _PERIPH_INTEN(rtc) +#define RTC_INTENSET(rtc) _PERIPH_INTENSET(rtc) +#define RTC_INTENCLR(rtc) _PERIPH_INTENCLR(rtc) +#define RTC_EVTEN(rtc) MMIO32((rtc) + 0x340) +#define RTC_EVTENSET(rtc) MMIO32((rtc) + 0x344) +#define RTC_EVTENCLR(rtc) MMIO32((rtc) + 0x348) +#define RTC_COUNTER(rtc) MMIO32((rtc) + 0x504) +#define RTC_PRESCALER(rtc) MMIO32((rtc) + 0x508) +#define RTC_CC(rtc, i) MMIO32((rtc) + 0x540 + 0x4 * (i)) + +/* Register Contents */ +#define RTC_INTEN_TICK (1 << 0) +#define RTC_INTEN_OVRFLW (1 << 1) +#define RTC_INTEN_COMPARE(n) (1 << (16 + (n))) +/**@}*/ + +BEGIN_DECLS + +void rtc_set_prescaler(uint32_t rtc, uint16_t presc); +uint32_t rtc_get_counter(uint32_t rtc); +void rtc_enable_events(uint32_t rtc, uint32_t mask); +void rtc_disable_events(uint32_t rtc, uint32_t mask); +void rtc_start(uint32_t rtc); +void rtc_stop(uint32_t rtc); +void rtc_clear(uint32_t rtc); +void rtc_set_compare(uint32_t rtc, uint8_t cmp, uint32_t value); + +END_DECLS + + diff --git a/include/libopencm3/nrf/common/timer.h b/include/libopencm3/nrf/common/timer.h new file mode 100644 index 00000000..9deb7887 --- /dev/null +++ b/include/libopencm3/nrf/common/timer.h @@ -0,0 +1,120 @@ +/** @addtogroup timer_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/**@{*/ +/* Timer/Counter */ +/** @addtogroup timer_block + * @{ + */ + +#define TIMER0 TIMER0_BASE +#define TIMER1 TIMER1_BASE +#define TIMER2 TIMER2_BASE + +/**@}*/ + +/* Tasks */ + +#define TIMER_TASK_START(T) MMIO32((T) + 0x000) +#define TIMER_TASK_STOP(T) MMIO32((T) + 0x004) +#define TIMER_TASK_COUNT(T) MMIO32((T) + 0x008) +#define TIMER_TASK_CLEAR(T) MMIO32((T) + 0x00C) +#define TIMER_TASK_SHUTDOWN(T) MMIO32((T) + 0x010) +#define TIMER_TASK_CAPTURE(T, C) MMIO32((T) + 0x040 + (uint32_t)(0x4 * (C))) + + + + +/* Events */ + +#define TIMER_EVENT_COMPARE(T, C) MMIO32((T) + 0x140 + (uint32_t)(0x4 * (C))) + +/* Registers */ + +#define TIMER_SHORTS(T) _PERIPH_SHORTS(T) +#define TIMER_INTENSET(T) _PERIPH_INTENSET(T) +#define TIMER_INTENCLR(T) _PERIPH_INTENCLR(T) +#define TIMER_MODE(T) MMIO32((T) + 0x504) +#define TIMER_BITMODE(T) MMIO32((T) + 0x508) +#define TIMER_PRESCALER(T) MMIO32((T) + 0x510) +#define TIMER_PRESCALER_MASK (0xf) + +#define TIMER_CC(T, C) MMIO32((T) + 0x540 + 0x4 * (C)) + + + + +/* Register Contents */ + +/** @addtogroup timer_shorts Timer event -> task shortcuts + * @{ + */ + +#define TIMER_SHORTS_COMPARE_CLEAR(C) (1 << (C)) +#define TIMER_SHORTS_COMPARE_STOP(C) (1 << (8 + (C))) +/**@}*/ + +#define TIMER_INTEN_COMPARE(C) (1 << (16 + (C))) + +#define TIMER_MODE_SELECT (1 << 0) + +enum timer_mode { + TIMER_MODE_TIMER, + TIMER_MODE_COUNTER, +}; + +enum timer_bitmode { + TIMER_BITMODE_16BIT, + TIMER_BITMODE_08BIT, + TIMER_BITMODE_24BIT, + TIMER_BITMODE_32BIT, +}; + +/**@}*/ + +BEGIN_DECLS + +uint32_t timer_get_ticks(uint32_t timer); +void timer_set_mode(uint32_t timer, enum timer_mode mode); +void timer_set_bitmode(uint32_t timer, enum timer_bitmode bitmode); +void timer_start(uint32_t timer); +void timer_stop(uint32_t timer); +void timer_clear(uint32_t timer); +void timer_set_prescaler(uint32_t timer, uint8_t presc); +void timer_set_compare(uint32_t timer, uint8_t compare_num, uint32_t compare_val); +uint32_t timer_get_cc(uint32_t timer, uint8_t compare_num); +uint32_t timer_get_freq(uint32_t timer); + +END_DECLS + + diff --git a/include/libopencm3/nrf/common/uart.h b/include/libopencm3/nrf/common/uart.h new file mode 100644 index 00000000..df8501c4 --- /dev/null +++ b/include/libopencm3/nrf/common/uart.h @@ -0,0 +1,150 @@ +/** @addtogroup uart_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/**@{*/ + +/* Universal Asynchronous Receiver/Transmitter */ + +/** @addtogroup uart_block UART instance + * @{ + */ +#define UART0 UART0_BASE + +/**@}*/ + +/* Tasks */ + +#define UART_TASK_STARTRX(uart) MMIO32((uart) + 0x000) +#define UART_TASK_STOPRX(uart) MMIO32((uart) + 0x004) +#define UART_TASK_STARTTX(uart) MMIO32((uart) + 0x008) +#define UART_TASK_STOPTX(uart) MMIO32((uart) + 0x00C) +#define UART_TASK_SUSPEND(uart) MMIO32((uart) + 0x01C) + +/* Events */ + +#define UART_EVENT_CTS(uart) MMIO32((uart) + 0x100) +#define UART_EVENT_NCTS(uart) MMIO32((uart) + 0x104) +#define UART_EVENT_RXDRDY(uart) MMIO32((uart) + 0x108) +#define UART_EVENT_TXDRDY(uart) MMIO32((uart) + 0x11C) +#define UART_EVENT_ERROR(uart) MMIO32((uart) + 0x124) +#define UART_EVENT_RXTO(uart) MMIO32((uart) + 0x144) + +/* Registers */ + +#define UART_INTEN(uart) _PERIPH_INTEN(uart) +#define UART_INTENSET(uart) _PERIPH_INTENSET(uart) +#define UART_INTENCLR(uart) _PERIPH_INTENCLR(uart) +#define UART_ERRORSRC(uart) MMIO32((uart) + 0x480) +#define UART_ENABLE(uart) MMIO32((uart) + 0x500) +#define UART_PSELRTS(uart) MMIO32((uart) + 0x508) +#define UART_PSELTXD(uart) MMIO32((uart) + 0x50C) +#define UART_PSELCTS(uart) MMIO32((uart) + 0x510) +#define UART_PSELRXD(uart) MMIO32((uart) + 0x514) +#define UART_RXD(uart) MMIO32((uart) + 0x518) +#define UART_TXD(uart) MMIO32((uart) + 0x51C) +#define UART_BAUDRATE(uart) MMIO32((uart) + 0x524) +#define UART_CONFIG(uart) MMIO32((uart) + 0x56C) + +/* Register Contents */ + +/** @addtogroup uart_inten UART interrupt sources + * @{ + */ +#define UART_INTEN_CTS (1 << 0) +#define UART_INTEN_NCTS (1 << 1) +#define UART_INTEN_RXDRDY (1 << 2) +#define UART_INTEN_TXDRDY (1 << 7) +#define UART_INTEN_ERROR (1 << 9) +#define UART_INTEN_RXTO (1 << 17) + +/**@}*/ + +#define UART_ERRORSRC_OVERRUN (1 << 0) +#define UART_ERRORSRC_PARITY (1 << 1) +#define UART_ERRORSRC_FRAMING (1 << 2) +#define UART_ERRORSRC_BREAK (1 << 3) + +#define UART_ENABLE_ENABLED (4) +#define UART_ENABLE_DISABLED (0) +#define UART_CONFIG_HWFC (1) +#define UART_CONFIG_PARITY (7 << 1) + +#define UART_PSEL_OFF (0xff) +#define UART_MAX_PIN (31) +#define UART_PSEL_VAL(p) (p <= UART_MAX_PIN ? (uint32_t) p : 0xffffffff) + + +enum uart_baud { + UART_BAUD_1200 = 0x0004F000, + UART_BAUD_2400 = 0x0009D000, + UART_BAUD_4800 = 0x0013B000, + UART_BAUD_9600 = 0x00275000, + UART_BAUD_14400 = 0x003B0000, + UART_BAUD_19200 = 0x004EA000, + UART_BAUD_28800 = 0x0075F000, + UART_BAUD_38400 = 0x009D5000, + UART_BAUD_57600 = 0x00EBF000, + UART_BAUD_76800 = 0x013A9000, + UART_BAUD_115200 = 0x01D7E000, + UART_BAUD_230400 = 0x03AFB000, + UART_BAUD_250000 = 0x04000000, + UART_BAUD_460800 = 0x075F7000, + UART_BAUD_921600 = 0x0EBEDFA4, + UART_BAUD_1M = 0x10000000, +}; + + +BEGIN_DECLS + +void uart_enable(uint32_t uart); +void uart_disable(uint32_t uart); +void uart_configure(uint32_t uart, +uint32_t txd, uint32_t rxd, uint32_t rts, uint32_t cts, +enum uart_baud br, bool enable_parity); +void uart_set_baudrate(uint32_t uart, enum uart_baud br); +void uart_set_parity(uint32_t uart, int parity); +void uart_set_flow_control(uint32_t uart, int flow); +void uart_send_stop(uint32_t uart); + +void uart_start_tx(uint32_t uart); +void uart_stop_tx(uint32_t uart); +void uart_send(uint32_t uart, uint16_t byte); +void uart_start_rx(uint32_t uart); +void uart_stop_rx(uint32_t uart); +uint16_t uart_recv(uint32_t uart); +void uart_set_pins(uint32_t uart, uint32_t rx, uint32_t tx, uint32_t cts, uint32_t rts); + +END_DECLS + +/**@}*/ + diff --git a/include/libopencm3/nrf/common/uicr.h b/include/libopencm3/nrf/common/uicr.h new file mode 100644 index 00000000..991596a0 --- /dev/null +++ b/include/libopencm3/nrf/common/uicr.h @@ -0,0 +1,53 @@ +/** @addtogroup uicr_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include + +/**@{*/ +/* User Information Configuration Register */ + +#define UICR_CLENR0 MMIO32(UICR_BASE + 0x000) +#define UICR_RBPCONF MMIO32(UICR_BASE + 0x004) +#define UICR_XTALFREQ MMIO32(UICR_BASE + 0x008) +#define UICR_FWID MMIO32(UICR_BASE + 0x010) +#define UICR_BOOTLOADERADDR MMIO32(UICR_BASE + 0x014) + +/* Reserved for Nordic firmware design, n = 1..14 */ +#define UICR_NRFFW(n) MMIO32(UICR_BASE + 0x014 + 0x4 * (n)) + +/* Reserved for Nordic hardware design, n = 0..11 */ +#define UICR_NRFHW(n) MMIO32(UICR_BASE + 0x050 + 0x4 * (n)) + +/* Reserved for customer n = 0..31 */ +#define UICR_CUSTOMER(n) MMIO32(UICR_BASE + 0x080 + 0x4 * (n)) + + +/**@}*/ + diff --git a/include/libopencm3/nrf/ficr.h b/include/libopencm3/nrf/ficr.h new file mode 100644 index 00000000..5040b73d --- /dev/null +++ b/include/libopencm3/nrf/ficr.h @@ -0,0 +1,38 @@ +/** @addtogroup ficr_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/gpio.h b/include/libopencm3/nrf/gpio.h new file mode 100644 index 00000000..eddec01f --- /dev/null +++ b/include/libopencm3/nrf/gpio.h @@ -0,0 +1,40 @@ +/** @addtogroup gpio_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#include +#include + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/i2c.h b/include/libopencm3/nrf/i2c.h new file mode 100644 index 00000000..5a948ace --- /dev/null +++ b/include/libopencm3/nrf/i2c.h @@ -0,0 +1,37 @@ +/** @addtogroup i2c_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/memorymap.h b/include/libopencm3/nrf/memorymap.h new file mode 100644 index 00000000..44c29ef9 --- /dev/null +++ b/include/libopencm3/nrf/memorymap.h @@ -0,0 +1,30 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/periph.h b/include/libopencm3/nrf/periph.h new file mode 100644 index 00000000..b56494c5 --- /dev/null +++ b/include/libopencm3/nrf/periph.h @@ -0,0 +1,30 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/power.h b/include/libopencm3/nrf/power.h new file mode 100644 index 00000000..d653363c --- /dev/null +++ b/include/libopencm3/nrf/power.h @@ -0,0 +1,37 @@ +/** @addtogroup power_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF51) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/ppi.h b/include/libopencm3/nrf/ppi.h new file mode 100644 index 00000000..1d357e19 --- /dev/null +++ b/include/libopencm3/nrf/ppi.h @@ -0,0 +1,37 @@ +/** @addtogroup ppi_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/radio.h b/include/libopencm3/nrf/radio.h new file mode 100644 index 00000000..705f9853 --- /dev/null +++ b/include/libopencm3/nrf/radio.h @@ -0,0 +1,37 @@ +/** @addtogroup radio_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/rtc.h b/include/libopencm3/nrf/rtc.h new file mode 100644 index 00000000..a65c8945 --- /dev/null +++ b/include/libopencm3/nrf/rtc.h @@ -0,0 +1,37 @@ +/** @addtogroup rtc_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/timer.h b/include/libopencm3/nrf/timer.h new file mode 100644 index 00000000..ae592d5f --- /dev/null +++ b/include/libopencm3/nrf/timer.h @@ -0,0 +1,37 @@ +/** @addtogroup timer_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/uart.h b/include/libopencm3/nrf/uart.h new file mode 100644 index 00000000..2f076617 --- /dev/null +++ b/include/libopencm3/nrf/uart.h @@ -0,0 +1,37 @@ +/** @addtogroup uart_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/include/libopencm3/nrf/uicr.h b/include/libopencm3/nrf/uicr.h new file mode 100644 index 00000000..9da10efa --- /dev/null +++ b/include/libopencm3/nrf/uicr.h @@ -0,0 +1,37 @@ +/** @addtogroup uicr_defines + * + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + **/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * 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 . + */ + +#pragma once + +#if defined(NRF51) +# include +#elif defined(NRF52) +# include +#else +# error "Processor family not defined." +#endif + diff --git a/ld/devices.data b/ld/devices.data index e9f04264..035e22b5 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -496,6 +496,20 @@ pac5527 pac55xx ROM=128K RAM=32K pac5532 pac55xx ROM=128K RAM=32K pac5556 pac55xx ROM=128K RAM=32K +################################################################################ +# nRF52xx Cortex-M4 based chips +nrf52805* nrf52sf ROM=192k RAM=24K +nrf52810* nrf52sf ROM=192k RAM=24K +nrf52811* nrf52sf ROM=192k RAM=24K +nrf52820* nrf52sf ROM=256k RAM=32K + +nrf52832qfaa nrf52fp ROM=512K RAM=64K +nrf52832qfab nrf52fp ROM=256K RAM=32K +nrf52832ciaa nrf52fp ROM=512K RAM=64K + +nrf52833* nrf52fp ROM=512K RAM=128K +nrf52840* nrf52fp ROM=1024K RAM=256K + ################################################################################ ################################################################################ ################################################################################ @@ -600,3 +614,13 @@ vf6xx END CPU=cortex-m4 FPU=hard-fpv4-sp-d16 # PAC55xx families pac55xx END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 + +################################################################################ +# nRF52xx families +# +nrf52sf nrf52 FPU=soft +nrf52fp nrf52 FPU=hard-fpv4-sp-d16 + +nrf52 END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m4 + + diff --git a/lib/dispatch/vector_nvic.c b/lib/dispatch/vector_nvic.c index 7cf05d04..9d96970b 100644 --- a/lib/dispatch/vector_nvic.c +++ b/lib/dispatch/vector_nvic.c @@ -50,6 +50,11 @@ #elif defined(LPC43XX_M0) # include "../lpc43xx/m0/vector_nvic.c" +#elif defined(NRF51) +# include "../nrf/51/vector_nvic.c" +#elif defined(NRF52) +# include "../nrf/52/vector_nvic.c" + #elif defined(SAM3A) # include "../sam/3a/vector_nvic.c" #elif defined(SAM3N) diff --git a/lib/nrf/51/Makefile b/lib/nrf/51/Makefile new file mode 100644 index 00000000..9e1688f2 --- /dev/null +++ b/lib/nrf/51/Makefile @@ -0,0 +1,50 @@ +## +## This file is part of the libopencm3 project. +## Copyright (C) 2017-2018 Unicore MX project +## Copyright (C) 2021 Eduard Drusa +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_nrf51 +SRCLIBDIR ?= ../.. + +CC = $(PREFIX)gcc +AR = $(PREFIX)ar + +FP_FLAGS ?= -msoft-float + +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m0 -mthumb $(FP_FLAGS) \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DNRF51 + +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs + +OBJS += clock_common.o clock.o +OBJS += gpio.o +OBJS += i2c.o +OBJS += ppi.o +OBJS += rtc.o +OBJS += radio_common.o ./radio.o +OBJS += timer.o +OBJS += uart.o + +VPATH += ../../cm3:../common + +include ../../Makefile.include + diff --git a/lib/nrf/51/clock.c b/lib/nrf/51/clock.c new file mode 100644 index 00000000..61930cff --- /dev/null +++ b/lib/nrf/51/clock.c @@ -0,0 +1,45 @@ +/** @addtogroup clock_file CLOCK peripheral API + * + * @brief Access functions for the NRF51 Clock Controller + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Roel Postelmans + * + */ + +/* + * This file is part of the unicore-mx project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +/**@{*/ + +/** @brief Select nominal frequency of external crystal for HFCLK. + * + * @details This register has to match the actual crystal used in design to + * enable correct behaviour. + * + * @param[in] freq enum clock_xtal_freq + * */ +void clock_set_xtal_freq(enum clock_xtal_freq freq) +{ + CLOCK_XTALFREQ = freq; +} +/**@}*/ + diff --git a/lib/nrf/51/radio.c b/lib/nrf/51/radio.c new file mode 100644 index 00000000..e81c35a0 --- /dev/null +++ b/lib/nrf/51/radio.c @@ -0,0 +1,66 @@ +/** @addtogroup radio_file RADIO peripheral API + * + * @brief Access functions for the NRF51 2.4 GHz Radio + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Maxim Sloyko + * + */ + +/* + * This file is part of the unicore-mx project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/**@{*/ + +/** @brief Set radio mode. + * + * @details The function also performs all required overrides for BLE and NRF mode. + * + * @param[in] mode the new mode. + * */ +void radio_set_mode(enum radio_mode mode) +{ + /* This is alias to memory register, thus volatile */ + volatile uint32_t *override_pos = 0; + if ((RADIO_MODE_BLE_1MBIT == mode) + && (FICR_OVERRIDEEN & ~FICR_OVERRIDEEN_BLE_1MBIT)) { + /* Need to use Override */ + override_pos = &FICR_BLE_1MBIT0; + } else if ((RADIO_MODE_NRF_1MBIT == mode) + && (FICR_OVERRIDEEN & ~FICR_OVERRIDEEN_NRF_1MBIT)) { + override_pos = &FICR_NRF_1MBIT0; + } + + if (override_pos) { + uint8_t i; + for (i = 0; i <= 4; ++i, ++override_pos) { + RADIO_OVERRIDE(i) = *override_pos; + } + + RADIO_OVERRIDE(4) |= RADIO_OVERRIDE4_ENABLE; + } else { + RADIO_OVERRIDE(4) &= ~RADIO_OVERRIDE4_ENABLE; + } + + RADIO_MODE = mode; +} +/**@}*/ + diff --git a/lib/nrf/52/Makefile b/lib/nrf/52/Makefile new file mode 100644 index 00000000..a0e4884c --- /dev/null +++ b/lib/nrf/52/Makefile @@ -0,0 +1,50 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2017-2018 Unicore MX project +## Copyright (C) 2021 Eduard Drusa +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_nrf52 +SRCLIBDIR ?= ../.. + +CC = $(PREFIX)gcc +AR = $(PREFIX)ar + +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m4 -mthumb $(FP_FLAGS) \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DNRF52 +TGT_CFLAGS += $(DEBUG_FLAGS) +TGT_CFLAGS += $(STANDARD_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs + +OBJS += clock_common.o +OBJS += gpio.o +OBJS += i2c.o +OBJS += ppi.o +OBJS += radio_common.o +OBJS += rtc.o +OBJS += timer.o +OBJS += uart.o + +VPATH += ../../cm3:../common + +include ../../Makefile.include + diff --git a/lib/nrf/common/clock_common.c b/lib/nrf/common/clock_common.c new file mode 100644 index 00000000..9397c040 --- /dev/null +++ b/lib/nrf/common/clock_common.c @@ -0,0 +1,83 @@ +/** @addtogroup clock_file CLOCK peripheral API + * + * @brief Access functions for the Clock Controller + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 Eduard Drusa + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +/**@{*/ + +/** @brief Start Low Frequency Clock + * + * @param[in] wait bool: If true, will busy wait for the clock to start. + */ +void clock_start_lfclk(bool wait) +{ + PERIPH_TRIGGER_TASK(CLOCK_TASK_LFCLKSTART); + if (wait) { + while (!(CLOCK_LFCLKSTAT & CLOCK_LFCLKSTAT_STATE)); + } +} + +/** @brief Stop Low Frequency Clock */ +void clock_stop_lfclk() +{ + PERIPH_TRIGGER_TASK(CLOCK_TASK_LFCLKSTOP); +} + +/** @brief Start High Frequency Crystal Oscillator. + * + * @details Oscillator needs to be running for the radio to work. + * + * @param[in] wait bool If true, will busy wait for the clock to start. + */ +void clock_start_hfclk(bool wait) +{ + PERIPH_TRIGGER_TASK(CLOCK_TASK_HFCLKSTART); + if (wait) { + while (!(CLOCK_HFCLKSTAT & CLOCK_HFCLKSTAT_STATE)); + } +} + +/** @brief Stop High Frequency Crystal Oscillator */ +void clock_stop_hfclk() +{ + PERIPH_TRIGGER_TASK(CLOCK_TASK_HFCLKSTOP); +} + +/** @brief Low Frequency Clock Source. + * + * @param[in] lfclk_src enum clock_lfclk_src + */ +void clock_set_lfclk_src(enum clock_lfclk_src lfclk_src) +{ + CLOCK_LFCLKSRC = lfclk_src; +} +/**@}*/ + diff --git a/lib/nrf/common/gpio.c b/lib/nrf/common/gpio.c new file mode 100644 index 00000000..afafa46d --- /dev/null +++ b/lib/nrf/common/gpio.c @@ -0,0 +1,208 @@ +/** @addtogroup gpio_file GPIO peripheral API + * + * @brief Access functions for the I/O Controller + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Maxim Sloyko + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/** @{ */ + +#include + +/** @brief Atomic set output + * + * @param[in] gpioport Port identifier @ref gpio_port_id + * @param[in] gpios Pin identifiers @ref gpio_pin_id + */ +void gpio_set(uint32_t gpioport, uint32_t gpios) +{ + (void) gpioport; + GPIO_OUTSET = gpios; +} + +/** @brief Atomic clear output + * + * @param[in] gpioport Port identifier @ref gpio_port_id + * @param[in] gpios Pin identifiers @ref gpio_pin_id + */ +void gpio_clear(uint32_t gpioport, uint32_t gpios) +{ + (void) gpioport; + GPIO_OUTCLR = gpios; +} + +/** @brief Toggle output + * + * @param[in] gpioport Port identifier @ref gpio_port_id + * @param[in] gpios Pin identifiers @ref gpio_pin_id + */ +void gpio_toggle(uint32_t gpioport, uint32_t gpios) +{ + (void) gpioport; + uint32_t reg_val = GPIO_OUT; + GPIO_OUTCLR = reg_val & gpios; + GPIO_OUTSET = (~reg_val) & gpios; +} + +/** @brief Read GPIO values + * + * @param[in] gpioport Port identifier @ref gpio_port_id + * @param[in] gpios Pin identifiers @ref gpio_pin_id + */ +uint32_t gpio_get(uint32_t gpioport, uint32_t gpios) +{ + (void) gpioport; + return GPIO_IN & gpios; +} + +/** @brief Set GPIO Pin Mode + * + * Sets the mode (input/output) and configuration (analog/digitial and + * open drain/push pull), for a set of GPIO pins on a given GPIO port. + * + * @param[in] gpioport Port identifier @ref gpio_port_id + * @param[in] mode Pin mode @ref gpio_mode + * @param[in] pull_up_down Pull up / pull down configuration @ref gpio_pupd + * @param[in] gpios Pin identifiers @ref gpio_pin_id + * If multiple pins are to be set, use bitwise OR '|' to separate + * them. + */ +void gpio_mode_setup(uint32_t gpioport, uint32_t mode, uint32_t pull_up_down, + uint32_t gpios) +{ + (void) gpioport; + + uint8_t i = 0; + while (gpios) { + if (gpios & 1) { + GPIO_PIN_CNF(i) = ( + GPIO_PIN_CNF(i) & + ~((GPIO_CNF_MODE_MASK << GPIO_CNF_MODE_SHIFT) + | (GPIO_CNF_PUPD_MASK << GPIO_CNF_PUPD_SHIFT) + ) + ) | (mode << GPIO_CNF_MODE_SHIFT) + | (pull_up_down << GPIO_CNF_PUPD_SHIFT); + } + ++i; + gpios >>= 1; + } +} + +/** Configure GPIO pin input and output specifics. + * + * Configure drive strength and input sensing for given GPIO port. + * @param [in] gpioport GPIO port identifier, see @ref gpio_port_id + * @param [in] drive Drive schema used to drive pin, see @ref gpio_drive + * @param [in] sense Pin sensing mechanism, see @ref gpio_sense + * @param[in] gpios Pin identifiers @ref gpio_pin_id + * If multiple pins are to be set, use bitwise OR '|' to separate + * them. + */ +void gpio_set_options(uint32_t gpioport, uint32_t drive, uint32_t sense, + uint32_t gpios) +{ + (void) gpioport; + + uint8_t i = 0; + while (gpios) { + if (gpios & 1) { + GPIO_PIN_CNF(i) = (GPIO_PIN_CNF(i) & + ~((GPIO_CNF_DRIVE_MASK << GPIO_CNF_DRIVE_SHIFT) + | (GPIO_CNF_SENSE_MASK << GPIO_CNF_SENSE_SHIFT) + ) + ) | (drive << GPIO_CNF_DRIVE_SHIFT) + | (sense << GPIO_CNF_SENSE_SHIFT); + } + ++i; + gpios >>= 1; + } + +} + + +/** @brief Configure Task in GPIO TE Module + * + * @param[in] task_num uint8_t Task number (0-3) + * @param[in] pin_num uint8_t GPIO Pin number (0-31) + * @param[in] polarity uint8_t polarity Operation to perform when task is triggered. + * @param[in] init uint8_t Initial state of the pin, non-zero means initially active, + * zero means initially inactive + */ +void gpio_configure_task(uint8_t task_num, + uint8_t pin_num, uint8_t polarity, uint32_t init) +{ + /* any non-zero value means, that pin is active */ + if (init) { + init = GPIO_TE_CONFIG_OUTINIT; + } + + GPIO_TE_CONFIG(task_num) = (GPIO_TE_MODE_TASK << GPIO_TE_CONFIG_MODE_SHIFT) + | (pin_num << GPIO_TE_CONFIG_PSEL_SHIFT) + | (polarity << GPIO_TE_CONFIG_POLARITY_SHIFT) + | init; +} + +/** @brief Configure Event in GPIO TE Module + * + * @param[in] event_num Event number (0-3) + * @param[in] pin_num GPIO Pin number (0-31) + * @param[in] polarity Operation to perform when task is triggered. + */ +void gpio_configure_event(uint8_t event_num, uint8_t pin_num, uint8_t polarity) +{ + GPIO_TE_CONFIG(event_num) = (GPIO_TE_MODE_EVENT << GPIO_TE_CONFIG_MODE_SHIFT) + | (pin_num << GPIO_TE_CONFIG_PSEL_SHIFT) + | (polarity << GPIO_TE_CONFIG_POLARITY_SHIFT); +} + +/** @brief Enable GPIO interrupts + * + * @param[in] mask interrupts to enable. + */ +void gpio_enable_interrupts(uint32_t mask) +{ + GPIO_INTENSET = mask; +} + +/** @brief Disable GPIO interrupts + * + * @param[in] mask interrupts to disable. + */ +void gpio_disable_interrupts(uint32_t mask) +{ + GPIO_INTENCLR = mask; +} + +/** @brief Disable all GPIO interrupts + * + */ +void gpio_clear_interrupts(void) +{ + GPIO_INTENCLR = 0xffffffff; +} + +/** @} */ diff --git a/lib/nrf/common/i2c.c b/lib/nrf/common/i2c.c new file mode 100644 index 00000000..5086bb23 --- /dev/null +++ b/lib/nrf/common/i2c.c @@ -0,0 +1,184 @@ +/** @addtogroup i2c_file I2C peripheral API + * + * @brief Access functions for the I2C Controller + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Maxim Sloyko + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/** @brief Enable I2C peripheral + * + * @param[in] i2c uint32_t i2c peripheral base + */ +void i2c_enable(uint32_t i2c) +{ + I2C_ENABLE(i2c) = I2C_ENABLE_VALUE; +} + +/** @brief Disable I2C peripheral + * + * @param[in] i2c uint32_t i2c peripheral base + */ +void i2c_disable(uint32_t i2c) +{ + I2C_ENABLE(i2c) = 0; +} + +/** @brief Start I2C transmission. + * + * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] data uint8_t the first byte to send. + */ +void i2c_start_tx(uint32_t i2c, uint8_t data) +{ + PERIPH_TRIGGER_TASK(I2C_TASK_STARTTX(i2c)); + I2C_TXD(i2c) = data; +} + +/** @brief Start I2C reception. + * + * @param[in] i2c uint32_t i2c peripheral base. + */ +void i2c_start_rx(uint32_t i2c) +{ + PERIPH_TRIGGER_TASK(I2C_TASK_STARTRX(i2c)); +} + +/** @brief Signal stop on I2C line. + * + * @param[in] i2c uint32_t i2c peripheral base. + */ +void i2c_send_stop(uint32_t i2c) +{ + PERIPH_TRIGGER_TASK(I2C_TASK_STOP(i2c)); +} + +/** @brief Select Fast (400kHz) mode. + * + * @param[in] i2c uint32_t i2c peripheral base. + */ +void i2c_set_fast_mode(uint32_t i2c) +{ + I2C_FREQUENCY(i2c) = I2C_FREQUENCY_400K; +} + +/** @brief Select Standard (100kHz) mode. + * + * @param[in] i2c uint32_t i2c peripheral base. + */ +void i2c_set_standard_mode(uint32_t i2c) +{ + I2C_FREQUENCY(i2c) = I2C_FREQUENCY_100K; +} + +/** @brief Set I2C frequency. + * + * In addition to Standard (100kHz) and Fast (400kHz) modes + * this peripheral also supports 250kHz mode. + * + * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] freq uint32_t frequency constant. See defines for details + * and note that this is not actually a frequency in Hz or kHz. + */ +void i2c_set_frequency(uint32_t i2c, uint32_t freq) +{ + I2C_FREQUENCY(i2c) = freq; +} + +/** @brief Write Data to TXD register to be sent. + * + * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] data uint8_t byte to send next. + */ +void i2c_send_data(uint32_t i2c, uint8_t data) +{ + I2C_TXD(i2c) = data; +} + +/** @brief Read Data from RXD register. + * + * @param[in] i2c uint32_t i2c peripheral base. + * @returns uint8_t data from RXD register. + */ +uint8_t i2c_get_data(uint32_t i2c) +{ + return (uint8_t)I2C_RXD(i2c); +} + +/** @brief Select GPIO pins to be used by this peripheral. + * + * This needs to be configured when no transaction is in progress. + * + * @param[in] i2c i2c peripheral base. + * @param[in] scl_pin SCL pin. Use GPIO defines in @ref gpio_pin_id or GPIO_UNCONNECTED + * if signal shall not be connected to any pin. + * @param[in] sda_pin SDA pin. Use GPIO defines in @ref gpio_pin_id or GPIO_UNCONNECTED + * if signal shall not be connected to any pin. + + */ +void i2c_select_pins(uint32_t i2c, uint32_t scl_pin, uint32_t sda_pin) +{ + if (scl_pin != GPIO_UNCONNECTED) { + I2C_PSELSCL(i2c) = __GPIO2PIN(scl_pin); + } else { + I2C_PSELSCL(i2c) = scl_pin; + } + + if (sda_pin != GPIO_UNCONNECTED) { + I2C_PSELSDA(i2c) = __GPIO2PIN(sda_pin); + } else { + I2C_PSELSDA(i2c) = sda_pin; + } +} + +/** @brief Set 7bit I2C address of the device you wish to communicate with. + * + * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] addr uint8_t device address (7bit). + */ +void i2c_set_address(uint32_t i2c, uint8_t addr) +{ + I2C_ADDRESS(i2c) = addr; +} + +/** @brief Resume I2C transaction. + * + * This function is unusual, but required to implement + * i2c exchange with this peripheral. + * + * @param[in] i2c uint32_t i2c peripheral base. + */ +void i2c_resume(uint32_t i2c) +{ + PERIPH_TRIGGER_TASK(I2C_TASK_RESUME(i2c)); +} + + +/**@}*/ diff --git a/lib/nrf/common/ppi.c b/lib/nrf/common/ppi.c new file mode 100644 index 00000000..1c90efb3 --- /dev/null +++ b/lib/nrf/common/ppi.c @@ -0,0 +1,145 @@ +/** @addtogroup ppi_file PPI peripheral API + * + * @brief Access functions for the Programmable Peripheral Interconnect + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Maxim Sloyko + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#include +/**@{*/ + +/** @brief Configure PPI Channel. + * + * @param[in] chan_num uint8_t Channel number (0-15). + * @param[in] eep uint32_t Event endpoint. Memory address of the event endpoint. + * @param[in] tep uint32_t Task endpoint. Memory address of the task endpoint. + */ +void ppi_configure_channel(uint8_t chan_num, uint32_t eep, uint32_t tep) +{ + PPI_CH_EEP(chan_num) = eep; + PPI_CH_TEP(chan_num) = tep; +} + +/** @brief Enable PPI channels, given the channels mask. + * + * @param[in] channels uint32_t mask of the channels to enable. + */ +void ppi_enable_channels(uint32_t channels) +{ + PPI_CHENSET = channels; +} + +/** @brief Disable PPI channels, given the channels mask. + * + * @param[in] channels uint32_t mask of the channels to disable. + */ +void ppi_disable_channels(uint32_t channels) +{ + PPI_CHENCLR = channels; +} + +/** @brief Set channels group, given channels mask. + * + * @param[in] group uint8_t group number (0-3) + * @param[in] channels uint32_t mask of the channels to group together. + */ +void ppi_set_group(uint8_t group, uint32_t channels) +{ + PPI_CHG(group) = channels; +} + +/** @brief Enable previously configured group of channels. + * + * @param[in] group uint8_t group number (0-3) + */ +void ppi_enable_group(uint8_t group) +{ + PPI_TASK_CHG_EN(group) = 1; +} + +/** @brief Disable previously configured group of channels. + * + * @param[in] group uint8_t group number (0-3) + */ +void ppi_disable_group(uint8_t group) +{ + PPI_TASK_CHG_DIS(group) = 1; +} + +/** @brief Configure new channel. + * + * This is the alternative API, which requires the caller to store the mask of used channels. + * + * @param chan_map uint32_t* The mask of channels that are already in use. + * For the first call initialize with zero and pass in. + * @param[in] eep uint32_t Event endpoint. + * @param[in] tep uint32_t Task endpoint. + * @param enable bool If true, enable the channel immediately. + * @return The number of the new channel. If there are no channels available, returns 0xff. + */ +uint8_t ppi_add_channel(uint32_t *chan_map, uint32_t eep, uint32_t tep, bool enable) +{ + /* Find a free channel */ + uint8_t i; + uint32_t chan_bit; + for (i = 0, chan_bit = 1; i <= PPI_MAX_PROG_CHANNEL; ++i, chan_bit <<= 1) { + if (!(chan_bit & *chan_map)) { + *chan_map |= chan_bit; + break; + } + } + + /* If all channels are taken, return error. */ + if (i > PPI_MAX_PROG_CHANNEL) { + return 0xff; + } + + ppi_configure_channel(i, eep, tep); + if (enable) { + ppi_enable_channels(chan_bit); + } + + return i; +} + +/** @brief Disable channel and remove it from the map of used channels. + * + * This is the alternative API, which requires the caller to store the mask of used channels. + * + * @param chan_map uint32_t* The mask of channels that are already in use. + * For the first call initialize with zero and pass in. + * @param[in] chan_num uint8_t the number of the channel to remove from the map. + */ +void ppi_remove_channel(uint32_t *chan_map, uint8_t chan_num) +{ + ppi_disable_channels(PPI_CH(chan_num)); + *chan_map &= ~(PPI_CH(chan_num)); +} +/**@}*/ + diff --git a/lib/nrf/common/radio_common.c b/lib/nrf/common/radio_common.c new file mode 100644 index 00000000..091e0dbc --- /dev/null +++ b/lib/nrf/common/radio_common.c @@ -0,0 +1,250 @@ +/** @addtogroup radio_file RADIO peripheral API + * + * @brief Access functions for the 2.4 GHz Radio + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Maxim Sloyko + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/**@{*/ + +/** @brief Set radio transmission power. + * + * @details Note, not all supported power levels are BLE compliant. + * + * @param[in] txpower enum radio_txpower + * */ +void radio_set_txpower(enum radio_txpower txpower) +{ + RADIO_TXPOWER = txpower; +} + +/** @brief Set bit transmission order to LSB first. */ +void radio_set_lsbfirst(void) +{ + RADIO_PCNF1 &= ~RADIO_PCNF1_ENDIAN_BIG; +} + +/** @brief Set bit transmission order to MSB first. */ +void radio_set_msbfirst(void) +{ + RADIO_PCNF1 |= RADIO_PCNF1_ENDIAN_BIG; +} + +/** @brief Enable on the air data whitening + * + * @details the in-memory data will remain unwhitened. + * */ +void radio_enable_whitening(void) +{ + RADIO_PCNF1 |= RADIO_PCNF1_WHITEEN; +} + +/** @brief Disable on the air data whitening. */ +void radio_disable_whitening(void) +{ + RADIO_PCNF1 &= ~RADIO_PCNF1_WHITEEN; +} + +/** @brief Set CRC length in number of bytes. + * + * @param[in] crc_len uint8_t CRC length in number of bytes (1-3), 0 = CRC disabled. + */ +void radio_set_crclen(uint8_t crc_len) +{ + uint32_t reg_crc = RADIO_CRCCNF; + reg_crc &= ~RADIO_CRCCNF_LEN_MASK; + RADIO_CRCCNF = reg_crc | RADIO_CRCCNF_LEN_MASKED(crc_len); +} + +/** @brief Disable CRC calculation. */ +void radio_disable_crc(void) +{ + RADIO_CRCCNF &= ~RADIO_CRCCNF_LEN_MASK; +} + +/** @brief Enable the peripheral. */ +void radio_enable(void) +{ + RADIO_POWER = RADIO_POWER_ENABLED; +} + +/** @brief Disable the peripheral. */ +void radio_disable(void) +{ + RADIO_POWER = RADIO_POWER_DISABLED; +} + + +/** @brief Set Base Address length. + * + * @param[in] ba_len uint8_t Base Address length in number of bytes (2-4). + */ +void radio_set_balen(uint8_t ba_len) +{ + uint32_t reg_pcnf1 = RADIO_PCNF1; + reg_pcnf1 &= ~RADIO_PCNF1_BALEN_MASK; + RADIO_PCNF1 = reg_pcnf1 | RADIO_PCNF1_BALEN_MASKED(ba_len); +} + +/** @brief Set maximum transmission length in number of bytes. + * + * @param[in] maxlen uint8_t maximum transmission length. + */ +void radio_set_maxlen(uint8_t maxlen) +{ + uint32_t reg_pcnf1 = RADIO_PCNF1; + reg_pcnf1 &= ~RADIO_PCNF1_MAXLEN_MASK; + RADIO_PCNF1 = reg_pcnf1 | RADIO_PCNF1_MAXLEN_MASKED(maxlen); +} + +/** @brief Exclude access address from CRC calculation. + * + * @param[in] is_skip_addr bool If true, CRC will be calculated over PDU only, + * if false, it will also include the Access Address. + */ +void radio_set_crc_skipaddr(bool is_skip_addr) +{ + if (is_skip_addr) { + RADIO_CRCCNF |= RADIO_CRCCNF_SKIPADDR; + } else { + RADIO_CRCCNF &= ~RADIO_CRCCNF_SKIPADDR; + } +} + +/** @brief Configure the radio to be used in BLE mode. + * + * @details This needs to be called before the radio can be used in BLE mode. + * It will set som BLE standard parameters, like Inter-Frame Spacing time, + * LSB first, enable whitening, properly configure CRC (for advertising) and address length. + */ +void radio_configure_ble(void) +{ +#ifdef NRF51 + radio_set_mode(RADIO_MODE_BLE_1MBIT); +#endif + RADIO_TIFS = RADIO_BLE_TIFS; + radio_set_lsbfirst(); + radio_enable_whitening(); + + radio_set_crclen(RADIO_BLE_CRCLEN); + RADIO_CRCPOLY = RADIO_BLE_CRCPOLY; + RADIO_CRCINIT = RADIO_BLE_CRCINIT; + radio_set_crc_skipaddr(true); + radio_set_balen(3); +} + +/** @brief Configure the packet. + * + * @details See the data sheet for details. + */ +void radio_configure_packet(uint8_t lf_len_bits, uint8_t s0_len_bytes, uint8_t s1_len_bits) +{ + RADIO_PCNF0 = RADIO_PCNF0_LFLEN_MASKED(lf_len_bits) + | RADIO_PCNF0_S0LEN_MASKED(s0_len_bytes) + | RADIO_PCNF0_S1LEN_MASKED(s1_len_bits); +} + +/** @brief Set radio frequency. + * + * @param[in] freq uint8_t Frequency offset from 2.4GHz in MHz, for example "29" will + * tune the radio to 2429MHz + */ +void radio_set_frequency(uint8_t freq) +{ + RADIO_FREQUENCY = freq; +} + +/** @brief Set Data Whitening Initialization Vector. + * + * @param[in] iv uint8_t Initialization Vector. For BLE, this is channel index. + */ +void radio_set_datawhiteiv(uint8_t iv) +{ + RADIO_DATAWHITEIV = iv; +} + +/* @brief Set Address (base and prefix) + * + * @details Note that bases are shared between addresses 1-7, + * so changing one of them will change others too. + * + * @param[in] addr_index uint8_t address index (0-7) + * @param[in] base uint32_t base part of the address. If balen < 4, appropriate number + * of LSBs will be thrown away. + * @param[in] prefix uint8_t Address prefix. + */ +void radio_set_addr(uint8_t addr_index, uint32_t base, uint8_t prefix) +{ + if (addr_index == 0) { + RADIO_BASE0 = base; + } else { + RADIO_BASE1 = base; + } + + uint32_t reg_prefix = RADIO_PREFIX_AP(addr_index); + reg_prefix &= ~RADIO_PREFIX_AP_MASK(addr_index); + RADIO_PREFIX_AP_SET(addr_index, reg_prefix | RADIO_PREFIX_AP_MASKED(addr_index, prefix)); +} + +/* @brief Set TX address index + * + * @details The address needs to be previously configured with radio_set_addr() + * + * @param[in] address_index uint8_t address index (0-7) + */ +void radio_set_tx_address(uint8_t addr_index) +{ + RADIO_TXADDRESS = addr_index; +} + +/* @brief Set pointer for RX/TX data + * + * @param[in] packet_ptr uint8_t* packet buffer address. + */ +void radio_set_packet_ptr(uint8_t *packet_ptr) +{ + RADIO_PACKETPTR = (uint32_t)packet_ptr; +} + +/* @brief Enable radio Transmitter */ +void radio_enable_tx(void) +{ + PERIPH_TRIGGER_TASK(RADIO_TASK_TXEN); +} + +/* @brief Enable radio Receiver */ +void radio_enable_rx(void) +{ + PERIPH_TRIGGER_TASK(RADIO_TASK_RXEN); +} + + +/**@}*/ + diff --git a/lib/nrf/common/rtc.c b/lib/nrf/common/rtc.c new file mode 100644 index 00000000..6dc39eea --- /dev/null +++ b/lib/nrf/common/rtc.c @@ -0,0 +1,116 @@ +/** @addtogroup rtc_file RTC peripheral API + * + * @brief Access functions for the Real Time Counter Controller + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Maxim Sloyko + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +/**@{*/ + +/** @brief RTC set Prescaler value. + * + * @details The clock needs to be stopped for this to have any effect. + * + * @param[in] rtc uint32_t RTC base + * @param[in] presc uint16_t 12 bit prescaler value. + */ +void rtc_set_prescaler(uint32_t rtc, uint16_t presc) +{ + RTC_PRESCALER(rtc) = presc & 0xfff; +} + +/** @brief RTC get Counter value. + * + * @param[in] rtc uint32_t RTC base + */ +uint32_t rtc_get_counter(uint32_t rtc) +{ + return RTC_COUNTER(rtc); +} + +/** @brief Enable events + * + * @param[in] rtc uint32_t RTC base + * @param[in] mask uint32_t which events to enable + */ +void rtc_enable_events(uint32_t rtc, uint32_t mask) +{ + RTC_EVTENSET(rtc) = mask; +} + +/** @brief Disable events + * + * @param[in] rtc uint32_t RTC base + * @param[in] mask uint32_t which events to disable + */ +void rtc_disable_events(uint32_t rtc, uint32_t mask) +{ + RTC_EVTENCLR(rtc) = mask; +} + +/** @brief Start the RTC + * + * @param[in] rtc uint32_t RTC base + */ +void rtc_start(uint32_t rtc) +{ + PERIPH_TRIGGER_TASK(RTC_TASK_START(rtc)); +} + +/** @brief Stop the RTC + * + * @param[in] rtc uint32_t RTC base + */ +void rtc_stop(uint32_t rtc) +{ + PERIPH_TRIGGER_TASK(RTC_TASK_STOP(rtc)); +} + +/** @brief Clear the RTC + * + * @param[in] rtc uint32_t RTC base + */ +void rtc_clear(uint32_t rtc) +{ + PERIPH_TRIGGER_TASK(RTC_TASK_CLEAR(rtc)); +} + +/** @brief Set compare register + * + * @param[in] rtc uint32_t RTC base + * @param[in] cmp uint8_t compare number (0-3) + * @param[in] value uint32_t compare value + */ +void rtc_set_compare(uint32_t rtc, uint8_t cmp, uint32_t value) +{ + if (cmp < 4) { + RTC_CC(rtc, cmp) = value; + } +} +/**@}*/ + diff --git a/lib/nrf/common/timer.c b/lib/nrf/common/timer.c new file mode 100644 index 00000000..fcae0d81 --- /dev/null +++ b/lib/nrf/common/timer.c @@ -0,0 +1,147 @@ +/** @addtogroup timer_file TIMER peripheral API + * + * @brief Access functions for the Timer/Counter + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Maxim Sloyko + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +/**@{*/ + +/** @brief Get timer ticks + * + * @param[in] timer uint32_t timer base + * @returns current ticks value + */ +uint32_t timer_get_ticks(uint32_t timer) +{ + uint32_t ticks; + uint32_t cc; + + /* TODO: Check WTF is this doing? */ + cc = TIMER_CC(0, 0); + TIMER_TASK_CAPTURE(timer, 0) = 1; + ticks = TIMER_CC(timer, 0); + TIMER_CC(timer, 0) = cc; + return ticks; +} + +/** @brief Set timer mode (counter/timer) + * + * @param[in] timer uint32_t timer base + * @param[in] mode enum timer_mode + */ +void timer_set_mode(uint32_t timer, enum timer_mode mode) +{ + TIMER_MODE(timer) = mode; +} + +/** @brief Set timer bit mode (width) + * + * @param[in] timer uint32_t timer base + * @param[in] bitmode enum timer_bitmode + */ +void timer_set_bitmode(uint32_t timer, enum timer_bitmode bitmode) +{ + TIMER_BITMODE(timer) = bitmode; +} + +/** @brief Start the timer + * + * @param[in] timer uint32_t timer base + */ +void timer_start(uint32_t timer) +{ + PERIPH_TRIGGER_TASK(TIMER_TASK_START(timer)); +} + +/** @brief Stop the timer + * + * @param[in] timer uint32_t timer base + */ +void timer_stop(uint32_t timer) +{ + PERIPH_TRIGGER_TASK(TIMER_TASK_STOP(timer)); +} + +/** @brief Clear the timer + * + * @param[in] timer uint32_t timer base + */ +void timer_clear(uint32_t timer) +{ + PERIPH_TRIGGER_TASK(TIMER_TASK_CLEAR(timer)); +} + +/** @brief Set prescaler value + * + * @param[in] timer uint32_t timer base + * @param[in] presc uint8_t prescaler value + */ +void timer_set_prescaler(uint32_t timer, uint8_t presc) +{ + TIMER_PRESCALER(timer) = presc & TIMER_PRESCALER_MASK; +} + +/** @brief Set compare register + * + * @param[in] timer uint32_t timer base + * @param[in] compare_num uint8_t compare number (0-3) + * @param[in] compare_val uint32_t compare value + */ +void timer_set_compare(uint32_t timer, uint8_t compare_num, uint32_t compare_val) +{ + if (compare_num > 3) { + return; + } + + TIMER_CC(timer, compare_num) = compare_val; +} + +/** @brief Get the timer tick frequency + * + * @param[in] timer uint32_t timer base + * @returns frequency of ticking + */ +uint32_t timer_get_freq(uint32_t timer) +{ + return CLOCK_PCLK/(1<Access functions for the UART controller + * + * @ingroup peripheral_apis + * LGPL License Terms @ref lgpl_license + * @author @htmlonly © @endhtmlonly 2016 + * Maxim Sloyko + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2017-2018 Unicore MX project + * Copyright (C) 2021 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +/**@{*/ + +/** @brief Enable the peripheral + * + * @param[in] uart uint32_t uart base + */ +void uart_enable(uint32_t uart) +{ + UART_ENABLE(uart) = UART_ENABLE_ENABLED; +} + +/** @brief Disable the peripheral + * + * @param[in] uart uint32_t uart base + */ +void uart_disable(uint32_t uart) +{ + UART_ENABLE(uart) = UART_ENABLE_DISABLED; +} + +/** @brief Configure UART parameters in single call + * + * @details Any pin number can be set to 0xff (or any number larger than UART_MAX_PIN) + * to disconnect that pin. + * + * @param[in] uart uint32_t uart base + * @param[in] tx_pin uint8_t TX pin number + * @param[in] rx_pin uint8_t RX pin number + * @param[in] rts_pin uint8_t RTS pin number + * @param[in] cts_pin uint8_t CTS pin number + * @param[in] br enum uart_baud baud rate + * @param[in] enable_parity bool If true, enable parity bit + */ +void uart_configure(uint32_t uart, + uint32_t tx_pin, uint32_t rx_pin, uint32_t rts_pin, uint32_t cts_pin, + enum uart_baud br, bool enable_parity) +{ + uart_set_pins(uart, rx_pin, tx_pin, cts_pin, rts_pin); + + uint32_t reg_config = enable_parity ? UART_CONFIG_PARITY : 0; + if (rts_pin <= UART_MAX_PIN || cts_pin <= UART_MAX_PIN) { + reg_config |= UART_CONFIG_HWFC; + } + + UART_CONFIG(uart) = reg_config; + uart_set_baudrate(uart, br); +} + +/** @brief Select GPIO pins to be used by this peripheral. + * + * This needs to be configured while UART peripheral is disabled. + * + * @param[in] uart uart peripheral base. + * @param[in] rx RX pin. Use GPIO defines in @ref gpio_pin_id or GPIO_UNCONNECTED + * if signal shall not be connected to any pin. + * @param[in] tx TX pin. Use GPIO defines in @ref gpio_pin_id or GPIO_UNCONNECTED + * if signal shall not be connected to any pin. + * @param[in] cts CTS pin. Use GPIO defines in @ref gpio_pin_id or GPIO_UNCONNECTED + * if signal shall not be connected to any pin. + * @param[in] rts RTS pin. Use GPIO defines in @ref gpio_pin_id or GPIO_UNCONNECTED + * if signal shall not be connected to any pin. + + */ +void uart_set_pins(uint32_t uart, uint32_t rx, uint32_t tx, uint32_t cts, uint32_t rts) +{ + if (rx != GPIO_UNCONNECTED) { + UART_PSELRXD(uart) = __GPIO2PIN(rx); + } else { + UART_PSELRXD(uart) = rx; + } + + if (tx != GPIO_UNCONNECTED) { + UART_PSELTXD(uart) = __GPIO2PIN(tx); + } else { + UART_PSELTXD(uart) = tx; + } + + if (cts != GPIO_UNCONNECTED) { + UART_PSELCTS(uart) = __GPIO2PIN(cts); + } else { + UART_PSELCTS(uart) = cts; + } + + if (rts != GPIO_UNCONNECTED) { + UART_PSELRTS(uart) = __GPIO2PIN(rts); + } else { + UART_PSELRTS(uart) = rts; + } +} + +#undef _LOG2 + +void uart_set_baudrate(uint32_t uart, enum uart_baud br) +{ + UART_BAUDRATE(uart) = br; +} + +void uart_set_parity(uint32_t uart, int parity) +{ + UART_CONFIG(uart) |= parity ? UART_CONFIG_PARITY : 0; +} + +void uart_set_flow_control(uint32_t uart, int flow) +{ + UART_CONFIG(uart) |= flow ? UART_CONFIG_HWFC : 0; +} + +void uart_start_tx(uint32_t uart) +{ + PERIPH_TRIGGER_TASK(UART_TASK_STARTTX((uart))); +} + +void uart_send(uint32_t uart, uint16_t byte) +{ + UART_TXD((uart)) = byte; +} + +void uart_stop_tx(uint32_t uart) +{ + PERIPH_TRIGGER_TASK(UART_TASK_STOPTX((uart))); +} + +void uart_start_rx(uint32_t uart) +{ + PERIPH_TRIGGER_TASK(UART_TASK_STARTRX((uart))); +} + +uint16_t uart_recv(uint32_t uart) +{ + return UART_RXD(uart); +} + +void uart_stop_rx(uint32_t uart) +{ + PERIPH_TRIGGER_TASK(UART_TASK_STOPRX((uart))); +} +/**@}*/ + From 25b1e4aad96a5b9f735ca5097812ed6ccfe6859d Mon Sep 17 00:00:00 2001 From: mikisama <41532794+mikisama@users.noreply.github.com> Date: Tue, 7 Dec 2021 09:41:16 +0800 Subject: [PATCH 123/206] stm32: fix typo --- lib/stm32/common/rcc_common_all.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/stm32/common/rcc_common_all.c b/lib/stm32/common/rcc_common_all.c index 4cbe0a81..91c8b41b 100644 --- a/lib/stm32/common/rcc_common_all.c +++ b/lib/stm32/common/rcc_common_all.c @@ -38,7 +38,7 @@ * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) * * @param[in] en Unsigned int32. Logical OR of all enables to be set - * @li If register is RCC_AHBER, from @ref rcc_ahbenr_en + * @li If register is RCC_AHBENR, from @ref rcc_ahbenr_en * @li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en * @li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en */ @@ -51,7 +51,7 @@ void rcc_peripheral_enable_clock(volatile uint32_t *reg, uint32_t en) /*---------------------------------------------------------------------------*/ /** @brief RCC Disable Peripheral Clocks. * - * Enable the clock on particular peripherals. There are three registers + * Disable the clock on particular peripherals. There are three registers * involved, each one controlling the enabling of clocks associated with * the AHB, APB1 and APB2 respectively. Several peripherals could be disabled * simultaneously only if they are controlled by the same register. @@ -62,7 +62,7 @@ void rcc_peripheral_enable_clock(volatile uint32_t *reg, uint32_t en) * (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) * @param[in] en Unsigned int32. Logical OR of all enables to be used for * disabling. - * @li If register is RCC_AHBER, from @ref rcc_ahbenr_en + * @li If register is RCC_AHBENR, from @ref rcc_ahbenr_en * @li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en * @li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en */ From d030a664750e6a805bfb18719100e0afa90d0ff1 Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Sat, 11 Dec 2021 11:05:18 +0100 Subject: [PATCH 124/206] NRF: fix missing .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 062c5177..8e7ed2c9 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ include/libopencmsis/lpc13xx/ include/libopencmsis/lpc17xx/ include/libopencmsis/lpc43xx/ include/libopencmsis/msp432/ +include/libopencmsis/nrf/ include/libopencmsis/pac55xx/ include/libopencmsis/sam/ include/libopencmsis/stm32/ From 1b83a3ce47111b24e249bbf9c789d67649b1d851 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Jan 2022 00:06:32 +0000 Subject: [PATCH 125/206] stm32g4: pwr: Fix CR3 USB PD option bits Presumably copy/paste error in original submission. Verified in RM0440rev1 and rev5. Fixes: c26eab251 Reported-by: qyx on the internet Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g4/pwr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/libopencm3/stm32/g4/pwr.h b/include/libopencm3/stm32/g4/pwr.h index f46558be..ea0a5b48 100644 --- a/include/libopencm3/stm32/g4/pwr.h +++ b/include/libopencm3/stm32/g4/pwr.h @@ -112,8 +112,8 @@ specific memorymap.h header before including this header file.*/ /* --- PWR_CR3 values ------------------------------------------------------- */ #define PWR_CR3_EIWUL (1 << 15) -#define PWR_CR3_UCPD1_DBDIS (1 << 15) -#define PWR_CR3_UCPD1_STDBY (1 << 15) +#define PWR_CR3_UCPD1_DBDIS (1 << 14) +#define PWR_CR3_UCPD1_STDBY (1 << 13) #define PWR_CR3_APC (1 << 10) #define PWR_CR3_RRS (1 << 8) #define PWR_CR3_EWUP5 (1 << 4) From 3f52b7784cada2e20337bc20bc2c859eea29f24c Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 1 Feb 2022 13:15:13 +0000 Subject: [PATCH 126/206] stm32/timers: clarify "advanced timers" restriction by making it vaguer. These days, there's extra timers that support the BDTR register, so the simple "advanced" timer description is no longer sufficiently clear. You have to check your particular reference manual. Fixes: https://github.com/libopencm3/libopencm3/issues/1378 --- lib/stm32/common/timer_common_all.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/stm32/common/timer_common_all.c b/lib/stm32/common/timer_common_all.c index 285f8bcf..cec245a4 100644 --- a/lib/stm32/common/timer_common_all.c +++ b/lib/stm32/common/timer_common_all.c @@ -1347,7 +1347,7 @@ Enables the output in the Break feature of an advanced timer. This does not enable the break functionality itself but only sets the Master Output Enable in the Break and Deadtime Register. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @note It is necessary to call this function to enable the output on an advanced timer even if break or deadtime features are not being used. @@ -1367,7 +1367,7 @@ void timer_enable_break_main_output(uint32_t timer_peripheral) Disables the output in the Break feature of an advanced timer. This clears the Master Output Enable in the Break and Deadtime Register. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1385,7 +1385,7 @@ Enables the automatic output feature of the Break function of an advanced timer so that the output is re-enabled at the next update event following a break event. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1403,7 +1403,7 @@ Disables the automatic output feature of the Break function of an advanced timer so that the output is re-enabled at the next update event following a break event. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1419,7 +1419,7 @@ void timer_disable_break_automatic_output(uint32_t timer_peripheral) Sets the break function to activate when the break input becomes high. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1435,7 +1435,7 @@ void timer_set_break_polarity_high(uint32_t timer_peripheral) Sets the break function to activate when the break input becomes low. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1451,7 +1451,7 @@ void timer_set_break_polarity_low(uint32_t timer_peripheral) Enables the break function of an advanced timer. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1467,7 +1467,7 @@ void timer_enable_break(uint32_t timer_peripheral) Disables the break function of an advanced timer. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1487,7 +1487,7 @@ if no complementary output is present. When the capture-compare output is disabled while the complementary output is enabled, the output is set to its inactive level as defined by the output polarity. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1506,7 +1506,7 @@ timer in which the complementary outputs have been configured. It has no effect if no complementary output is present. When the capture-compare output is disabled, the output is also disabled. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1524,7 +1524,7 @@ Enables the off-state in idle mode for the break function of an advanced timer. When the master output is disabled the output is set to its inactive level as defined by the output polarity. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1541,7 +1541,7 @@ void timer_set_enabled_off_state_in_idle_mode(uint32_t timer_peripheral) Disables the off-state in idle mode for the break function of an advanced timer. When the master output is disabled the output is also disabled. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1559,7 +1559,7 @@ Set the lock bits for an advanced timer. Three levels of lock providing protection against software errors. Once written they cannot be changed until a timer reset has occurred. -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 @@ -1583,7 +1583,7 @@ terms of the number of DTSC cycles: @li Bits 7:5 = 110, deadtime = 8x(32+bits(5:0)) @li Bits 7:5 = 111, deadtime = 16x(32+bits(5:0)) -@note This setting is only valid for the advanced timers. +@note Not all timers support Break/Deadtime features @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 From 72d40647442b264f2a84f23715c0513297b7dd07 Mon Sep 17 00:00:00 2001 From: Evgenii Iarkov Date: Tue, 1 Feb 2022 21:41:20 +0200 Subject: [PATCH 127/206] stm32/g0: rcc: Correct RCC_CCIPR_TIM1SEL_SHIFT value (20 -> 22) Reviewed-by: Karl Palsson --- include/libopencm3/stm32/g0/rcc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/g0/rcc.h b/include/libopencm3/stm32/g0/rcc.h index dd3d4acf..3c5ad375 100644 --- a/include/libopencm3/stm32/g0/rcc.h +++ b/include/libopencm3/stm32/g0/rcc.h @@ -487,7 +487,7 @@ /**@}*/ #define RCC_CCIPR_TIM1SEL_MASK 0x1 -#define RCC_CCIPR_TIM1SEL_SHIFT 20 +#define RCC_CCIPR_TIM1SEL_SHIFT 22 /** @defgroup rcc_ccipr_tim1sel TIM1SEL @{*/ #define RCC_CCIPR_TIM1SEL_TIMPCLK 0 From 9a5a6a2bfd8d60e0099e4165d29ef5c71653c2bc Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Wed, 2 Mar 2022 19:41:04 -0800 Subject: [PATCH 128/206] LM4F: Make SYSCTL enum definitions C++ compliant Refactor definitions to remove pointer-to-int casts --- include/libopencm3/lm4f/systemcontrol.h | 513 +++++++++++++++--------- 1 file changed, 326 insertions(+), 187 deletions(-) diff --git a/include/libopencm3/lm4f/systemcontrol.h b/include/libopencm3/lm4f/systemcontrol.h index 62e22313..458e0a3f 100644 --- a/include/libopencm3/lm4f/systemcontrol.h +++ b/include/libopencm3/lm4f/systemcontrol.h @@ -40,155 +40,294 @@ LGPL License Terms @ref lgpl_license #include #include -#define SYSCTL_DID0 MMIO32(SYSCTL_BASE + 0x000) -#define SYSCTL_DID1 MMIO32(SYSCTL_BASE + 0x004) -#define SYSCTL_PBORCTL MMIO32(SYSCTL_BASE + 0x030) -#define SYSCTL_LDORCTL MMIO32(SYSCTL_BASE + 0x034) -#define SYSCTL_RIS MMIO32(SYSCTL_BASE + 0x050) -#define SYSCTL_IMC MMIO32(SYSCTL_BASE + 0x054) -#define SYSCTL_MISC MMIO32(SYSCTL_BASE + 0x058) -#define SYSCTL_RESC MMIO32(SYSCTL_BASE + 0x05C) -#define SYSCTL_RCC MMIO32(SYSCTL_BASE + 0x060) -#define SYSCTL_PLLCFG MMIO32(SYSCTL_BASE + 0x064) -#define SYSCTL_GPIOHBCTL MMIO32(SYSCTL_BASE + 0x06C) -#define SYSCTL_RCC2 MMIO32(SYSCTL_BASE + 0x070) -#define SYSCTL_MOSCCTL MMIO32(SYSCTL_BASE + 0x07C) -#define SYSCTL_DSLPCLKCFG MMIO32(SYSCTL_BASE + 0x144) -#define SYSCTL_SYSPROP MMIO32(SYSCTL_BASE + 0x14C) -#define SYSCTL_PIOSCCAL MMIO32(SYSCTL_BASE + 0x150) -#define SYSCTL_PIOSCSTAT MMIO32(SYSCTL_BASE + 0x154) -#define SYSCTL_PLLFREQ0 MMIO32(SYSCTL_BASE + 0x160) -#define SYSCTL_PLLFREQ1 MMIO32(SYSCTL_BASE + 0x164) -#define SYSCTL_PLLSTAT MMIO32(SYSCTL_BASE + 0x168) +#define SYSCTL_DID0_OFFSET 0x000 +#define SYSCTL_DID0 MMIO32(SYSCTL_BASE + SYSCTL_DID0_OFFSET) +#define SYSCTL_DID1_OFFSET 0x004 +#define SYSCTL_DID1 MMIO32(SYSCTL_BASE + SYSCTL_DID1_OFFSET) +#define SYSCTL_PBORCTL_OFFSET 0x030 +#define SYSCTL_PBORCTL MMIO32(SYSCTL_BASE + SYSCTL_PBORCTL_OFFSET) +#define SYSCTL_LDORCTL_OFFSET 0x034 +#define SYSCTL_LDORCTL MMIO32(SYSCTL_BASE + SYSCTL_LDORCTL_OFFSET) +#define SYSCTL_RIS_OFFSET 0x050 +#define SYSCTL_RIS MMIO32(SYSCTL_BASE + SYSCTL_RIS_OFFSET) +#define SYSCTL_IMC_OFFSET 0x054 +#define SYSCTL_IMC MMIO32(SYSCTL_BASE + SYSCTL_IMC_OFFSET) +#define SYSCTL_MISC_OFFSET 0x058 +#define SYSCTL_MISC MMIO32(SYSCTL_BASE + SYSCTL_MISC_OFFSET) +#define SYSCTL_RESC_OFFSET 0x05C +#define SYSCTL_RESC MMIO32(SYSCTL_BASE + SYSCTL_RESC_OFFSET) +#define SYSCTL_RCC_OFFSET 0x060 +#define SYSCTL_RCC MMIO32(SYSCTL_BASE + SYSCTL_RCC_OFFSET) +#define SYSCTL_PLLCFG_OFFSET 0x064 +#define SYSCTL_PLLCFG MMIO32(SYSCTL_BASE + SYSCTL_PLLCFG_OFFSET) +#define SYSCTL_GPIOHBCTL_OFFSET 0x06C +#define SYSCTL_GPIOHBCTL MMIO32(SYSCTL_BASE + SYSCTL_GPIOHBCTL_OFFSET) +#define SYSCTL_RCC2_OFFSET 0x070 +#define SYSCTL_RCC2 MMIO32(SYSCTL_BASE + SYSCTL_RCC2_OFFSET) +#define SYSCTL_MOSCCTL_OFFSET 0x07C +#define SYSCTL_MOSCCTL MMIO32(SYSCTL_BASE + SYSCTL_MOSCCTL_OFFSET) +#define SYSCTL_DSLPCLKCFG_OFFSET 0x144 +#define SYSCTL_DSLPCLKCFG MMIO32(SYSCTL_BASE + SYSCTL_DSLPCLKCFG_OFFSET) +#define SYSCTL_SYSPROP_OFFSET 0x14C +#define SYSCTL_SYSPROP MMIO32(SYSCTL_BASE + SYSCTL_SYSPROP_OFFSET) +#define SYSCTL_PIOSCCAL_OFFSET 0x150 +#define SYSCTL_PIOSCCAL MMIO32(SYSCTL_BASE + SYSCTL_PIOSCCAL_OFFSET) +#define SYSCTL_PIOSCSTAT_OFFSET 0x154 +#define SYSCTL_PIOSCSTAT MMIO32(SYSCTL_BASE + SYSCTL_PIOSCSTAT_OFFSET) +#define SYSCTL_PLLFREQ0_OFFSET 0x160 +#define SYSCTL_PLLFREQ0 MMIO32(SYSCTL_BASE + SYSCTL_PLLFREQ0_OFFSET) +#define SYSCTL_PLLFREQ1_OFFSET 0x164 +#define SYSCTL_PLLFREQ1 MMIO32(SYSCTL_BASE + SYSCTL_PLLFREQ1_OFFSET) +#define SYSCTL_PLLSTAT_OFFSET 0x168 +#define SYSCTL_PLLSTAT MMIO32(SYSCTL_BASE + SYSCTL_PLLSTAT_OFFSET) /* Peripheral present */ -#define SYSCTL_PPWD MMIO32(SYSCTL_BASE + 0x300) -#define SYSCTL_PPTIMER MMIO32(SYSCTL_BASE + 0x304) -#define SYSCTL_PPGPIO MMIO32(SYSCTL_BASE + 0x308) -#define SYSCTL_PPDMA MMIO32(SYSCTL_BASE + 0x30C) -#define SYSCTL_PPHIB MMIO32(SYSCTL_BASE + 0x314) -#define SYSCTL_PPUART MMIO32(SYSCTL_BASE + 0x318) -#define SYSCTL_PPSSI MMIO32(SYSCTL_BASE + 0x31C) -#define SYSCTL_PPI2C MMIO32(SYSCTL_BASE + 0x320) -#define SYSCTL_PPUSB MMIO32(SYSCTL_BASE + 0x328) -#define SYSCTL_PPCAN MMIO32(SYSCTL_BASE + 0x334) -#define SYSCTL_PPADC MMIO32(SYSCTL_BASE + 0x338) -#define SYSCTL_PPACMP MMIO32(SYSCTL_BASE + 0x33C) -#define SYSCTL_PPPWM MMIO32(SYSCTL_BASE + 0x340) -#define SYSCTL_PPQEI MMIO32(SYSCTL_BASE + 0x344) -#define SYSCTL_PPEEPROM MMIO32(SYSCTL_BASE + 0x358) -#define SYSCTL_PPWTIMER MMIO32(SYSCTL_BASE + 0x35C) +#define SYSCTL_PPWD_OFFSET 0x300 +#define SYSCTL_PPWD MMIO32(SYSCTL_BASE + SYSCTL_PPWD_OFFSET) +#define SYSCTL_PPTIMER_OFFSET 0x304 +#define SYSCTL_PPTIMER MMIO32(SYSCTL_BASE + SYSCTL_PPTIMER_OFFSET) +#define SYSCTL_PPGPIO_OFFSET 0x308 +#define SYSCTL_PPGPIO MMIO32(SYSCTL_BASE + SYSCTL_PPGPIO_OFFSET) +#define SYSCTL_PPDMA_OFFSET 0x30C +#define SYSCTL_PPDMA MMIO32(SYSCTL_BASE + SYSCTL_PPDMA_OFFSET) +#define SYSCTL_PPHIB_OFFSET 0x314 +#define SYSCTL_PPHIB MMIO32(SYSCTL_BASE + SYSCTL_PPHIB_OFFSET) +#define SYSCTL_PPUART_OFFSET 0x318 +#define SYSCTL_PPUART MMIO32(SYSCTL_BASE + SYSCTL_PPUART_OFFSET) +#define SYSCTL_PPSSI_OFFSET 0x31C +#define SYSCTL_PPSSI MMIO32(SYSCTL_BASE + SYSCTL_PPSSI_OFFSET) +#define SYSCTL_PPI2C_OFFSET 0x320 +#define SYSCTL_PPI2C MMIO32(SYSCTL_BASE + SYSCTL_PPI2C_OFFSET) +#define SYSCTL_PPUSB_OFFSET 0x328 +#define SYSCTL_PPUSB MMIO32(SYSCTL_BASE + SYSCTL_PPUSB_OFFSET) +#define SYSCTL_PPCAN_OFFSET 0x334 +#define SYSCTL_PPCAN MMIO32(SYSCTL_BASE + SYSCTL_PPCAN_OFFSET) +#define SYSCTL_PPADC_OFFSET 0x338 +#define SYSCTL_PPADC MMIO32(SYSCTL_BASE + SYSCTL_PPADC_OFFSET) +#define SYSCTL_PPACMP_OFFSET 0x33C +#define SYSCTL_PPACMP MMIO32(SYSCTL_BASE + SYSCTL_PPACMP_OFFSET) +#define SYSCTL_PPPWM_OFFSET 0x340 +#define SYSCTL_PPPWM MMIO32(SYSCTL_BASE + SYSCTL_PPPWM_OFFSET) +#define SYSCTL_PPQEI_OFFSET 0x344 +#define SYSCTL_PPQEI MMIO32(SYSCTL_BASE + SYSCTL_PPQEI_OFFSET) +#define SYSCTL_PPEEPROM_OFFSET 0x358 +#define SYSCTL_PPEEPROM MMIO32(SYSCTL_BASE + SYSCTL_PPEEPROM_OFFSET) +#define SYSCTL_PPWTIMER_OFFSET 0x35C +#define SYSCTL_PPWTIMER MMIO32(SYSCTL_BASE + SYSCTL_PPWTIMER_OFFSET) /* Peripheral software reset */ -#define SYSCTL_SRWD MMIO32(SYSCTL_BASE + 0x500) -#define SYSCTL_SRTIMER MMIO32(SYSCTL_BASE + 0x504) -#define SYSCTL_SRGPIO MMIO32(SYSCTL_BASE + 0x508) -#define SYSCTL_SRDMA MMIO32(SYSCTL_BASE + 0x50C) -#define SYSCTL_SRHIB MMIO32(SYSCTL_BASE + 0x514) -#define SYSCTL_SRUART MMIO32(SYSCTL_BASE + 0x518) -#define SYSCTL_SRSSI MMIO32(SYSCTL_BASE + 0x51C) -#define SYSCTL_SRI2C MMIO32(SYSCTL_BASE + 0x520) -#define SYSCTL_SRUSB MMIO32(SYSCTL_BASE + 0x528) -#define SYSCTL_SRCAN MMIO32(SYSCTL_BASE + 0x534) -#define SYSCTL_SRADC MMIO32(SYSCTL_BASE + 0x538) -#define SYSCTL_SRACMP MMIO32(SYSCTL_BASE + 0x53C) -#define SYSCTL_SRPWM MMIO32(SYSCTL_BASE + 0x540) -#define SYSCTL_SRQEI MMIO32(SYSCTL_BASE + 0x544) -#define SYSCTL_SREEPROM MMIO32(SYSCTL_BASE + 0x558) -#define SYSCTL_SRWTIMER MMIO32(SYSCTL_BASE + 0x55C) +#define SYSCTL_SRWD_OFFSET 0x500 +#define SYSCTL_SRWD MMIO32(SYSCTL_BASE + SYSCTL_SRWD_OFFSET) +#define SYSCTL_SRTIMER_OFFSET 0x504 +#define SYSCTL_SRTIMER MMIO32(SYSCTL_BASE + SYSCTL_SRTIMER_OFFSET) +#define SYSCTL_SRGPIO_OFFSET 0x508 +#define SYSCTL_SRGPIO MMIO32(SYSCTL_BASE + SYSCTL_SRGPIO_OFFSET) +#define SYSCTL_SRDMA_OFFSET 0x50C +#define SYSCTL_SRDMA MMIO32(SYSCTL_BASE + SYSCTL_SRDMA_OFFSET) +#define SYSCTL_SRHIB_OFFSET 0x514 +#define SYSCTL_SRHIB MMIO32(SYSCTL_BASE + SYSCTL_SRHIB_OFFSET) +#define SYSCTL_SRUART_OFFSET 0x518 +#define SYSCTL_SRUART MMIO32(SYSCTL_BASE + SYSCTL_SRUART_OFFSET) +#define SYSCTL_SRSSI_OFFSET 0x51C +#define SYSCTL_SRSSI MMIO32(SYSCTL_BASE + SYSCTL_SRSSI_OFFSET) +#define SYSCTL_SRI2C_OFFSET 0x520 +#define SYSCTL_SRI2C MMIO32(SYSCTL_BASE + SYSCTL_SRI2C_OFFSET) +#define SYSCTL_SRUSB_OFFSET 0x528 +#define SYSCTL_SRUSB MMIO32(SYSCTL_BASE + SYSCTL_SRUSB_OFFSET) +#define SYSCTL_SRCAN_OFFSET 0x534 +#define SYSCTL_SRCAN MMIO32(SYSCTL_BASE + SYSCTL_SRCAN_OFFSET) +#define SYSCTL_SRADC_OFFSET 0x538 +#define SYSCTL_SRADC MMIO32(SYSCTL_BASE + SYSCTL_SRADC_OFFSET) +#define SYSCTL_SRACMP_OFFSET 0x53C +#define SYSCTL_SRACMP MMIO32(SYSCTL_BASE + SYSCTL_SRACMP_OFFSET) +#define SYSCTL_SRPWM_OFFSET 0x540 +#define SYSCTL_SRPWM MMIO32(SYSCTL_BASE + SYSCTL_SRPWM_OFFSET) +#define SYSCTL_SRQEI_OFFSET 0x544 +#define SYSCTL_SRQEI MMIO32(SYSCTL_BASE + SYSCTL_SRQEI_OFFSET) +#define SYSCTL_SREEPROM_OFFSET 0x558 +#define SYSCTL_SREEPROM MMIO32(SYSCTL_BASE + SYSCTL_SREEPROM_OFFSET) +#define SYSCTL_SRWTIMER_OFFSET 0x55C +#define SYSCTL_SRWTIMER MMIO32(SYSCTL_BASE + SYSCTL_SRWTIMER_OFFSET) /* Peripheral run mode clock gating control */ -#define SYSCTL_RCGCWD MMIO32(SYSCTL_BASE + 0x600) -#define SYSCTL_RCGCTIMER MMIO32(SYSCTL_BASE + 0x604) -#define SYSCTL_RCGCGPIO MMIO32(SYSCTL_BASE + 0x608) -#define SYSCTL_RCGCDMA MMIO32(SYSCTL_BASE + 0x60C) -#define SYSCTL_RCGCHIB MMIO32(SYSCTL_BASE + 0x614) -#define SYSCTL_RCGCUART MMIO32(SYSCTL_BASE + 0x618) -#define SYSCTL_RCGCSSI MMIO32(SYSCTL_BASE + 0x61C) -#define SYSCTL_RCGCI2C MMIO32(SYSCTL_BASE + 0x620) -#define SYSCTL_RCGCUSB MMIO32(SYSCTL_BASE + 0x628) -#define SYSCTL_RCGCCAN MMIO32(SYSCTL_BASE + 0x634) -#define SYSCTL_RCGCADC MMIO32(SYSCTL_BASE + 0x638) -#define SYSCTL_RCGCACMP MMIO32(SYSCTL_BASE + 0x63C) -#define SYSCTL_RCGCPWM MMIO32(SYSCTL_BASE + 0x640) -#define SYSCTL_RCGCQEI MMIO32(SYSCTL_BASE + 0x644) -#define SYSCTL_RCGCEEPROM MMIO32(SYSCTL_BASE + 0x658) -#define SYSCTL_RCGCWTIMER MMIO32(SYSCTL_BASE + 0x65C) +#define SYSCTL_RCGCWD_OFFSET 0x600 +#define SYSCTL_RCGCWD MMIO32(SYSCTL_BASE + SYSCTL_RCGCWD_OFFSET) +#define SYSCTL_RCGCTIMER_OFFSET 0x604 +#define SYSCTL_RCGCTIMER MMIO32(SYSCTL_BASE + SYSCTL_RCGCTIMER_OFFSET) +#define SYSCTL_RCGCGPIO_OFFSET 0x608 +#define SYSCTL_RCGCGPIO MMIO32(SYSCTL_BASE + SYSCTL_RCGCGPIO_OFFSET) +#define SYSCTL_RCGCDMA_OFFSET 0x60C +#define SYSCTL_RCGCDMA MMIO32(SYSCTL_BASE + SYSCTL_RCGCDMA_OFFSET) +#define SYSCTL_RCGCHIB_OFFSET 0x614 +#define SYSCTL_RCGCHIB MMIO32(SYSCTL_BASE + SYSCTL_RCGCHIB_OFFSET) +#define SYSCTL_RCGCUART_OFFSET 0x618 +#define SYSCTL_RCGCUART MMIO32(SYSCTL_BASE + SYSCTL_RCGCUART_OFFSET) +#define SYSCTL_RCGCSSI_OFFSET 0x61C +#define SYSCTL_RCGCSSI MMIO32(SYSCTL_BASE + SYSCTL_RCGCSSI_OFFSET) +#define SYSCTL_RCGCI2C_OFFSET 0x620 +#define SYSCTL_RCGCI2C MMIO32(SYSCTL_BASE + SYSCTL_RCGCI2C_OFFSET) +#define SYSCTL_RCGCUSB_OFFSET 0x628 +#define SYSCTL_RCGCUSB MMIO32(SYSCTL_BASE + SYSCTL_RCGCUSB_OFFSET) +#define SYSCTL_RCGCCAN_OFFSET 0x634 +#define SYSCTL_RCGCCAN MMIO32(SYSCTL_BASE + SYSCTL_RCGCCAN_OFFSET) +#define SYSCTL_RCGCADC_OFFSET 0x638 +#define SYSCTL_RCGCADC MMIO32(SYSCTL_BASE + SYSCTL_RCGCADC_OFFSET) +#define SYSCTL_RCGCACMP_OFFSET 0x63C +#define SYSCTL_RCGCACMP MMIO32(SYSCTL_BASE + SYSCTL_RCGCACMP_OFFSET) +#define SYSCTL_RCGCPWM_OFFSET 0x640 +#define SYSCTL_RCGCPWM MMIO32(SYSCTL_BASE + SYSCTL_RCGCPWM_OFFSET) +#define SYSCTL_RCGCQEI_OFFSET 0x644 +#define SYSCTL_RCGCQEI MMIO32(SYSCTL_BASE + SYSCTL_RCGCQEI_OFFSET) +#define SYSCTL_RCGCEEPROM_OFFSET 0x658 +#define SYSCTL_RCGCEEPROM MMIO32(SYSCTL_BASE + SYSCTL_RCGCEEPROM_OFFSET) +#define SYSCTL_RCGCWTIMER_OFFSET 0x65C +#define SYSCTL_RCGCWTIMER MMIO32(SYSCTL_BASE + SYSCTL_RCGCWTIMER_OFFSET) /* Peripheral sleep mode clock gating control */ -#define SYSCTL_SCGCWD MMIO32(SYSCTL_BASE + 0x700) -#define SYSCTL_SCGCTIMER MMIO32(SYSCTL_BASE + 0x704) -#define SYSCTL_SCGCGPIO MMIO32(SYSCTL_BASE + 0x708) -#define SYSCTL_SCGCDMA MMIO32(SYSCTL_BASE + 0x70C) -#define SYSCTL_SCGCHIB MMIO32(SYSCTL_BASE + 0x714) -#define SYSCTL_SCGCUART MMIO32(SYSCTL_BASE + 0x718) -#define SYSCTL_SCGCSSI MMIO32(SYSCTL_BASE + 0x71C) -#define SYSCTL_SCGCI2C MMIO32(SYSCTL_BASE + 0x720) -#define SYSCTL_SCGCUSB MMIO32(SYSCTL_BASE + 0x728) -#define SYSCTL_SCGCCAN MMIO32(SYSCTL_BASE + 0x734) -#define SYSCTL_SCGCADC MMIO32(SYSCTL_BASE + 0x738) -#define SYSCTL_SCGCACMP MMIO32(SYSCTL_BASE + 0x73C) -#define SYSCTL_SCGCPWM MMIO32(SYSCTL_BASE + 0x740) -#define SYSCTL_SCGCQEI MMIO32(SYSCTL_BASE + 0x744) -#define SYSCTL_SCGCEEPROM MMIO32(SYSCTL_BASE + 0x758) -#define SYSCTL_SCGCWTIMER MMIO32(SYSCTL_BASE + 0x75C) +#define SYSCTL_SCGCWD_OFFSET 0x700 +#define SYSCTL_SCGCWD MMIO32(SYSCTL_BASE + SYSCTL_SCGCWD_OFFSET) +#define SYSCTL_SCGCTIMER_OFFSET 0x704 +#define SYSCTL_SCGCTIMER MMIO32(SYSCTL_BASE + SYSCTL_SCGCTIMER_OFFSET) +#define SYSCTL_SCGCGPIO_OFFSET 0x708 +#define SYSCTL_SCGCGPIO MMIO32(SYSCTL_BASE + SYSCTL_SCGCGPIO_OFFSET) +#define SYSCTL_SCGCDMA_OFFSET 0x70C +#define SYSCTL_SCGCDMA MMIO32(SYSCTL_BASE + SYSCTL_SCGCDMA_OFFSET) +#define SYSCTL_SCGCHIB_OFFSET 0x714 +#define SYSCTL_SCGCHIB MMIO32(SYSCTL_BASE + SYSCTL_SCGCHIB_OFFSET) +#define SYSCTL_SCGCUART_OFFSET 0x718 +#define SYSCTL_SCGCUART MMIO32(SYSCTL_BASE + SYSCTL_SCGCUART_OFFSET) +#define SYSCTL_SCGCSSI_OFFSET 0x71C +#define SYSCTL_SCGCSSI MMIO32(SYSCTL_BASE + SYSCTL_SCGCSSI_OFFSET) +#define SYSCTL_SCGCI2C_OFFSET 0x720 +#define SYSCTL_SCGCI2C MMIO32(SYSCTL_BASE + SYSCTL_SCGCI2C_OFFSET) +#define SYSCTL_SCGCUSB_OFFSET 0x728 +#define SYSCTL_SCGCUSB MMIO32(SYSCTL_BASE + SYSCTL_SCGCUSB_OFFSET) +#define SYSCTL_SCGCCAN_OFFSET 0x734 +#define SYSCTL_SCGCCAN MMIO32(SYSCTL_BASE + SYSCTL_SCGCCAN_OFFSET) +#define SYSCTL_SCGCADC_OFFSET 0x738 +#define SYSCTL_SCGCADC MMIO32(SYSCTL_BASE + SYSCTL_SCGCADC_OFFSET) +#define SYSCTL_SCGCACMP_OFFSET 0x73C +#define SYSCTL_SCGCACMP MMIO32(SYSCTL_BASE + SYSCTL_SCGCACMP_OFFSET) +#define SYSCTL_SCGCPWM_OFFSET 0x740 +#define SYSCTL_SCGCPWM MMIO32(SYSCTL_BASE + SYSCTL_SCGCPWM_OFFSET) +#define SYSCTL_SCGCQEI_OFFSET 0x744 +#define SYSCTL_SCGCQEI MMIO32(SYSCTL_BASE + SYSCTL_SCGCQEI_OFFSET) +#define SYSCTL_SCGCEEPROM_OFFSET 0x758 +#define SYSCTL_SCGCEEPROM MMIO32(SYSCTL_BASE + SYSCTL_SCGCEEPROM_OFFSET) +#define SYSCTL_SCGCWTIMER_OFFSET 0x75C +#define SYSCTL_SCGCWTIMER MMIO32(SYSCTL_BASE + SYSCTL_SCGCWTIMER_OFFSET) /* Peripheral deep-sleep mode clock gating control */ -#define SYSCTL_DCGCWD MMIO32(SYSCTL_BASE + 0x800) -#define SYSCTL_DCGCTIMER MMIO32(SYSCTL_BASE + 0x804) -#define SYSCTL_DCGCGPIO MMIO32(SYSCTL_BASE + 0x808) -#define SYSCTL_DCGCDMA MMIO32(SYSCTL_BASE + 0x80C) -#define SYSCTL_DCGCHIB MMIO32(SYSCTL_BASE + 0x814) -#define SYSCTL_DCGCUART MMIO32(SYSCTL_BASE + 0x818) -#define SYSCTL_DCGCSSI MMIO32(SYSCTL_BASE + 0x81C) -#define SYSCTL_DCGCI2C MMIO32(SYSCTL_BASE + 0x820) -#define SYSCTL_DCGCUSB MMIO32(SYSCTL_BASE + 0x828) -#define SYSCTL_DCGCCAN MMIO32(SYSCTL_BASE + 0x834) -#define SYSCTL_DCGCADC MMIO32(SYSCTL_BASE + 0x838) -#define SYSCTL_DCGCACMP MMIO32(SYSCTL_BASE + 0x83C) -#define SYSCTL_DCGCPWM MMIO32(SYSCTL_BASE + 0x840) -#define SYSCTL_DCGCQEI MMIO32(SYSCTL_BASE + 0x844) -#define SYSCTL_DCGCEEPROM MMIO32(SYSCTL_BASE + 0x858) -#define SYSCTL_DCGCWTIMER MMIO32(SYSCTL_BASE + 0x85C) +#define SYSCTL_DCGCWD_OFFSET 0x800 +#define SYSCTL_DCGCWD MMIO32(SYSCTL_BASE + SYSCTL_DCGCWD_OFFSET) +#define SYSCTL_DCGCTIMER_OFFSET 0x804 +#define SYSCTL_DCGCTIMER MMIO32(SYSCTL_BASE + SYSCTL_DCGCTIMER_OFFSET) +#define SYSCTL_DCGCGPIO_OFFSET 0x808 +#define SYSCTL_DCGCGPIO MMIO32(SYSCTL_BASE + SYSCTL_DCGCGPIO_OFFSET) +#define SYSCTL_DCGCDMA_OFFSET 0x80C +#define SYSCTL_DCGCDMA MMIO32(SYSCTL_BASE + SYSCTL_DCGCDMA_OFFSET) +#define SYSCTL_DCGCHIB_OFFSET 0x814 +#define SYSCTL_DCGCHIB MMIO32(SYSCTL_BASE + SYSCTL_DCGCHIB_OFFSET) +#define SYSCTL_DCGCUART_OFFSET 0x818 +#define SYSCTL_DCGCUART MMIO32(SYSCTL_BASE + SYSCTL_DCGCUART_OFFSET) +#define SYSCTL_DCGCSSI_OFFSET 0x81C +#define SYSCTL_DCGCSSI MMIO32(SYSCTL_BASE + SYSCTL_DCGCSSI_OFFSET) +#define SYSCTL_DCGCI2C_OFFSET 0x820 +#define SYSCTL_DCGCI2C MMIO32(SYSCTL_BASE + SYSCTL_DCGCI2C_OFFSET) +#define SYSCTL_DCGCUSB_OFFSET 0x828 +#define SYSCTL_DCGCUSB MMIO32(SYSCTL_BASE + SYSCTL_DCGCUSB_OFFSET) +#define SYSCTL_DCGCCAN_OFFSET 0x834 +#define SYSCTL_DCGCCAN MMIO32(SYSCTL_BASE + SYSCTL_DCGCCAN_OFFSET) +#define SYSCTL_DCGCADC_OFFSET 0x838 +#define SYSCTL_DCGCADC MMIO32(SYSCTL_BASE + SYSCTL_DCGCADC_OFFSET) +#define SYSCTL_DCGCACMP_OFFSET 0x83C +#define SYSCTL_DCGCACMP MMIO32(SYSCTL_BASE + SYSCTL_DCGCACMP_OFFSET) +#define SYSCTL_DCGCPWM_OFFSET 0x840 +#define SYSCTL_DCGCPWM MMIO32(SYSCTL_BASE + SYSCTL_DCGCPWM_OFFSET) +#define SYSCTL_DCGCQEI_OFFSET 0x844 +#define SYSCTL_DCGCQEI MMIO32(SYSCTL_BASE + SYSCTL_DCGCQEI_OFFSET) +#define SYSCTL_DCGCEEPROM_OFFSET 0x858 +#define SYSCTL_DCGCEEPROM MMIO32(SYSCTL_BASE + SYSCTL_DCGCEEPROM_OFFSET) +#define SYSCTL_DCGCWTIMER_OFFSET 0x85C +#define SYSCTL_DCGCWTIMER MMIO32(SYSCTL_BASE + SYSCTL_DCGCWTIMER_OFFSET) /* Peripheral ready */ -#define SYSCTL_PRWD MMIO32(SYSCTL_BASE + 0xA00) -#define SYSCTL_PRTIMER MMIO32(SYSCTL_BASE + 0xA04) -#define SYSCTL_PRGPIO MMIO32(SYSCTL_BASE + 0xA08) -#define SYSCTL_PRDMA MMIO32(SYSCTL_BASE + 0xA0C) -#define SYSCTL_PRHIB MMIO32(SYSCTL_BASE + 0xA14) -#define SYSCTL_PRUART MMIO32(SYSCTL_BASE + 0xA18) -#define SYSCTL_PRSSI MMIO32(SYSCTL_BASE + 0xA1C) -#define SYSCTL_PRI2C MMIO32(SYSCTL_BASE + 0xA20) -#define SYSCTL_PRUSB MMIO32(SYSCTL_BASE + 0xA28) -#define SYSCTL_PRCAN MMIO32(SYSCTL_BASE + 0xA34) -#define SYSCTL_PRADC MMIO32(SYSCTL_BASE + 0xA38) -#define SYSCTL_PRACMP MMIO32(SYSCTL_BASE + 0xA3C) -#define SYSCTL_PRPWM MMIO32(SYSCTL_BASE + 0xA40) -#define SYSCTL_PRQEI MMIO32(SYSCTL_BASE + 0xA44) -#define SYSCTL_PREEPROM MMIO32(SYSCTL_BASE + 0xA58) -#define SYSCTL_PRWTIMER MMIO32(SYSCTL_BASE + 0xA5C) +#define SYSCTL_PRWD_OFFSET 0xA00 +#define SYSCTL_PRWD MMIO32(SYSCTL_BASE + SYSCTL_PRWD_OFFSET) +#define SYSCTL_PRTIMER_OFFSET 0xA04 +#define SYSCTL_PRTIMER MMIO32(SYSCTL_BASE + SYSCTL_PRTIMER_OFFSET) +#define SYSCTL_PRGPIO_OFFSET 0xA08 +#define SYSCTL_PRGPIO MMIO32(SYSCTL_BASE + SYSCTL_PRGPIO_OFFSET) +#define SYSCTL_PRDMA_OFFSET 0xA0C +#define SYSCTL_PRDMA MMIO32(SYSCTL_BASE + SYSCTL_PRDMA_OFFSET) +#define SYSCTL_PRHIB_OFFSET 0xA14 +#define SYSCTL_PRHIB MMIO32(SYSCTL_BASE + SYSCTL_PRHIB_OFFSET) +#define SYSCTL_PRUART_OFFSET 0xA18 +#define SYSCTL_PRUART MMIO32(SYSCTL_BASE + SYSCTL_PRUART_OFFSET) +#define SYSCTL_PRSSI_OFFSET 0xA1C +#define SYSCTL_PRSSI MMIO32(SYSCTL_BASE + SYSCTL_PRSSI_OFFSET) +#define SYSCTL_PRI2C_OFFSET 0xA20 +#define SYSCTL_PRI2C MMIO32(SYSCTL_BASE + SYSCTL_PRI2C_OFFSET) +#define SYSCTL_PRUSB_OFFSET 0xA28 +#define SYSCTL_PRUSB MMIO32(SYSCTL_BASE + SYSCTL_PRUSB_OFFSET) +#define SYSCTL_PRCAN_OFFSET 0xA34 +#define SYSCTL_PRCAN MMIO32(SYSCTL_BASE + SYSCTL_PRCAN_OFFSET) +#define SYSCTL_PRADC_OFFSET 0xA38 +#define SYSCTL_PRADC MMIO32(SYSCTL_BASE + SYSCTL_PRADC_OFFSET) +#define SYSCTL_PRACMP_OFFSET 0xA3C +#define SYSCTL_PRACMP MMIO32(SYSCTL_BASE + SYSCTL_PRACMP_OFFSET) +#define SYSCTL_PRPWM_OFFSET 0xA40 +#define SYSCTL_PRPWM MMIO32(SYSCTL_BASE + SYSCTL_PRPWM_OFFSET) +#define SYSCTL_PRQEI_OFFSET 0xA44 +#define SYSCTL_PRQEI MMIO32(SYSCTL_BASE + SYSCTL_PRQEI_OFFSET) +#define SYSCTL_PREEPROM_OFFSET 0xA58 +#define SYSCTL_PREEPROM MMIO32(SYSCTL_BASE + SYSCTL_PREEPROM_OFFSET) +#define SYSCTL_PRWTIMER_OFFSET 0xA5C +#define SYSCTL_PRWTIMER MMIO32(SYSCTL_BASE + SYSCTL_PRWTIMER_OFFSET) /* ============================================================================= * System Control Legacy Registers * ---------------------------------------------------------------------------*/ #ifdef LM4F_LEGACY_SYSCTL -#define SYSCTL_DC0 MMIO32(SYSCTL_BASE + 0x008) -#define SYSCTL_DC1 MMIO32(SYSCTL_BASE + 0x010) -#define SYSCTL_DC2 MMIO32(SYSCTL_BASE + 0x014) -#define SYSCTL_DC3 MMIO32(SYSCTL_BASE + 0x018) -#define SYSCTL_DC4 MMIO32(SYSCTL_BASE + 0x01C) -#define SYSCTL_DC5 MMIO32(SYSCTL_BASE + 0x020) -#define SYSCTL_DC6 MMIO32(SYSCTL_BASE + 0x024) -#define SYSCTL_DC7 MMIO32(SYSCTL_BASE + 0x028) -#define SYSCTL_DC8 MMIO32(SYSCTL_BASE + 0x02C) -#define SYSCTL_SRCR0 MMIO32(SYSCTL_BASE + 0x040) -#define SYSCTL_SRCR1 MMIO32(SYSCTL_BASE + 0x044) -#define SYSCTL_SRCR2 MMIO32(SYSCTL_BASE + 0x048) -#define SYSCTL_RCGC0 MMIO32(SYSCTL_BASE + 0x100) -#define SYSCTL_RCGC1 MMIO32(SYSCTL_BASE + 0x104) -#define SYSCTL_RCGC2 MMIO32(SYSCTL_BASE + 0x108) -#define SYSCTL_SCGC0 MMIO32(SYSCTL_BASE + 0x110) -#define SYSCTL_SCGC1 MMIO32(SYSCTL_BASE + 0x114) -#define SYSCTL_SCGC2 MMIO32(SYSCTL_BASE + 0x118) -#define SYSCTL_DCGC0 MMIO32(SYSCTL_BASE + 0x120) -#define SYSCTL_DCGC1 MMIO32(SYSCTL_BASE + 0x124) -#define SYSCTL_DCGC2 MMIO32(SYSCTL_BASE + 0x128) -#define SYSCTL_DC9 MMIO32(SYSCTL_BASE + 0x190) -#define SYSCTL_NVMSTAT MMIO32(SYSCTL_BASE + 0x1A0) +#define SYSCTL_DC0_OFFSET 0x008 +#define SYSCTL_DC0 MMIO32(SYSCTL_BASE + SYSCTL_DC0_OFFSET) +#define SYSCTL_DC1_OFFSET 0x010 +#define SYSCTL_DC1 MMIO32(SYSCTL_BASE + SYSCTL_DC1_OFFSET) +#define SYSCTL_DC2_OFFSET 0x014 +#define SYSCTL_DC2 MMIO32(SYSCTL_BASE + SYSCTL_DC2_OFFSET) +#define SYSCTL_DC3_OFFSET 0x018 +#define SYSCTL_DC3 MMIO32(SYSCTL_BASE + SYSCTL_DC3_OFFSET) +#define SYSCTL_DC4_OFFSET 0x01C +#define SYSCTL_DC4 MMIO32(SYSCTL_BASE + SYSCTL_DC4_OFFSET) +#define SYSCTL_DC5_OFFSET 0x020 +#define SYSCTL_DC5 MMIO32(SYSCTL_BASE + SYSCTL_DC5_OFFSET) +#define SYSCTL_DC6_OFFSET 0x024 +#define SYSCTL_DC6 MMIO32(SYSCTL_BASE + SYSCTL_DC6_OFFSET) +#define SYSCTL_DC7_OFFSET 0x028 +#define SYSCTL_DC7 MMIO32(SYSCTL_BASE + SYSCTL_DC7_OFFSET) +#define SYSCTL_DC8_OFFSET 0x02C +#define SYSCTL_DC8 MMIO32(SYSCTL_BASE + SYSCTL_DC8_OFFSET) +#define SYSCTL_SRCR0_OFFSET 0x040 +#define SYSCTL_SRCR0 MMIO32(SYSCTL_BASE + SYSCTL_SRCR0_OFFSET) +#define SYSCTL_SRCR1_OFFSET 0x044 +#define SYSCTL_SRCR1 MMIO32(SYSCTL_BASE + SYSCTL_SRCR1_OFFSET) +#define SYSCTL_SRCR2_OFFSET 0x048 +#define SYSCTL_SRCR2 MMIO32(SYSCTL_BASE + SYSCTL_SRCR2_OFFSET) +#define SYSCTL_RCGC0_OFFSET 0x100 +#define SYSCTL_RCGC0 MMIO32(SYSCTL_BASE + SYSCTL_RCGC0_OFFSET) +#define SYSCTL_RCGC1_OFFSET 0x104 +#define SYSCTL_RCGC1 MMIO32(SYSCTL_BASE + SYSCTL_RCGC1_OFFSET) +#define SYSCTL_RCGC2_OFFSET 0x108 +#define SYSCTL_RCGC2 MMIO32(SYSCTL_BASE + SYSCTL_RCGC2_OFFSET) +#define SYSCTL_SCGC0_OFFSET 0x110 +#define SYSCTL_SCGC0 MMIO32(SYSCTL_BASE + SYSCTL_SCGC0_OFFSET) +#define SYSCTL_SCGC1_OFFSET 0x114 +#define SYSCTL_SCGC1 MMIO32(SYSCTL_BASE + SYSCTL_SCGC1_OFFSET) +#define SYSCTL_SCGC2_OFFSET 0x118 +#define SYSCTL_SCGC2 MMIO32(SYSCTL_BASE + SYSCTL_SCGC2_OFFSET) +#define SYSCTL_DCGC0_OFFSET 0x120 +#define SYSCTL_DCGC0 MMIO32(SYSCTL_BASE + SYSCTL_DCGC0_OFFSET) +#define SYSCTL_DCGC1_OFFSET 0x124 +#define SYSCTL_DCGC1 MMIO32(SYSCTL_BASE + SYSCTL_DCGC1_OFFSET) +#define SYSCTL_DCGC2_OFFSET 0x128 +#define SYSCTL_DCGC2 MMIO32(SYSCTL_BASE + SYSCTL_DCGC2_OFFSET) +#define SYSCTL_DC9_OFFSET 0x190 +#define SYSCTL_DC9 MMIO32(SYSCTL_BASE + SYSCTL_DC9_OFFSET) +#define SYSCTL_NVMSTAT_OFFSET 0x1A0 +#define SYSCTL_NVMSTAT MMIO32(SYSCTL_BASE + SYSCTL_NVMSTAT_OFFSET) #endif /* LM4F_LEGACY_SYSCTL */ /* ============================================================================= @@ -490,17 +629,17 @@ enum lm4f_clken { /* * Run clock control */ - RCC_WD0 = ((uint32_t)&SYSCTL_RCGCWD - SYSCTL_BASE) << 5, + RCC_WD0 = SYSCTL_RCGCWD_OFFSET << 5, RCC_WD1, - RCC_TIMER0 = ((uint32_t)&SYSCTL_RCGCTIMER - SYSCTL_BASE) << 5, + RCC_TIMER0 = SYSCTL_RCGCTIMER_OFFSET << 5, RCC_TIMER1, RCC_TIMER2, RCC_TIMER3, RCC_TIMER4, RCC_TIMER5, - RCC_GPIOA = ((uint32_t)&SYSCTL_RCGCGPIO - SYSCTL_BASE) << 5, + RCC_GPIOA = SYSCTL_RCGCGPIO_OFFSET << 5, RCC_GPIOB, RCC_GPIOC, RCC_GPIOD, @@ -516,11 +655,11 @@ enum lm4f_clken { RCC_GPIOP, RCC_GPIOQ, - RCC_DMA = ((uint32_t)&SYSCTL_RCGCDMA - SYSCTL_BASE) << 5, + RCC_DMA = SYSCTL_RCGCDMA_OFFSET << 5, - RCC_HIB = ((uint32_t)&SYSCTL_RCGCGPIO - SYSCTL_BASE) << 5, + RCC_HIB = SYSCTL_RCGCGPIO_OFFSET << 5, - RCC_UART0 = ((uint32_t)&SYSCTL_RCGCUART - SYSCTL_BASE) << 5, + RCC_UART0 = SYSCTL_RCGCUART_OFFSET << 5, RCC_UART1, RCC_UART2, RCC_UART3, @@ -529,37 +668,37 @@ enum lm4f_clken { RCC_UART6, RCC_UART7, - RCC_SSI0 = ((uint32_t)&SYSCTL_RCGCSSI - SYSCTL_BASE) << 5, + RCC_SSI0 = SYSCTL_RCGCSSI_OFFSET << 5, RCC_SSI1, RCC_SSI2, RCC_SSI3, - RCC_I2C0 = ((uint32_t)&SYSCTL_RCGCI2C - SYSCTL_BASE) << 5, + RCC_I2C0 = SYSCTL_RCGCI2C_OFFSET << 5, RCC_I2C1, RCC_I2C2, RCC_I2C3, RCC_I2C4, RCC_I2C5, - RCC_USB0 = ((uint32_t)&SYSCTL_RCGCUSB - SYSCTL_BASE) << 5, + RCC_USB0 = SYSCTL_RCGCUSB_OFFSET << 5, - RCC_CAN0 = ((uint32_t)&SYSCTL_RCGCCAN - SYSCTL_BASE) << 5, + RCC_CAN0 = SYSCTL_RCGCCAN_OFFSET << 5, RCC_CAN1, - RCC_ADC0 = ((uint32_t)&SYSCTL_RCGCADC - SYSCTL_BASE) << 5, + RCC_ADC0 = SYSCTL_RCGCADC_OFFSET << 5, RCC_ADC1, - RCC_ACMP0 = ((uint32_t)&SYSCTL_RCGCACMP - SYSCTL_BASE) << 5, + RCC_ACMP0 = SYSCTL_RCGCACMP_OFFSET << 5, - RCC_PWM0 = ((uint32_t)&SYSCTL_RCGCPWM - SYSCTL_BASE) << 5, + RCC_PWM0 = SYSCTL_RCGCPWM_OFFSET << 5, RCC_PWM1, - RCC_QEI0 = ((uint32_t)&SYSCTL_RCGCQEI - SYSCTL_BASE) << 5, + RCC_QEI0 = SYSCTL_RCGCQEI_OFFSET << 5, RCC_QEI1, - RCC_EEPROM0 = ((uint32_t)&SYSCTL_RCGCEEPROM - SYSCTL_BASE) << 5, + RCC_EEPROM0 = SYSCTL_RCGCEEPROM_OFFSET << 5, - RCC_WTIMER0 = ((uint32_t)&SYSCTL_RCGCWTIMER - SYSCTL_BASE) << 5, + RCC_WTIMER0 = SYSCTL_RCGCWTIMER_OFFSET << 5, RCC_WTIMER1, RCC_WTIMER2, RCC_WTIMER3, @@ -570,17 +709,17 @@ enum lm4f_clken { /* * Sleep clock control */ - SCC_WD0 = ((uint32_t)&SYSCTL_SCGCWD - SYSCTL_BASE) << 5, + SCC_WD0 = SYSCTL_SCGCWD_OFFSET << 5, SCC_WD1, - SCC_TIMER0 = ((uint32_t)&SYSCTL_SCGCTIMER - SYSCTL_BASE) << 5, + SCC_TIMER0 = SYSCTL_SCGCTIMER_OFFSET << 5, SCC_TIMER1, SCC_TIMER2, SCC_TIMER3, SCC_TIMER4, SCC_TIMER5, - SCC_GPIOA = ((uint32_t)&SYSCTL_SCGCGPIO - SYSCTL_BASE) << 5, + SCC_GPIOA = SYSCTL_SCGCGPIO_OFFSET << 5, SCC_GPIOB, SCC_GPIOC, SCC_GPIOD, @@ -596,11 +735,11 @@ enum lm4f_clken { SCC_GPIOP, SCC_GPIOQ, - SCC_DMA = ((uint32_t)&SYSCTL_SCGCDMA - SYSCTL_BASE) << 5, + SCC_DMA = SYSCTL_SCGCDMA_OFFSET << 5, - SCC_HIB = ((uint32_t)&SYSCTL_SCGCGPIO - SYSCTL_BASE) << 5, + SCC_HIB = SYSCTL_SCGCGPIO_OFFSET << 5, - SCC_UART0 = ((uint32_t)&SYSCTL_SCGCUART - SYSCTL_BASE) << 5, + SCC_UART0 = SYSCTL_SCGCUART_OFFSET << 5, SCC_UART1, SCC_UART2, SCC_UART3, @@ -609,37 +748,37 @@ enum lm4f_clken { SCC_UART6, SCC_UART7, - SCC_SSI0 = ((uint32_t)&SYSCTL_SCGCSSI - SYSCTL_BASE) << 5, + SCC_SSI0 = SYSCTL_SCGCSSI_OFFSET << 5, SCC_SSI1, SCC_SSI2, SCC_SSI3, - SCC_I2C0 = ((uint32_t)&SYSCTL_SCGCI2C - SYSCTL_BASE) << 5, + SCC_I2C0 = SYSCTL_SCGCI2C_OFFSET << 5, SCC_I2C1, SCC_I2C2, SCC_I2C3, SCC_I2C4, SCC_I2C5, - SCC_USB0 = ((uint32_t)&SYSCTL_SCGCUSB - SYSCTL_BASE) << 5, + SCC_USB0 = SYSCTL_SCGCUSB_OFFSET << 5, - SCC_CAN0 = ((uint32_t)&SYSCTL_SCGCCAN - SYSCTL_BASE) << 5, + SCC_CAN0 = SYSCTL_SCGCCAN_OFFSET << 5, SCC_CAN1, - SCC_ADC0 = ((uint32_t)&SYSCTL_SCGCADC - SYSCTL_BASE) << 5, + SCC_ADC0 = SYSCTL_SCGCADC_OFFSET << 5, SCC_ADC1, - SCC_ACMP0 = ((uint32_t)&SYSCTL_SCGCACMP - SYSCTL_BASE) << 5, + SCC_ACMP0 = SYSCTL_SCGCACMP_OFFSET << 5, - SCC_PWM0 = ((uint32_t)&SYSCTL_SCGCPWM - SYSCTL_BASE) << 5, + SCC_PWM0 = SYSCTL_SCGCPWM_OFFSET << 5, SCC_PWM1, - SCC_QEI0 = ((uint32_t)&SYSCTL_SCGCQEI - SYSCTL_BASE) << 5, + SCC_QEI0 = SYSCTL_SCGCQEI_OFFSET << 5, SCC_QEI1, - SCC_EEPROM0 = ((uint32_t)&SYSCTL_SCGCEEPROM - SYSCTL_BASE) << 5, + SCC_EEPROM0 = SYSCTL_SCGCEEPROM_OFFSET << 5, - SCC_WTIMER0 = ((uint32_t)&SYSCTL_SCGCWTIMER - SYSCTL_BASE) << 5, + SCC_WTIMER0 = SYSCTL_SCGCWTIMER_OFFSET << 5, SCC_WTIMER1, SCC_WTIMER2, SCC_WTIMER3, @@ -649,17 +788,17 @@ enum lm4f_clken { /* * Deep-sleep clock control */ - DCC_WD0 = ((uint32_t)&SYSCTL_DCGCWD - SYSCTL_BASE) << 5, + DCC_WD0 = SYSCTL_DCGCWD_OFFSET << 5, DCC_WD1, - DCC_TIMER0 = ((uint32_t)&SYSCTL_DCGCTIMER - SYSCTL_BASE) << 5, + DCC_TIMER0 = SYSCTL_DCGCTIMER_OFFSET << 5, DCC_TIMER1, DCC_TIMER2, DCC_TIMER3, DCC_TIMER4, DCC_TIMER5, - DCC_GPIOA = ((uint32_t)&SYSCTL_DCGCGPIO - SYSCTL_BASE) << 5, + DCC_GPIOA = SYSCTL_DCGCGPIO_OFFSET << 5, DCC_GPIOB, DCC_GPIOC, DCC_GPIOD, @@ -675,11 +814,11 @@ enum lm4f_clken { DCC_GPIOP, DCC_GPIOQ, - DCC_DMA = ((uint32_t)&SYSCTL_DCGCDMA - SYSCTL_BASE) << 5, + DCC_DMA = SYSCTL_DCGCDMA_OFFSET << 5, - DCC_HIB = ((uint32_t)&SYSCTL_DCGCGPIO - SYSCTL_BASE) << 5, + DCC_HIB = SYSCTL_DCGCGPIO_OFFSET << 5, - DCC_UART0 = ((uint32_t)&SYSCTL_DCGCUART - SYSCTL_BASE) << 5, + DCC_UART0 = SYSCTL_DCGCUART_OFFSET << 5, DCC_UART1, DCC_UART2, DCC_UART3, @@ -688,37 +827,37 @@ enum lm4f_clken { DCC_UART6, DCC_UART7, - DCC_SSI0 = ((uint32_t)&SYSCTL_DCGCSSI - SYSCTL_BASE) << 5, + DCC_SSI0 = SYSCTL_DCGCSSI_OFFSET << 5, DCC_SSI1, DCC_SSI2, DCC_SSI3, - DCC_I2C0 = ((uint32_t)&SYSCTL_DCGCI2C - SYSCTL_BASE) << 5, + DCC_I2C0 = SYSCTL_DCGCI2C_OFFSET << 5, DCC_I2C1, DCC_I2C2, DCC_I2C3, DCC_I2C4, DCC_I2C5, - DCC_USB0 = ((uint32_t)&SYSCTL_DCGCUSB - SYSCTL_BASE) << 5, + DCC_USB0 = SYSCTL_DCGCUSB_OFFSET << 5, - DCC_CAN0 = ((uint32_t)&SYSCTL_DCGCCAN - SYSCTL_BASE) << 5, + DCC_CAN0 = SYSCTL_DCGCCAN_OFFSET << 5, DCC_CAN1, - DCC_ADC0 = ((uint32_t)&SYSCTL_DCGCADC - SYSCTL_BASE) << 5, + DCC_ADC0 = SYSCTL_DCGCADC_OFFSET << 5, DCC_ADC1, - DCC_ACMP0 = ((uint32_t)&SYSCTL_DCGCACMP - SYSCTL_BASE) << 5, + DCC_ACMP0 = SYSCTL_DCGCACMP_OFFSET << 5, - DCC_PWM0 = ((uint32_t)&SYSCTL_DCGCPWM - SYSCTL_BASE) << 5, + DCC_PWM0 = SYSCTL_DCGCPWM_OFFSET << 5, DCC_PWM1, - DCC_QEI0 = ((uint32_t)&SYSCTL_DCGCQEI - SYSCTL_BASE) << 5, + DCC_QEI0 = SYSCTL_DCGCQEI_OFFSET << 5, DCC_QEI1, - DCC_EEPROM0 = ((uint32_t)&SYSCTL_DCGCEEPROM - SYSCTL_BASE) << 5, + DCC_EEPROM0 = SYSCTL_DCGCEEPROM_OFFSET << 5, - DCC_WTIMER0 = ((uint32_t)&SYSCTL_DCGCWTIMER - SYSCTL_BASE) << 5, + DCC_WTIMER0 = SYSCTL_DCGCWTIMER_OFFSET << 5, DCC_WTIMER1, DCC_WTIMER2, DCC_WTIMER3, From 96ae7ff38a3ab3f57eb5c9ae04e98c88c89e58d4 Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Fri, 25 Feb 2022 15:36:13 +0100 Subject: [PATCH 129/206] STM32H7: Add linker support for STM32H7[2345] families * added: device data for STM32H7[2345] MCUs. CPU spec prefers presence of Cortex-M7 core, where Cortex-M7 and Cortex-M4 are both present --- ld/devices.data | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ld/devices.data b/ld/devices.data index 035e22b5..57a3de93 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -259,6 +259,18 @@ stm32g4?[34]?b* stm32g4ccm ROM=128K RAM=96K CCM=32K stm32g4?[34]?c* stm32g4ccm ROM=256K RAM=96K CCM=32K stm32g4?[34]?e* stm32g4ccm ROM=512K RAM=96K CCM=32K +# For STM32H7 CCM is called D-TCM +stm32h72[35]?e* stm32h7xxxe RAM=128K RAM1=16K RAM2=16K RAM4=16K CCM=128K +stm32h72[35]?g* stm32h7xxxg RAM=128K RAM1=16K RAM2=16K RAM4=16K CCM=128K +stm32h730?b* stm32h7xxxb RAM=128K RAM1=16K RAM2=16K RAM4=16K CCM=128K +stm32h73[35]?g* stm32h7xxxg RAM=128K RAM1=16K RAM2=16K RAM4=16K CCM=128K +stm32h742?i* stm32h7xxxi RAM=384K RAM1=32K RAM2=16K RAM4=64K CCM=128K +stm32h742?g* stm32h74xxg RAM=384K RAM1=32K RAM2=16K RAM4=64K CCM=128K +stm32h74[357]?i* stm32h7xxxi RAM=512K RAM1=128K RAM2=128K RAM3=32K RAM4=64K CCM=128K +stm32h74[357]?g* stm32h74xxg RAM=512K RAM1=128K RAM2=128K RAM3=32K RAM4=64K CCM=128K +stm32h75[357]?i* stm32h7xxxi RAM=512K RAM1=128K RAM2=128K RAM3=32K RAM4=64K CCM=128K +stm32h750?b* stm32h7xxxb RAM=512K RAM1=128K RAM2=128K RAM3=32K RAM4=64K CCM=128K + ################################################################################ # the SAM3 chips @@ -521,6 +533,13 @@ stm32f7ccm stm32f7 CCM_OFF=0x20000000 stm32g4ccm stm32g4 CCM_OFF=0x10000000 stm32l1eep stm32l1 EEP_OFF=0x08080000 +stm32h7xxxb stm32h7 ROM=128K +stm32h7xxxe stm32h7 ROM=512K +# stm32h72xxxg and stm32h73xxxg +stm32h7xxxg stm32h7 ROM=1M +stm32h74xxg stm32h7 ROM=512K ROM1=512K +stm32h7xxxi stm32h7 ROM=1M ROM1=1M + ################################################################################ # the SAM3 family groups sam3xnfc sam3x NFCRAM=4K NFCRAM_OFF=0x20100000 @@ -554,6 +573,7 @@ stm32l1 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft stm32l4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 RAM2_OFF=0x10000000 RAM3_OFF=0x20040000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 stm32g0 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m0plus FPU=soft stm32g4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 +stm32h7 END ROM_OFF=0x08000000 ROM1_OFF=0x08100000 RAM_OFF=0x24000000 RAM1_OFF=0x30000000 RAM2_OFF=0x30020000 RAM3_OFF=0x30040000 RAM4_OFF=0x38000000 CCM_OFF=0x20000000 CPU=cortex-m7 FPU=hard-fpv5-dp-d16 stm32w END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft stm32t END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft From af3b62cc184cbb8af61fb388147044663d97ea7a Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Fri, 25 Feb 2022 16:01:53 +0100 Subject: [PATCH 130/206] STM32H7: Fix FP spec * fixed: Use correct FP spec for H7 --- ld/devices.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ld/devices.data b/ld/devices.data index 57a3de93..ddc1501d 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -573,7 +573,7 @@ stm32l1 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft stm32l4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 RAM2_OFF=0x10000000 RAM3_OFF=0x20040000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 stm32g0 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m0plus FPU=soft stm32g4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 -stm32h7 END ROM_OFF=0x08000000 ROM1_OFF=0x08100000 RAM_OFF=0x24000000 RAM1_OFF=0x30000000 RAM2_OFF=0x30020000 RAM3_OFF=0x30040000 RAM4_OFF=0x38000000 CCM_OFF=0x20000000 CPU=cortex-m7 FPU=hard-fpv5-dp-d16 +stm32h7 END ROM_OFF=0x08000000 ROM1_OFF=0x08100000 RAM_OFF=0x24000000 RAM1_OFF=0x30000000 RAM2_OFF=0x30020000 RAM3_OFF=0x30040000 RAM4_OFF=0x38000000 CCM_OFF=0x20000000 CPU=cortex-m7 FPU=hard-fpv5-d16 stm32w END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft stm32t END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft From 5c65f0f6532e24801868c6b9d9c1838672e08a19 Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Mon, 28 Feb 2022 15:12:29 +0100 Subject: [PATCH 131/206] STM32H7: Add support for RAM4 & RAM5, cleanup * added: Linker script adds support for RAM4 and RAM5 memory regions, so that those are usable by code. This also fixes the fact that RAM4 was declared, but inaccessible previously * changed: RAM1 is renamed to RAM2, shifting numbering of all regions. This is done in order to be in line with other STM32 definitions, similarly ROM1 became ROM2. --- ld/devices.data | 24 ++++++++++++------------ ld/linker.ld.S | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/ld/devices.data b/ld/devices.data index ddc1501d..2731965d 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -260,16 +260,16 @@ stm32g4?[34]?c* stm32g4ccm ROM=256K RAM=96K CCM=32K stm32g4?[34]?e* stm32g4ccm ROM=512K RAM=96K CCM=32K # For STM32H7 CCM is called D-TCM -stm32h72[35]?e* stm32h7xxxe RAM=128K RAM1=16K RAM2=16K RAM4=16K CCM=128K -stm32h72[35]?g* stm32h7xxxg RAM=128K RAM1=16K RAM2=16K RAM4=16K CCM=128K -stm32h730?b* stm32h7xxxb RAM=128K RAM1=16K RAM2=16K RAM4=16K CCM=128K -stm32h73[35]?g* stm32h7xxxg RAM=128K RAM1=16K RAM2=16K RAM4=16K CCM=128K -stm32h742?i* stm32h7xxxi RAM=384K RAM1=32K RAM2=16K RAM4=64K CCM=128K -stm32h742?g* stm32h74xxg RAM=384K RAM1=32K RAM2=16K RAM4=64K CCM=128K -stm32h74[357]?i* stm32h7xxxi RAM=512K RAM1=128K RAM2=128K RAM3=32K RAM4=64K CCM=128K -stm32h74[357]?g* stm32h74xxg RAM=512K RAM1=128K RAM2=128K RAM3=32K RAM4=64K CCM=128K -stm32h75[357]?i* stm32h7xxxi RAM=512K RAM1=128K RAM2=128K RAM3=32K RAM4=64K CCM=128K -stm32h750?b* stm32h7xxxb RAM=512K RAM1=128K RAM2=128K RAM3=32K RAM4=64K CCM=128K +stm32h72[35]?e* stm32h7xxxe RAM=128K RAM2=16K RAM3=16K RAM5=16K CCM=128K +stm32h72[35]?g* stm32h7xxxg RAM=128K RAM2=16K RAM3=16K RAM5=16K CCM=128K +stm32h730?b* stm32h7xxxb RAM=128K RAM2=16K RAM3=16K RAM5=16K CCM=128K +stm32h73[35]?g* stm32h7xxxg RAM=128K RAM2=16K RAM3=16K RAM5=16K CCM=128K +stm32h742?i* stm32h7xxxi RAM=384K RAM2=32K RAM3=16K RAM5=64K CCM=128K +stm32h742?g* stm32h74xxg RAM=384K RAM2=32K RAM3=16K RAM5=64K CCM=128K +stm32h74[357]?i* stm32h7xxxi RAM=512K RAM2=128K RAM3=128K RAM4=32K RAM5=64K CCM=128K +stm32h74[357]?g* stm32h74xxg RAM=512K RAM2=128K RAM3=128K RAM4=32K RAM5=64K CCM=128K +stm32h75[357]?i* stm32h7xxxi RAM=512K RAM2=128K RAM3=128K RAM4=32K RAM5=64K CCM=128K +stm32h750?b* stm32h7xxxb RAM=512K RAM2=128K RAM3=128K RAM4=32K RAM5=64K CCM=128K ################################################################################ # the SAM3 chips @@ -537,8 +537,8 @@ stm32h7xxxb stm32h7 ROM=128K stm32h7xxxe stm32h7 ROM=512K # stm32h72xxxg and stm32h73xxxg stm32h7xxxg stm32h7 ROM=1M -stm32h74xxg stm32h7 ROM=512K ROM1=512K -stm32h7xxxi stm32h7 ROM=1M ROM1=1M +stm32h74xxg stm32h7 ROM=512K ROM2=512K +stm32h7xxxi stm32h7 ROM=1M ROM2=1M ################################################################################ # the SAM3 family groups diff --git a/ld/linker.ld.S b/ld/linker.ld.S index 20aaf024..8cb0ed87 100644 --- a/ld/linker.ld.S +++ b/ld/linker.ld.S @@ -50,6 +50,12 @@ MEMORY #if defined(_RAM3) ram3 (rwx) : ORIGIN = _RAM3_OFF, LENGTH = _RAM3 #endif +#if defined(_RAM4) + ram4 (rwx) : ORIGIN = _RAM4_OFF, LENGTH = _RAM4 +#endif +#if defined(_RAM5) + ram5 (rwx) : ORIGIN = _RAM5_OFF, LENGTH = _RAM5 +#endif #if defined(_CCM) ccm (rwx) : ORIGIN = _CCM_OFF, LENGTH = _CCM #endif @@ -168,6 +174,20 @@ SECTIONS } >ram3 #endif +#if defined(_RAM4) + .ram4 : { + *(.ram4*) + . = ALIGN(4); + } >ram4 +#endif + +#if defined(_RAM5) + .ram5 : { + *(.ram5*) + . = ALIGN(4); + } >ram4 +#endif + #if defined(_XSRAM) .xsram : { *(.xsram*) From bd4a970de9e25bb81548db5653c8ba382a07c055 Mon Sep 17 00:00:00 2001 From: Marek Koza Date: Sun, 6 Mar 2022 13:46:35 +0100 Subject: [PATCH 132/206] stm32:fdcan: Fix FDCAN_FIFO_XTD bit position --- include/libopencm3/stm32/fdcan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/fdcan.h b/include/libopencm3/stm32/fdcan.h index b724fbd2..76ed9eba 100644 --- a/include/libopencm3/stm32/fdcan.h +++ b/include/libopencm3/stm32/fdcan.h @@ -698,7 +698,7 @@ struct fdcan_tx_buffer_element { * @{ */ #define FDCAN_FIFO_ESI (1 << 31) -#define FDCAN_FIFO_XTD (1 << 20) +#define FDCAN_FIFO_XTD (1 << 30) #define FDCAN_FIFO_RTR (1 << 29) #define FDCAN_FIFO_EFC (1 << 23) #define FDCAN_FIFO_FDF (1 << 21) From 192d7fec2e29f47ef86b2c591dc1db518772045b Mon Sep 17 00:00:00 2001 From: Parth Panchal <47279170+parrthpanchal@users.noreply.github.com> Date: Sun, 13 Feb 2022 23:16:16 +0530 Subject: [PATCH 133/206] stm32f1:gpio: Added missing definitions for usart1 Add missing explicit gpio definitions for remainder of usart1 signals. Fixes: https://github.com/libopencm3/libopencm3/issues/1326 --- include/libopencm3/stm32/f1/gpio.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/libopencm3/stm32/f1/gpio.h b/include/libopencm3/stm32/f1/gpio.h index 4e997e03..040a8ae0 100644 --- a/include/libopencm3/stm32/f1/gpio.h +++ b/include/libopencm3/stm32/f1/gpio.h @@ -397,15 +397,21 @@ LGPL License Terms @ref lgpl_license #define GPIO_BANK_USART2_RE_CK GPIOD /* PD7 */ /* USART1 GPIO */ +#define GPIO_USART1_CTS GPIO11 /* PA11 */ +#define GPIO_USART1_RTS GPIO12 /* PA12 */ #define GPIO_USART1_TX GPIO9 /* PA9 */ #define GPIO_USART1_RX GPIO10 /* PA10 */ +#define GPIO_USART1_CK GPIO8 /* PA8 */ #define GPIO_USART1_RE_TX GPIO6 /* PB6 */ #define GPIO_USART1_RE_RX GPIO7 /* PB7 */ /* USART1 BANK */ +#define GPIO_BANK_USART1_CTS GPIOA /* PA11 */ +#define GPIO_BANK_USART1_RTS GPIOA /* PA12 */ #define GPIO_BANK_USART1_TX GPIOA /* PA9 */ #define GPIO_BANK_USART1_RX GPIOA /* PA10 */ +#define GPIO_BANK_USART1_CK GPIOA /* PA8 */ #define GPIO_BANK_USART1_RE_TX GPIOB /* PB6 */ #define GPIO_BANK_USART1_RE_RX GPIOB /* PB7 */ From b05865a854eebe8b2be9014f854bdd9ca7d4bcce Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Mar 2022 20:33:27 +0000 Subject: [PATCH 134/206] pac55xx: fix stylecheck warning --- include/libopencm3/pac55xx/ccs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/pac55xx/ccs.h b/include/libopencm3/pac55xx/ccs.h index b18f2f1c..5b135da9 100644 --- a/include/libopencm3/pac55xx/ccs.h +++ b/include/libopencm3/pac55xx/ccs.h @@ -42,7 +42,7 @@ /** Ring Oscillator Frequency */ #define CCS_ROSC_FREQ (16000000U) /** Internally generated and trimmed 4MHz clock */ -#define CCS_CLKREF_FREQ ( 4000000U) +#define CCS_CLKREF_FREQ (4000000U) /** Maximum external clock frequency */ #define CCS_EXTCLK_MAX_FREQ (20000000U) /**@}*/ From c08df942d7516643f22577a9203429fa4c342fb9 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Mar 2022 20:40:57 +0000 Subject: [PATCH 135/206] msp432: replace spaces with tabs: stylecheck --- include/libopencm3/msp432/e4/systemcontrol.h | 152 +++++++++---------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/include/libopencm3/msp432/e4/systemcontrol.h b/include/libopencm3/msp432/e4/systemcontrol.h index 628c6c24..d5622f35 100644 --- a/include/libopencm3/msp432/e4/systemcontrol.h +++ b/include/libopencm3/msp432/e4/systemcontrol.h @@ -1324,9 +1324,9 @@ * @li CLOCK_DEEP_SLEEP - Deep-Sleep Mode */ enum msp432_clock_mode { - CLOCK_RUN = 0x600, - CLOCK_SLEEP = 0x700, - CLOCK_DEEP_SLEEP = 0x800 + CLOCK_RUN = 0x600, + CLOCK_SLEEP = 0x700, + CLOCK_DEEP_SLEEP = 0x800 }; /** @@ -1339,8 +1339,8 @@ enum msp432_clock_mode { * is powered and receives a clock regardless of the value of power mode. */ enum msp432_power_mode { - POWER_DISABLE = false, - POWER_ENABLE = true + POWER_DISABLE = false, + POWER_ENABLE = true }; #define _REG_BIT(base, bit) (((base) << 5) + (bit)) @@ -1354,95 +1354,95 @@ enum msp432_power_mode { */ enum msp432_periph { - PERIPH_WD0 = _REG_BIT(0x00, 0), - PERIPH_WD1, + PERIPH_WD0 = _REG_BIT(0x00, 0), + PERIPH_WD1, - PERIPH_TIMER0 = _REG_BIT(0x04, 0), - PERIPH_TIMER1, - PERIPH_TIMER2, - PERIPH_TIMER3, - PERIPH_TIMER4, - PERIPH_TIMER5, - PERIPH_TIMER6, - PERIPH_TIMER7, + PERIPH_TIMER0 = _REG_BIT(0x04, 0), + PERIPH_TIMER1, + PERIPH_TIMER2, + PERIPH_TIMER3, + PERIPH_TIMER4, + PERIPH_TIMER5, + PERIPH_TIMER6, + PERIPH_TIMER7, - PERIPH_GPIOA = _REG_BIT(0x08, 0), - PERIPH_GPIOB, - PERIPH_GPIOC, - PERIPH_GPIOD, - PERIPH_GPIOE, - PERIPH_GPIOF, - PERIPH_GPIOG, - PERIPH_GPIOH, - PERIPH_GPIOJ, - PERIPH_GPIOK, - PERIPH_GPIOL, - PERIPH_GPIOM, - PERIPH_GPION, - PERIPH_GPIOP, - PERIPH_GPIOQ, - PERIPH_GPIOR, - PERIPH_GPIOS, - PERIPH_GPIOT, + PERIPH_GPIOA = _REG_BIT(0x08, 0), + PERIPH_GPIOB, + PERIPH_GPIOC, + PERIPH_GPIOD, + PERIPH_GPIOE, + PERIPH_GPIOF, + PERIPH_GPIOG, + PERIPH_GPIOH, + PERIPH_GPIOJ, + PERIPH_GPIOK, + PERIPH_GPIOL, + PERIPH_GPIOM, + PERIPH_GPION, + PERIPH_GPIOP, + PERIPH_GPIOQ, + PERIPH_GPIOR, + PERIPH_GPIOS, + PERIPH_GPIOT, - PERIPH_DMA = _REG_BIT(0x0C, 0), + PERIPH_DMA = _REG_BIT(0x0C, 0), - PERIPH_EPI = _REG_BIT(0x10, 0), + PERIPH_EPI = _REG_BIT(0x10, 0), - PERIPH_HIB = _REG_BIT(0x14, 0), + PERIPH_HIB = _REG_BIT(0x14, 0), - PERIPH_UART0 = _REG_BIT(0x18, 0), - PERIPH_UART1, - PERIPH_UART2, - PERIPH_UART3, - PERIPH_UART4, - PERIPH_UART5, - PERIPH_UART6, - PERIPH_UART7, + PERIPH_UART0 = _REG_BIT(0x18, 0), + PERIPH_UART1, + PERIPH_UART2, + PERIPH_UART3, + PERIPH_UART4, + PERIPH_UART5, + PERIPH_UART6, + PERIPH_UART7, - PERIPH_SSI0 = _REG_BIT(0x1C, 0), - PERIPH_SSI1, - PERIPH_SSI2, - PERIPH_SSI3, + PERIPH_SSI0 = _REG_BIT(0x1C, 0), + PERIPH_SSI1, + PERIPH_SSI2, + PERIPH_SSI3, - PERIPH_I2C0 = _REG_BIT(0x20, 0), - PERIPH_I2C1, - PERIPH_I2C2, - PERIPH_I2C3, - PERIPH_I2C4, - PERIPH_I2C5, - PERIPH_I2C6, - PERIPH_I2C7, - PERIPH_I2C8, - PERIPH_I2C9, + PERIPH_I2C0 = _REG_BIT(0x20, 0), + PERIPH_I2C1, + PERIPH_I2C2, + PERIPH_I2C3, + PERIPH_I2C4, + PERIPH_I2C5, + PERIPH_I2C6, + PERIPH_I2C7, + PERIPH_I2C8, + PERIPH_I2C9, - PERIPH_USB0 = _REG_BIT(0x28, 0), + PERIPH_USB0 = _REG_BIT(0x28, 0), - PERIPH_EPHY = _REG_BIT(0x30, 0), + PERIPH_EPHY = _REG_BIT(0x30, 0), - PERIPH_CAN0 = _REG_BIT(0x34, 0), - PERIPH_CAN1, + PERIPH_CAN0 = _REG_BIT(0x34, 0), + PERIPH_CAN1, - PERIPH_ADC0 = _REG_BIT(0x38, 0), - PERIPH_ADC1, + PERIPH_ADC0 = _REG_BIT(0x38, 0), + PERIPH_ADC1, - PERIPH_ACMP = _REG_BIT(0x3C, 0), + PERIPH_ACMP = _REG_BIT(0x3C, 0), - PERIPH_PWM = _REG_BIT(0x40, 0), + PERIPH_PWM = _REG_BIT(0x40, 0), - PERIPH_QEI = _REG_BIT(0x44, 0), + PERIPH_QEI = _REG_BIT(0x44, 0), - PERIPH_EEPROM = _REG_BIT(0x58, 0), + PERIPH_EEPROM = _REG_BIT(0x58, 0), - PERIPH_CCM = _REG_BIT(0x74, 0), + PERIPH_CCM = _REG_BIT(0x74, 0), - PERIPH_LCD = _REG_BIT(0x90, 0), + PERIPH_LCD = _REG_BIT(0x90, 0), - PERIPH_OWIRE = _REG_BIT(0x98, 0), + PERIPH_OWIRE = _REG_BIT(0x98, 0), - PERIPH_EMAC = _REG_BIT(0x9C, 0), + PERIPH_EMAC = _REG_BIT(0x9C, 0), - PERIPH_PRB = _REG_BIT(0xA0, 0) + PERIPH_PRB = _REG_BIT(0xA0, 0) }; #undef _REG_BIT @@ -1452,9 +1452,9 @@ enum msp432_periph { BEGIN_DECLS void sysctl_periph_clock_enable(enum msp432_clock_mode clock_mode, - enum msp432_periph periph); + enum msp432_periph periph); void sysctl_periph_clock_disable(enum msp432_clock_mode clock_mode, - enum msp432_periph periph); + enum msp432_periph periph); void sysctl_periph_reset(enum msp432_periph periph); void sysctl_periph_clear_reset(enum msp432_periph periph); @@ -1462,7 +1462,7 @@ void sysctl_periph_clear_reset(enum msp432_periph periph); bool sysctl_periph_is_present(enum msp432_periph periph); bool sysctl_periph_is_ready(enum msp432_periph periph); void sysctl_periph_set_power_state(enum msp432_power_mode power_mode, - enum msp432_periph periph); + enum msp432_periph periph); END_DECLS From bb31308bc7e2b3aa698b989fcea1fd49e56e1852 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Mar 2022 20:42:07 +0000 Subject: [PATCH 136/206] stm32: hrtim: stylecheck cleanup --- .../stm32/common/hrtim_common_all.h | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/include/libopencm3/stm32/common/hrtim_common_all.h b/include/libopencm3/stm32/common/hrtim_common_all.h index ae4094cc..7ca0b735 100644 --- a/include/libopencm3/stm32/common/hrtim_common_all.h +++ b/include/libopencm3/stm32/common/hrtim_common_all.h @@ -577,16 +577,16 @@ specific memorymap.h header before including this header file.*/ #define HRTIM_BMCR_BMPRSC_SHIFT 6 #define HRTIM_BMCR_BMPRSC_MASK (0xf << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_1 ( 0 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_2 ( 1 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_4 ( 2 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_8 ( 3 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_16 ( 4 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_32 ( 5 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_64 ( 6 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_128 ( 7 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_256 ( 8 << HRTIM_BMCR_BMPRSC_SHIFT) -#define HRTIM_BMCR_BMPRSC_512 ( 9 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_1 (0 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_2 (1 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_4 (2 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_8 (3 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_16 (4 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_32 (5 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_64 (6 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_128 (7 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_256 (8 << HRTIM_BMCR_BMPRSC_SHIFT) +#define HRTIM_BMCR_BMPRSC_512 (9 << HRTIM_BMCR_BMPRSC_SHIFT) #define HRTIM_BMCR_BMPRSC_1024 (10 << HRTIM_BMCR_BMPRSC_SHIFT) #define HRTIM_BMCR_BMPRSC_2048 (11 << HRTIM_BMCR_BMPRSC_SHIFT) #define HRTIM_BMCR_BMPRSC_4096 (12 << HRTIM_BMCR_BMPRSC_SHIFT) @@ -598,16 +598,16 @@ specific memorymap.h header before including this header file.*/ #define HRTIM_BMCR_BMCLK_SHIFT 2 #define HRTIM_BMCR_BMCLK_MASK (0xf << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_MASTER ( 0 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_TIMA ( 1 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_TIMB ( 2 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_TIMC ( 3 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_TIMD ( 4 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_TIME ( 5 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_BMC1 ( 6 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_BMC2 ( 7 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_BMC3 ( 8 << HRTIM_BMCR_BMCLK_SHIFT) -#define HRTIM_BMCR_BMCLK_BMC4 ( 9 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_MASTER (0 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_TIMA (1 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_TIMB (2 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_TIMC (3 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_TIMD (4 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_TIME (5 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_BMC1 (6 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_BMC2 (7 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_BMC3 (8 << HRTIM_BMCR_BMCLK_SHIFT) +#define HRTIM_BMCR_BMCLK_BMC4 (9 << HRTIM_BMCR_BMCLK_SHIFT) #define HRTIM_BMCR_BMCLK_HRTIM (10 << HRTIM_BMCR_BMCLK_SHIFT) /** BMOM: Burst Mode operating mode */ @@ -2104,16 +2104,16 @@ specific memorymap.h header before including this header file.*/ #define HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x) ((x) * 6 - 5) #define HRTIM_TIMx_EEF1_EExFLTR_MASK(x) (0xf << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_NONE(x) ( 0 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_CMP1(x) ( 1 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_CMP2(x) ( 2 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_CMP3(x) ( 3 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_CMP4(x) ( 4 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR1(x) ( 5 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR2(x) ( 6 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR3(x) ( 7 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR4(x) ( 8 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) -#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR5(x) ( 9 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_NONE(x) (0 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_CMP1(x) (1 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_CMP2(x) (2 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_CMP3(x) (3 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_CMP4(x) (4 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR1(x) (5 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR2(x) (6 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR3(x) (7 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR4(x) (8 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) +#define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR5(x) (9 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) #define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR6(x) (10 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) #define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR7(x) (11 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) #define HRTIM_TIMx_EEF1_EExFLTR_TIMFLTR8(x) (12 << HRTIM_TIMx_EEF1_EExFLTR_SHIFT(x)) From c13ad2fce4de89980146dfc2f2b223ddb94092a2 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Mar 2022 20:44:13 +0000 Subject: [PATCH 137/206] stm32g0:adc: stylecheck --- include/libopencm3/stm32/g0/adc.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/libopencm3/stm32/g0/adc.h b/include/libopencm3/stm32/g0/adc.h index e2b65d35..af595931 100644 --- a/include/libopencm3/stm32/g0/adc.h +++ b/include/libopencm3/stm32/g0/adc.h @@ -305,14 +305,14 @@ /** @defgroup adc_api_smptime ADC Sampling Time *@{*/ -#define ADC_SMPTIME_001DOT5 ADC_SMPR_SMPx_001DOT5CYC -#define ADC_SMPTIME_003DOT5 ADC_SMPR_SMPx_003DOT5CYC -#define ADC_SMPTIME_007DOT5 ADC_SMPR_SMPx_007DOT5CYC -#define ADC_SMPTIME_012DOT5 ADC_SMPR_SMPx_012DOT5CYC -#define ADC_SMPTIME_019DOT5 ADC_SMPR_SMPx_019DOT5CYC -#define ADC_SMPTIME_039DOT5 ADC_SMPR_SMPx_039DOT5CYC -#define ADC_SMPTIME_079DOT5 ADC_SMPR_SMPx_079DOT5CYC -#define ADC_SMPTIME_160DOT5 ADC_SMPR_SMPx_160DOT5CYC +#define ADC_SMPTIME_001DOT5 ADC_SMPR_SMPx_001DOT5CYC +#define ADC_SMPTIME_003DOT5 ADC_SMPR_SMPx_003DOT5CYC +#define ADC_SMPTIME_007DOT5 ADC_SMPR_SMPx_007DOT5CYC +#define ADC_SMPTIME_012DOT5 ADC_SMPR_SMPx_012DOT5CYC +#define ADC_SMPTIME_019DOT5 ADC_SMPR_SMPx_019DOT5CYC +#define ADC_SMPTIME_039DOT5 ADC_SMPR_SMPx_039DOT5CYC +#define ADC_SMPTIME_079DOT5 ADC_SMPR_SMPx_079DOT5CYC +#define ADC_SMPTIME_160DOT5 ADC_SMPR_SMPx_160DOT5CYC /**@}*/ /* --- Function prototypes ------------------------------------------------- */ From f92a52bef538f673dbc17731e0031bf299d99a79 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Mar 2022 20:48:21 +0000 Subject: [PATCH 138/206] stm32g0: rcc: fix i2s1 clksel definition Stylecheck uncovered a bad define. --- include/libopencm3/stm32/g0/rcc.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/libopencm3/stm32/g0/rcc.h b/include/libopencm3/stm32/g0/rcc.h index 3c5ad375..40441ee1 100644 --- a/include/libopencm3/stm32/g0/rcc.h +++ b/include/libopencm3/stm32/g0/rcc.h @@ -463,7 +463,7 @@ /** @defgroup rcc_ccipr_rngdiv RNGDIV @{*/ #define RCC_CCIPR_RNGDIV_1 0 -#define RCC_CCIPR_RNGDIV_2 1 +#define RCC_CCIPR_RNGDIV_2 1 #define RCC_CCIPR_RNGDIV_4 2 #define RCC_CCIPR_RNGDIV_8 3 /**@}*/ @@ -473,7 +473,7 @@ /** @defgroup rcc_ccipr_rngsel RNGSEL @{*/ #define RCC_CCIPR_RNGSEL_NONE 0 -#define RCC_CCIPR_RNGSEL_HSI16 1 +#define RCC_CCIPR_RNGSEL_HSI16 1 #define RCC_CCIPR_RNGSEL_SYSCLK 2 #define RCC_CCIPR_RNGSEL_PLLQCLK 3 /**@}*/ @@ -483,7 +483,7 @@ /** @defgroup rcc_ccipr_tim15sel TIM15SEL @{*/ #define RCC_CCIPR_TIM15SEL_TIMPCLK 0 -#define RCC_CCIPR_TIM15SEL_PLLQCLK 1 +#define RCC_CCIPR_TIM15SEL_PLLQCLK 1 /**@}*/ #define RCC_CCIPR_TIM1SEL_MASK 0x1 @@ -491,7 +491,7 @@ /** @defgroup rcc_ccipr_tim1sel TIM1SEL @{*/ #define RCC_CCIPR_TIM1SEL_TIMPCLK 0 -#define RCC_CCIPR_TIM1SEL_PLLQCLK 1 +#define RCC_CCIPR_TIM1SEL_PLLQCLK 1 /**@}*/ #define RCC_CCIPR_LPTIM2SEL_MASK 0x3 @@ -499,8 +499,8 @@ /** @defgroup rcc_ccipr_lptim2sel LPTIM2SEL LPTIM2 Clock source selection @{*/ #define RCC_CCIPR_LPTIM2SEL_PCLK 0 -#define RCC_CCIPR_LPTIM2SEL_LSI 1 -#define RCC_CCIPR_LPTIM2SEL_HSI16 2 +#define RCC_CCIPR_LPTIM2SEL_LSI 1 +#define RCC_CCIPR_LPTIM2SEL_HSI16 2 #define RCC_CCIPR_LPTIM2SEL_LSE 3 /**@}*/ @@ -510,7 +510,7 @@ @{*/ #define RCC_CCIPR_LPTIM1SEL_PCLK 0 #define RCC_CCIPR_LPTIM1SEL_LSI 1 -#define RCC_CCIPR_LPTIM1SEL_HSI16 2 +#define RCC_CCIPR_LPTIM1SEL_HSI16 2 #define RCC_CCIPR_LPTIM1SEL_LSE 3 /**@}*/ @@ -520,8 +520,8 @@ @{*/ #define RCC_CCIPR_I2S1SEL_SYSCLK 0 #define RCC_CCIPR_I2S1SEL_PLLPLCK 1 -#define RCC_CCIPR_I2S1SEL_HSI16 2 -#define RCC_CCIPR_I2S1SEL_I2S_CKIN 2 +#define RCC_CCIPR_I2S1SEL_HSI16 2 +#define RCC_CCIPR_I2S1SEL_I2S_CKIN 3 /**@}*/ #define RCC_CCIPR_I2C1SEL_MASK 0x3 @@ -530,7 +530,7 @@ @{*/ #define RCC_CCIPR_I2C1SEL_PCLK 0 #define RCC_CCIPR_I2C1SEL_SYSCLK 1 -#define RCC_CCIPR_I2C1SEL_HSI16 2 +#define RCC_CCIPR_I2C1SEL_HSI16 2 /**@}*/ #define RCC_CCIPR_LPUART1SEL_MASK 0x3 @@ -539,7 +539,7 @@ @{*/ #define RCC_CCIPR_LPUART1SEL_PCLK 0 #define RCC_CCIPR_LPUART1SEL_SYSCLK 1 -#define RCC_CCIPR_LPUART1SEL_HSI16 2 +#define RCC_CCIPR_LPUART1SEL_HSI16 2 #define RCC_CCIPR_LPUART1SEL_LSE 3 /**@}*/ @@ -548,7 +548,7 @@ /** @defgroup rcc_ccipr_cecsel CECSEL CEC Clock souce selection @{*/ #define RCC_CCIPR_CECSEL_HSI16 0 -#define RCC_CCIPR_CECSEL_LSE 1 +#define RCC_CCIPR_CECSEL_LSE 1 /**@}*/ #define RCC_CCIPR_USART2SEL_MASK 0x3 @@ -556,8 +556,8 @@ /** @defgroup rcc_ccipr_usart2sel USART2SEL USART2 Clock source selection @{*/ #define RCC_CCIPR_USART2SEL_PCLK 0 -#define RCC_CCIPR_USART2SEL_SYSCLK 1 -#define RCC_CCIPR_USART2SEL_HSI16 2 +#define RCC_CCIPR_USART2SEL_SYSCLK 1 +#define RCC_CCIPR_USART2SEL_HSI16 2 #define RCC_CCIPR_USART2SEL_LSE 3 /**@}*/ @@ -567,7 +567,7 @@ @{*/ #define RCC_CCIPR_USART1SEL_PCLK 0 #define RCC_CCIPR_USART1SEL_SYSCLK 1 -#define RCC_CCIPR_USART1SEL_HSI16 2 +#define RCC_CCIPR_USART1SEL_HSI16 2 #define RCC_CCIPR_USART1SEL_LSE 3 /**@}*/ /**@}*/ From bef7df02b006b5967d9b08d2365f66526498f801 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Mar 2022 20:50:55 +0000 Subject: [PATCH 139/206] stm32h7: rcc: stylecheck fixes --- include/libopencm3/stm32/h7/rcc.h | 478 +++++++++++++++--------------- 1 file changed, 239 insertions(+), 239 deletions(-) diff --git a/include/libopencm3/stm32/h7/rcc.h b/include/libopencm3/stm32/h7/rcc.h index e9ca5be2..7915ebce 100644 --- a/include/libopencm3/stm32/h7/rcc.h +++ b/include/libopencm3/stm32/h7/rcc.h @@ -423,276 +423,276 @@ LGPL License Terms @ref lgpl_license /** Enumerations for core system/bus clocks for user/driver/system access to base bus clocks * not directly associated with a peripheral. */ enum rcc_clock_source { - RCC_CPUCLK, - RCC_SYSCLK, - RCC_PERCLK, - RCC_SYSTICKCLK, - RCC_HCLK3, - RCC_AHBCLK, /* AHB1,2,4 all share base HCLK. */ - RCC_APB1CLK, /* Note: APB1 and PCLK1 in manual */ - RCC_APB2CLK, /* Note: APB2 and PCLK2 in manual */ - RCC_APB3CLK, /* Note: APB3 and PCLK3 in manual */ - RCC_APB4CLK, /* Note: APB4 and PCLK4 in manual */ + RCC_CPUCLK, + RCC_SYSCLK, + RCC_PERCLK, + RCC_SYSTICKCLK, + RCC_HCLK3, + RCC_AHBCLK, /* AHB1,2,4 all share base HCLK. */ + RCC_APB1CLK, /* Note: APB1 and PCLK1 in manual */ + RCC_APB2CLK, /* Note: APB2 and PCLK2 in manual */ + RCC_APB3CLK, /* Note: APB3 and PCLK3 in manual */ + RCC_APB4CLK, /* Note: APB4 and PCLK4 in manual */ }; enum rcc_osc { - RCC_PLL, - RCC_HSE, - RCC_HSI, - RCC_LSE, - RCC_LSI + RCC_PLL, + RCC_HSE, + RCC_HSI, + RCC_LSE, + RCC_LSI }; /** PLL Configuration structure. */ struct rcc_pll_config { - enum rcc_osc sysclock_source; /**< SYSCLK source input selection. */ - uint8_t pll_source; /**< RCC_PLLCKSELR_PLLSRC_xxx value. */ - uint32_t hse_frequency; /**< User specified HSE frequency, 0 if none. */ - struct pll_config { - uint8_t divm; /**< Pre-divider value for each PLL. 0-64 integers. */ - uint16_t divn; /**< Multiplier, 0-512 integer. */ - uint8_t divp; /**< Post divider for PLLP clock. */ - uint8_t divq; /**< Post divider for PLLQ clock. */ - uint8_t divr; /**< Post divider for PLLR clock. */ - } pll1, pll2, pll3; /**< PLL1-PLL3 configurations. */ - uint8_t core_pre; /**< Core prescaler note: domain 1. */ - uint8_t hpre; /**< HCLK3 prescaler note: domain 1. */ - uint8_t ppre1; /**< APB1 Peripheral prescaler note: domain 2. */ - uint8_t ppre2; /**< APB2 Peripheral prescaler note: domain 2. */ - uint8_t ppre3; /**< APB3 Peripheral prescaler note: domain 1. */ - uint8_t ppre4; /**< APB4 Peripheral prescaler note: domain 3. */ - uint8_t flash_waitstates; /**< Latency Value to set for flahs. */ - enum pwr_vos_scale voltage_scale; /**< LDO/SMPS Voltage scale used for this frequency. */ - enum pwr_sys_mode power_mode; /**< LDO/SMPS configuration for device. */ - uint8_t smps_level; /**< If using SMPS, voltage level to set. */ + enum rcc_osc sysclock_source; /**< SYSCLK source input selection. */ + uint8_t pll_source; /**< RCC_PLLCKSELR_PLLSRC_xxx value. */ + uint32_t hse_frequency; /**< User specified HSE frequency, 0 if none. */ + struct pll_config { + uint8_t divm; /**< Pre-divider value for each PLL. 0-64 integers. */ + uint16_t divn; /**< Multiplier, 0-512 integer. */ + uint8_t divp; /**< Post divider for PLLP clock. */ + uint8_t divq; /**< Post divider for PLLQ clock. */ + uint8_t divr; /**< Post divider for PLLR clock. */ + } pll1, pll2, pll3; /**< PLL1-PLL3 configurations. */ + uint8_t core_pre; /**< Core prescaler note: domain 1. */ + uint8_t hpre; /**< HCLK3 prescaler note: domain 1. */ + uint8_t ppre1; /**< APB1 Peripheral prescaler note: domain 2. */ + uint8_t ppre2; /**< APB2 Peripheral prescaler note: domain 2. */ + uint8_t ppre3; /**< APB3 Peripheral prescaler note: domain 1. */ + uint8_t ppre4; /**< APB4 Peripheral prescaler note: domain 3. */ + uint8_t flash_waitstates; /**< Latency Value to set for flahs. */ + enum pwr_vos_scale voltage_scale; /**< LDO/SMPS Voltage scale used for this frequency. */ + enum pwr_sys_mode power_mode; /**< LDO/SMPS configuration for device. */ + uint8_t smps_level; /**< If using SMPS, voltage level to set. */ }; #define _REG_BIT(base, bit) (((base) << 5) + (bit)) enum rcc_periph_clken { - /* AHB1 peripherals */ - RCC_DMA1 = _REG_BIT(0xD8, 0), - RCC_DMA2 = _REG_BIT(0xD8, 1), - RCC_ADC12 = _REG_BIT(0xD8, 5), - RCC_ETH1MAC = _REG_BIT(0xD8, 15), - RCC_ETH1TX = _REG_BIT(0xD8, 16), - RCC_ETH1RX = _REG_BIT(0xD8, 17), - RCC_USB2OTGHSULPIEN = _REG_BIT(0xD8, 18), - RCC_USB1OTGHSEN = _REG_BIT(0xD8, 25), - RCC_USB1OTGHSULPIEN = _REG_BIT(0xD8, 26), - RCC_USB2OTGHSEN = _REG_BIT(0xD8, 27), + /* AHB1 peripherals */ + RCC_DMA1 = _REG_BIT(0xD8, 0), + RCC_DMA2 = _REG_BIT(0xD8, 1), + RCC_ADC12 = _REG_BIT(0xD8, 5), + RCC_ETH1MAC = _REG_BIT(0xD8, 15), + RCC_ETH1TX = _REG_BIT(0xD8, 16), + RCC_ETH1RX = _REG_BIT(0xD8, 17), + RCC_USB2OTGHSULPIEN = _REG_BIT(0xD8, 18), + RCC_USB1OTGHSEN = _REG_BIT(0xD8, 25), + RCC_USB1OTGHSULPIEN = _REG_BIT(0xD8, 26), + RCC_USB2OTGHSEN = _REG_BIT(0xD8, 27), - /* AHB2 peripherals */ - RCC_DCMI = _REG_BIT(0xDC, 0), - RCC_CRYP = _REG_BIT(0xDC, 4), - RCC_HASH = _REG_BIT(0xDC, 5), - RCC_RNG = _REG_BIT(0xDC, 6), - RCC_SDMMC2 = _REG_BIT(0xDC, 9), - RCC_SRAM1 = _REG_BIT(0xDC, 29), - RCC_SRAM2 = _REG_BIT(0xDC, 30), - RCC_SRAM3 = _REG_BIT(0xDC, 31), + /* AHB2 peripherals */ + RCC_DCMI = _REG_BIT(0xDC, 0), + RCC_CRYP = _REG_BIT(0xDC, 4), + RCC_HASH = _REG_BIT(0xDC, 5), + RCC_RNG = _REG_BIT(0xDC, 6), + RCC_SDMMC2 = _REG_BIT(0xDC, 9), + RCC_SRAM1 = _REG_BIT(0xDC, 29), + RCC_SRAM2 = _REG_BIT(0xDC, 30), + RCC_SRAM3 = _REG_BIT(0xDC, 31), - /* AHB3 peripherals */ - RCC_MDMA = _REG_BIT(0xD4, 0), - RCC_DMA2D = _REG_BIT(0xD4, 4), - RCC_JPGDEC = _REG_BIT(0xD4, 5), - RCC_FMC = _REG_BIT(0xD4, 12), - RCC_QSPI = _REG_BIT(0xD4, 14), - RCC_SDMMC1 = _REG_BIT(0xD4, 16), + /* AHB3 peripherals */ + RCC_MDMA = _REG_BIT(0xD4, 0), + RCC_DMA2D = _REG_BIT(0xD4, 4), + RCC_JPGDEC = _REG_BIT(0xD4, 5), + RCC_FMC = _REG_BIT(0xD4, 12), + RCC_QSPI = _REG_BIT(0xD4, 14), + RCC_SDMMC1 = _REG_BIT(0xD4, 16), - /* AHB4 peripherals*/ - RCC_GPIOA = _REG_BIT(0xE0, 0), - RCC_GPIOB = _REG_BIT(0xE0, 1), - RCC_GPIOC = _REG_BIT(0xE0, 2), - RCC_GPIOD = _REG_BIT(0xE0, 3), - RCC_GPIOE = _REG_BIT(0xE0, 4), - RCC_GPIOF = _REG_BIT(0xE0, 5), - RCC_GPIOG = _REG_BIT(0xE0, 6), - RCC_GPIOH = _REG_BIT(0xE0, 7), - RCC_GPIOI = _REG_BIT(0xE0, 8), - RCC_GPIOJ = _REG_BIT(0xE0, 9), - RCC_GPIOK = _REG_BIT(0xE0, 10), - RCC_CRC = _REG_BIT(0xE0, 19), - RCC_BDMA = _REG_BIT(0xE0, 21), - RCC_ADC3 = _REG_BIT(0xE0, 24), - RCC_HSEM = _REG_BIT(0xE0, 25), - RCC_BKPSRAM = _REG_BIT(0xE0, 28), + /* AHB4 peripherals*/ + RCC_GPIOA = _REG_BIT(0xE0, 0), + RCC_GPIOB = _REG_BIT(0xE0, 1), + RCC_GPIOC = _REG_BIT(0xE0, 2), + RCC_GPIOD = _REG_BIT(0xE0, 3), + RCC_GPIOE = _REG_BIT(0xE0, 4), + RCC_GPIOF = _REG_BIT(0xE0, 5), + RCC_GPIOG = _REG_BIT(0xE0, 6), + RCC_GPIOH = _REG_BIT(0xE0, 7), + RCC_GPIOI = _REG_BIT(0xE0, 8), + RCC_GPIOJ = _REG_BIT(0xE0, 9), + RCC_GPIOK = _REG_BIT(0xE0, 10), + RCC_CRC = _REG_BIT(0xE0, 19), + RCC_BDMA = _REG_BIT(0xE0, 21), + RCC_ADC3 = _REG_BIT(0xE0, 24), + RCC_HSEM = _REG_BIT(0xE0, 25), + RCC_BKPSRAM = _REG_BIT(0xE0, 28), - /* APB1L peripherals*/ - RCC_TIM2 = _REG_BIT(0xE8, 0), - RCC_TIM3 = _REG_BIT(0xE8, 1), - RCC_TIM4 = _REG_BIT(0xE8, 2), - RCC_TIM5 = _REG_BIT(0xE8, 3), - RCC_TIM6 = _REG_BIT(0xE8, 4), - RCC_TIM7 = _REG_BIT(0xE8, 5), - RCC_TIM12 = _REG_BIT(0xE8, 6), - RCC_TIM13 = _REG_BIT(0xE8, 7), - RCC_TIM14 = _REG_BIT(0xE8, 8), - RCC_LPTIM1 = _REG_BIT(0xE8, 9), - RCC_SPI2 = _REG_BIT(0xE8, 14), - RCC_SPI3 = _REG_BIT(0xE8, 15), - RCC_SPDIFRX = _REG_BIT(0xE8, 16), - RCC_USART2 = _REG_BIT(0xE8, 17), - RCC_USART3 = _REG_BIT(0xE8, 18), - RCC_UART4 = _REG_BIT(0xE8, 19), - RCC_UART5 = _REG_BIT(0xE8, 20), - RCC_I2C1 = _REG_BIT(0xE8, 21), - RCC_I2C2 = _REG_BIT(0xE8, 22), - RCC_I2C3 = _REG_BIT(0xE8, 23), - RCC_CEC = _REG_BIT(0xE8, 27), - RCC_DAC = _REG_BIT(0xE8, 29), - RCC_UART7 = _REG_BIT(0xE8, 30), - RCC_UART8 = _REG_BIT(0xE8, 31), + /* APB1L peripherals*/ + RCC_TIM2 = _REG_BIT(0xE8, 0), + RCC_TIM3 = _REG_BIT(0xE8, 1), + RCC_TIM4 = _REG_BIT(0xE8, 2), + RCC_TIM5 = _REG_BIT(0xE8, 3), + RCC_TIM6 = _REG_BIT(0xE8, 4), + RCC_TIM7 = _REG_BIT(0xE8, 5), + RCC_TIM12 = _REG_BIT(0xE8, 6), + RCC_TIM13 = _REG_BIT(0xE8, 7), + RCC_TIM14 = _REG_BIT(0xE8, 8), + RCC_LPTIM1 = _REG_BIT(0xE8, 9), + RCC_SPI2 = _REG_BIT(0xE8, 14), + RCC_SPI3 = _REG_BIT(0xE8, 15), + RCC_SPDIFRX = _REG_BIT(0xE8, 16), + RCC_USART2 = _REG_BIT(0xE8, 17), + RCC_USART3 = _REG_BIT(0xE8, 18), + RCC_UART4 = _REG_BIT(0xE8, 19), + RCC_UART5 = _REG_BIT(0xE8, 20), + RCC_I2C1 = _REG_BIT(0xE8, 21), + RCC_I2C2 = _REG_BIT(0xE8, 22), + RCC_I2C3 = _REG_BIT(0xE8, 23), + RCC_CEC = _REG_BIT(0xE8, 27), + RCC_DAC = _REG_BIT(0xE8, 29), + RCC_UART7 = _REG_BIT(0xE8, 30), + RCC_UART8 = _REG_BIT(0xE8, 31), - /* APB1H peripherals*/ - RCC_CRS = _REG_BIT(0xEC, 1), - RCC_SWP = _REG_BIT(0xEC, 2), - RCC_OPAMP = _REG_BIT(0xEC, 4), - RCC_MDIO = _REG_BIT(0xEC, 5), - RCC_FDCAN = _REG_BIT(0xEC, 8), + /* APB1H peripherals*/ + RCC_CRS = _REG_BIT(0xEC, 1), + RCC_SWP = _REG_BIT(0xEC, 2), + RCC_OPAMP = _REG_BIT(0xEC, 4), + RCC_MDIO = _REG_BIT(0xEC, 5), + RCC_FDCAN = _REG_BIT(0xEC, 8), - /* APB2 peripherals */ - RCC_TIM1 = _REG_BIT(0xF0, 0), - RCC_TIM8 = _REG_BIT(0xF0, 1), - RCC_USART1 = _REG_BIT(0xF0, 4), - RCC_USART6 = _REG_BIT(0xF0, 5), - RCC_SPI1 = _REG_BIT(0xF0, 12), - RCC_SPI4 = _REG_BIT(0xF0, 13), - RCC_TIM15 = _REG_BIT(0xF0, 16), - RCC_TIM16 = _REG_BIT(0xF0, 17), - RCC_TIM17 = _REG_BIT(0xF0, 18), - RCC_SPI5 = _REG_BIT(0xF0, 20), - RCC_SAI1 = _REG_BIT(0xF0, 22), - RCC_SAI2 = _REG_BIT(0xF0, 23), - RCC_SAI3 = _REG_BIT(0xF0, 24), - RCC_DFSDM = _REG_BIT(0xF0, 28), - RCC_HRTIM = _REG_BIT(0xF0, 29), + /* APB2 peripherals */ + RCC_TIM1 = _REG_BIT(0xF0, 0), + RCC_TIM8 = _REG_BIT(0xF0, 1), + RCC_USART1 = _REG_BIT(0xF0, 4), + RCC_USART6 = _REG_BIT(0xF0, 5), + RCC_SPI1 = _REG_BIT(0xF0, 12), + RCC_SPI4 = _REG_BIT(0xF0, 13), + RCC_TIM15 = _REG_BIT(0xF0, 16), + RCC_TIM16 = _REG_BIT(0xF0, 17), + RCC_TIM17 = _REG_BIT(0xF0, 18), + RCC_SPI5 = _REG_BIT(0xF0, 20), + RCC_SAI1 = _REG_BIT(0xF0, 22), + RCC_SAI2 = _REG_BIT(0xF0, 23), + RCC_SAI3 = _REG_BIT(0xF0, 24), + RCC_DFSDM = _REG_BIT(0xF0, 28), + RCC_HRTIM = _REG_BIT(0xF0, 29), - /* APB3 peripherals */ - RCC_LTDCEN = _REG_BIT(0xE4, 3), - RCC_WWDG1EN = _REG_BIT(0xE4, 6), + /* APB3 peripherals */ + RCC_LTDCEN = _REG_BIT(0xE4, 3), + RCC_WWDG1EN = _REG_BIT(0xE4, 6), - /* APB4 peripherals */ - RCC_SYSCFG = _REG_BIT(0xF4, 1), - RCC_LPUART1 = _REG_BIT(0xF4, 3), - RCC_SPI6 = _REG_BIT(0xF4, 5), - RCC_I2C4 = _REG_BIT(0xF4, 7), - RCC_LPTIM2 = _REG_BIT(0xF4, 9), - RCC_LPTIM3 = _REG_BIT(0xF4, 10), - RCC_LPTIM4 = _REG_BIT(0xF4, 11), - RCC_LPTIM5 = _REG_BIT(0xF4, 12), - RCC_COMP12 = _REG_BIT(0xF4, 14), - RCC_VREF = _REG_BIT(0xF4, 15), - RCC_RTCAPB = _REG_BIT(0xF4, 16), - RCC_SAI4 = _REG_BIT(0xF4, 21), + /* APB4 peripherals */ + RCC_SYSCFG = _REG_BIT(0xF4, 1), + RCC_LPUART1 = _REG_BIT(0xF4, 3), + RCC_SPI6 = _REG_BIT(0xF4, 5), + RCC_I2C4 = _REG_BIT(0xF4, 7), + RCC_LPTIM2 = _REG_BIT(0xF4, 9), + RCC_LPTIM3 = _REG_BIT(0xF4, 10), + RCC_LPTIM4 = _REG_BIT(0xF4, 11), + RCC_LPTIM5 = _REG_BIT(0xF4, 12), + RCC_COMP12 = _REG_BIT(0xF4, 14), + RCC_VREF = _REG_BIT(0xF4, 15), + RCC_RTCAPB = _REG_BIT(0xF4, 16), + RCC_SAI4 = _REG_BIT(0xF4, 21), }; enum rcc_periph_rst { - /* AHB1 peripherals */ - RST_DMA1 = _REG_BIT(0x80, 0), - RST_DMA2 = _REG_BIT(0x80, 1), - RST_ADC12 = _REG_BIT(0x80, 5), - RST_ETH1MAC = _REG_BIT(0x80, 15), - RST_USB1OTGRST = _REG_BIT(0x80, 25), - RST_USB2OTGRST = _REG_BIT(0x80, 27), + /* AHB1 peripherals */ + RST_DMA1 = _REG_BIT(0x80, 0), + RST_DMA2 = _REG_BIT(0x80, 1), + RST_ADC12 = _REG_BIT(0x80, 5), + RST_ETH1MAC = _REG_BIT(0x80, 15), + RST_USB1OTGRST = _REG_BIT(0x80, 25), + RST_USB2OTGRST = _REG_BIT(0x80, 27), - /* AHB2 peripherals */ - RST_DCMI = _REG_BIT(0xDC, 0), - RST_CRYP = _REG_BIT(0xDC, 4), - RST_HASH = _REG_BIT(0xDC, 5), - RST_RNG = _REG_BIT(0xDC, 6), - RST_SDMMC2 = _REG_BIT(0xDC, 9), + /* AHB2 peripherals */ + RST_DCMI = _REG_BIT(0xDC, 0), + RST_CRYP = _REG_BIT(0xDC, 4), + RST_HASH = _REG_BIT(0xDC, 5), + RST_RNG = _REG_BIT(0xDC, 6), + RST_SDMMC2 = _REG_BIT(0xDC, 9), - /* AHB3 peripherals */ - RST_MDMA = _REG_BIT(0x7C, 0), - RST_DMA2D = _REG_BIT(0x7C, 4), - RST_JPGDEC = _REG_BIT(0x7C, 5), - RST_FMC = _REG_BIT(0x7C, 12), - RST_QSPI = _REG_BIT(0x7C, 14), - RST_SDMMC1 = _REG_BIT(0x7C, 16), + /* AHB3 peripherals */ + RST_MDMA = _REG_BIT(0x7C, 0), + RST_DMA2D = _REG_BIT(0x7C, 4), + RST_JPGDEC = _REG_BIT(0x7C, 5), + RST_FMC = _REG_BIT(0x7C, 12), + RST_QSPI = _REG_BIT(0x7C, 14), + RST_SDMMC1 = _REG_BIT(0x7C, 16), - /* AHB4 peripherals*/ - RST_GPIOA = _REG_BIT(0x88, 0), - RST_GPIOB = _REG_BIT(0x88, 1), - RST_GPIOC = _REG_BIT(0x88, 2), - RST_GPIOD = _REG_BIT(0x88, 3), - RST_GPIOE = _REG_BIT(0x88, 4), - RST_GPIOF = _REG_BIT(0x88, 5), - RST_GPIOG = _REG_BIT(0x88, 6), - RST_GPIOH = _REG_BIT(0x88, 7), - RST_GPIOI = _REG_BIT(0x88, 8), - RST_GPIOJ = _REG_BIT(0x88, 9), - RST_GPIOK = _REG_BIT(0x88, 10), - RST_CRC = _REG_BIT(0x88, 19), - RST_BDMA = _REG_BIT(0x88, 21), - RST_ADC3 = _REG_BIT(0x88, 24), - RST_HSEM = _REG_BIT(0x88, 25), + /* AHB4 peripherals*/ + RST_GPIOA = _REG_BIT(0x88, 0), + RST_GPIOB = _REG_BIT(0x88, 1), + RST_GPIOC = _REG_BIT(0x88, 2), + RST_GPIOD = _REG_BIT(0x88, 3), + RST_GPIOE = _REG_BIT(0x88, 4), + RST_GPIOF = _REG_BIT(0x88, 5), + RST_GPIOG = _REG_BIT(0x88, 6), + RST_GPIOH = _REG_BIT(0x88, 7), + RST_GPIOI = _REG_BIT(0x88, 8), + RST_GPIOJ = _REG_BIT(0x88, 9), + RST_GPIOK = _REG_BIT(0x88, 10), + RST_CRC = _REG_BIT(0x88, 19), + RST_BDMA = _REG_BIT(0x88, 21), + RST_ADC3 = _REG_BIT(0x88, 24), + RST_HSEM = _REG_BIT(0x88, 25), - /* APB1L peripherals*/ - RST_TIM2 = _REG_BIT(0x90, 0), - RST_TIM3 = _REG_BIT(0x90, 1), - RST_TIM4 = _REG_BIT(0x90, 2), - RST_TIM5 = _REG_BIT(0x90, 3), - RST_TIM6 = _REG_BIT(0x90, 4), - RST_TIM7 = _REG_BIT(0x90, 5), - RST_TIM12 = _REG_BIT(0x90, 6), - RST_TIM13 = _REG_BIT(0x90, 7), - RST_TIM14 = _REG_BIT(0x90, 8), - RST_LPTIM1 = _REG_BIT(0x90, 9), - RST_SPI2 = _REG_BIT(0x90, 14), - RST_SPI3 = _REG_BIT(0x90, 15), - RST_SPDIFRX = _REG_BIT(0x90, 16), - RST_USART2 = _REG_BIT(0x90, 17), - RST_USART3 = _REG_BIT(0x90, 18), - RST_UART4 = _REG_BIT(0x90, 19), - RST_UART5 = _REG_BIT(0x90, 20), - RST_I2C1 = _REG_BIT(0x90, 21), - RST_I2C2 = _REG_BIT(0x90, 22), - RST_I2C3 = _REG_BIT(0x90, 23), - RST_CEC = _REG_BIT(0x90, 27), - RST_DAC = _REG_BIT(0x90, 29), - RST_UART7 = _REG_BIT(0x90, 30), - RST_UART8 = _REG_BIT(0x90, 31), + /* APB1L peripherals*/ + RST_TIM2 = _REG_BIT(0x90, 0), + RST_TIM3 = _REG_BIT(0x90, 1), + RST_TIM4 = _REG_BIT(0x90, 2), + RST_TIM5 = _REG_BIT(0x90, 3), + RST_TIM6 = _REG_BIT(0x90, 4), + RST_TIM7 = _REG_BIT(0x90, 5), + RST_TIM12 = _REG_BIT(0x90, 6), + RST_TIM13 = _REG_BIT(0x90, 7), + RST_TIM14 = _REG_BIT(0x90, 8), + RST_LPTIM1 = _REG_BIT(0x90, 9), + RST_SPI2 = _REG_BIT(0x90, 14), + RST_SPI3 = _REG_BIT(0x90, 15), + RST_SPDIFRX = _REG_BIT(0x90, 16), + RST_USART2 = _REG_BIT(0x90, 17), + RST_USART3 = _REG_BIT(0x90, 18), + RST_UART4 = _REG_BIT(0x90, 19), + RST_UART5 = _REG_BIT(0x90, 20), + RST_I2C1 = _REG_BIT(0x90, 21), + RST_I2C2 = _REG_BIT(0x90, 22), + RST_I2C3 = _REG_BIT(0x90, 23), + RST_CEC = _REG_BIT(0x90, 27), + RST_DAC = _REG_BIT(0x90, 29), + RST_UART7 = _REG_BIT(0x90, 30), + RST_UART8 = _REG_BIT(0x90, 31), - /* APB1H peripherals*/ - RST_CRS = _REG_BIT(0x94, 1), - RST_SWP = _REG_BIT(0x94, 2), - RST_OPAMP = _REG_BIT(0x94, 4), - RST_MDIO = _REG_BIT(0x94, 5), - RST_FDCAN = _REG_BIT(0x94, 8), + /* APB1H peripherals*/ + RST_CRS = _REG_BIT(0x94, 1), + RST_SWP = _REG_BIT(0x94, 2), + RST_OPAMP = _REG_BIT(0x94, 4), + RST_MDIO = _REG_BIT(0x94, 5), + RST_FDCAN = _REG_BIT(0x94, 8), - /* APB2 peripherals */ - RST_TIM1 = _REG_BIT(0x98, 0), - RST_TIM8 = _REG_BIT(0x98, 1), - RST_USART1 = _REG_BIT(0x98, 4), - RST_USART6 = _REG_BIT(0x98, 5), - RST_SPI1 = _REG_BIT(0x98, 12), - RST_SPI4 = _REG_BIT(0x98, 13), - RST_TIM15 = _REG_BIT(0x98, 16), - RST_TIM16 = _REG_BIT(0x98, 17), - RST_TIM17 = _REG_BIT(0x98, 18), - RST_SPI5 = _REG_BIT(0x98, 20), - RST_SAI1 = _REG_BIT(0x98, 22), - RST_SAI2 = _REG_BIT(0x98, 23), - RST_SAI3 = _REG_BIT(0x98, 24), - RST_DFSDM = _REG_BIT(0x98, 28), - RST_HRTIM = _REG_BIT(0x98, 29), + /* APB2 peripherals */ + RST_TIM1 = _REG_BIT(0x98, 0), + RST_TIM8 = _REG_BIT(0x98, 1), + RST_USART1 = _REG_BIT(0x98, 4), + RST_USART6 = _REG_BIT(0x98, 5), + RST_SPI1 = _REG_BIT(0x98, 12), + RST_SPI4 = _REG_BIT(0x98, 13), + RST_TIM15 = _REG_BIT(0x98, 16), + RST_TIM16 = _REG_BIT(0x98, 17), + RST_TIM17 = _REG_BIT(0x98, 18), + RST_SPI5 = _REG_BIT(0x98, 20), + RST_SAI1 = _REG_BIT(0x98, 22), + RST_SAI2 = _REG_BIT(0x98, 23), + RST_SAI3 = _REG_BIT(0x98, 24), + RST_DFSDM = _REG_BIT(0x98, 28), + RST_HRTIM = _REG_BIT(0x98, 29), - /* APB3 peripherals */ - RST_LTDCRST = _REG_BIT(0x8C, 3), + /* APB3 peripherals */ + RST_LTDCRST = _REG_BIT(0x8C, 3), - /* APB4 peripherals */ - RST_SYSCFG = _REG_BIT(0x9C, 1), - RST_LPUART1 = _REG_BIT(0x9C, 3), - RST_SPI6 = _REG_BIT(0x9C, 5), - RST_I2C4 = _REG_BIT(0x9C, 7), - RST_LPTIM2 = _REG_BIT(0x9C, 9), - RST_LPTIM3 = _REG_BIT(0x9C, 10), - RST_LPTIM4 = _REG_BIT(0x9C, 11), - RST_LPTIM5 = _REG_BIT(0x9C, 12), - RST_COMP12 = _REG_BIT(0x9C, 14), - RST_VREF = _REG_BIT(0x9C, 15), - RST_SAI4 = _REG_BIT(0x9C, 21), + /* APB4 peripherals */ + RST_SYSCFG = _REG_BIT(0x9C, 1), + RST_LPUART1 = _REG_BIT(0x9C, 3), + RST_SPI6 = _REG_BIT(0x9C, 5), + RST_I2C4 = _REG_BIT(0x9C, 7), + RST_LPTIM2 = _REG_BIT(0x9C, 9), + RST_LPTIM3 = _REG_BIT(0x9C, 10), + RST_LPTIM4 = _REG_BIT(0x9C, 11), + RST_LPTIM5 = _REG_BIT(0x9C, 12), + RST_COMP12 = _REG_BIT(0x9C, 14), + RST_VREF = _REG_BIT(0x9C, 15), + RST_SAI4 = _REG_BIT(0x9C, 21), }; #undef _REG_BIT From c78007338e13a927c71385b0d647ba5bfb526bd7 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Mar 2022 20:51:46 +0000 Subject: [PATCH 140/206] stm32l: lptimer: stylecheck --- include/libopencm3/stm32/l0/lptimer.h | 2 +- include/libopencm3/stm32/l4/lptimer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/libopencm3/stm32/l0/lptimer.h b/include/libopencm3/stm32/l0/lptimer.h index e6d99d8c..4abaf13a 100644 --- a/include/libopencm3/stm32/l0/lptimer.h +++ b/include/libopencm3/stm32/l0/lptimer.h @@ -1,7 +1,7 @@ /** @defgroup lptimer_defines LPTIM Defines * * @ingroup STM32L0xx_defines - * + * * @brief libopencm3 Defined Constants and Types for the STM32L0xx Low Power Timer * * @version 1.0.0 diff --git a/include/libopencm3/stm32/l4/lptimer.h b/include/libopencm3/stm32/l4/lptimer.h index 1dc78c9d..feb299f7 100644 --- a/include/libopencm3/stm32/l4/lptimer.h +++ b/include/libopencm3/stm32/l4/lptimer.h @@ -1,7 +1,7 @@ /** @defgroup lptimer_defines LPTIM Defines * * @ingroup STM32L4xx_defines - * + * * @brief libopencm3 Defined Constants and Types for the STM32L4xx Low Power Timer * * @version 1.0.0 From 458766398f6d101a6b22da37bc33fd32265d1106 Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Thu, 31 Mar 2022 11:24:59 +0200 Subject: [PATCH 141/206] NRF5x: Enable generation of Doxygen docs Add NRF51 and NRF52 into list of targets Doxygen docs are generated for. Fixes missing documentation. --- doc/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/Makefile b/doc/Makefile index b638775b..399451bb 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -12,6 +12,7 @@ TARGETS ?= stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/f7 stm32/h7 \ efm32/wg efm32/ezr32wg \ lm3s lm4f \ msp432/e4 \ + nrf/51 nrf/52 \ lpc13xx lpc17xx lpc43xx \ sam/3a sam/3n sam/3s sam/3u sam/3x \ sam/d sam/4l \ From 66bf499e1b33751433c85b533a05ba8e4bbac60e Mon Sep 17 00:00:00 2001 From: Eduard Drusa Date: Thu, 31 Mar 2022 11:17:59 +0200 Subject: [PATCH 142/206] NRF5x: I2C EasyDMA support for NRF5x, extended API This commit adds support for NRF52 TWI Master mode and slightly extends existing I2C API. This is a breaking change, while mode selection needs to be done during enabling I2C. There is one additional breaking change done because: 1) Unicore MX API design was PITA for writes 2) It is incompatible with EasyDMA I strongly apologize to all two users who might be affected by this change. --- include/libopencm3/nrf/52/i2c.h | 64 ++++++++++++++++++++ include/libopencm3/nrf/common/i2c.h | 40 +++++++++++- lib/nrf/51/Makefile | 2 +- lib/nrf/52/Makefile | 2 +- lib/nrf/52/i2c.c | 62 +++++++++++++++++++ lib/nrf/common/{i2c.c => i2c_common.c} | 84 ++++++++++++++++---------- 6 files changed, 218 insertions(+), 36 deletions(-) create mode 100644 lib/nrf/52/i2c.c rename lib/nrf/common/{i2c.c => i2c_common.c} (57%) diff --git a/include/libopencm3/nrf/52/i2c.h b/include/libopencm3/nrf/52/i2c.h index 3341c59a..407f30d7 100644 --- a/include/libopencm3/nrf/52/i2c.h +++ b/include/libopencm3/nrf/52/i2c.h @@ -37,4 +37,68 @@ #include #include +/**@{*/ + +#define I2C_EVENT_RXSTARTED(i2c) MMIO32((i2c) + 0x14C) +#define I2C_EVENT_TXSTARTED(i2c) MMIO32((i2c) + 0x150) +#define I2C_EVENT_LASTRX(i2c) MMIO32((i2c) + 0x15C) +#define I2C_EVENT_LASTTX(i2c) MMIO32((i2c) + 0x160) + +#define I2C_RXDPTR(i2c) MMIO32((i2c) + 0x534) +#define I2C_RXDMAXCNT(i2c) MMIO32((i2c) + 0x538) +#define I2C_RXDAMOUNT(i2c) MMIO32((i2c) + 0x53C) +#define I2C_RXDLIST(i2c) MMIO32((i2c) + 0x540) +#define I2C_TXDPTR(i2c) MMIO32((i2c) + 0x544) +#define I2C_TXDMAXCNT(i2c) MMIO32((i2c) + 0x548) +#define I2C_TXDAMOUNT(i2c) MMIO32((i2c) + 0x54C) +#define I2C_TXDLIST(i2c) MMIO32((i2c) + 0x550) + +/** @addtogroup i2c_shorts + * @{ + */ + +/** On start of last byte transmission, activate start of reception task */ +#define I2C_SHORTS_LASTTX_STARTRX (1 << 7) + +/** On start of last byte transmission, activate suspend task */ +#define I2C_SHORTS_LASTTX_SUSPEND (1 << 8) + +/** On start of last byte transmission, activate stop task */ +#define I2C_SHORTS_LASTTX_STOP (1 << 9) + +/** On start of last byte reception, activate start of transmission task */ +#define I2C_SHORTS_LASTRX_STARTTX (1 << 10) + +/** On start of last byte reception, activate stop task */ +#define I2C_SHORTS_LASTRX_STOP (1 << 12) +/** @} */ + +/** @addtogroup i2c_inten I2C interrupt enable flags + * @{ */ + +#define I2C_INTEN_SUSPENDED (1 << 18) +#define I2C_INTEN_RXSTARTED (1 << 19) +#define I2C_INTEN_TXSTARTED (1 << 20) +#define I2C_INTEN_LASTRX (1 << 23) +#define I2C_INTEN_LASTTX (1 << 24) + +/** @} */ + +/** @addtogroup i2c_mode I2C peripheral mode + * @{ + */ + +/** NRF52 I2C Master mode with EasyDMA support */ +#define I2C_MODE_MASTER (6) +/**@}*/ + + +BEGIN_DECLS + +void i2c_set_tx_buffer(uint32_t i2c, const uint8_t * buffer, uint8_t len); +void i2c_set_rx_buffer(uint32_t i2c, uint8_t * buffer, uint8_t len); + +END_DECLS + +/** @} */ diff --git a/include/libopencm3/nrf/common/i2c.h b/include/libopencm3/nrf/common/i2c.h index 26c3c601..ec4ed69a 100644 --- a/include/libopencm3/nrf/common/i2c.h +++ b/include/libopencm3/nrf/common/i2c.h @@ -75,9 +75,16 @@ /* Register Contents */ /** @addtogroup i2c_shorts I2C event -> task shortcuts + * The effect of activated shortcut is, that upon I2C event + * triggering, the hardware will automatically start chosen + * task without intervention of the software. * @{ */ + +/** On byte boundary, activate suspend task. */ #define I2C_SHORTS_BB_SUSPEND (1 << 0) + +/** On byte boundary, activate stop task. */ #define I2C_SHORTS_BB_STOP (1 << 1) /**@}*/ @@ -97,11 +104,37 @@ #define I2C_ERRORSRC_ANACK (1 << 1) #define I2C_ERRORSRC_DNACK (1 << 2) -#define I2C_ENABLE_VALUE (5) +/** @addtogroup i2c_mode I2C peripheral mode + * @{ + */ +/** NRF51 legacy mode. + * On NRF51, this is the only mode available. + * On NRF52, this mode does not support EasyDMA. + */ +#define I2C_MODE_LEGACY (5) +/**@}*/ +/** @addtogroup i2c_freq_const I2C frequency constants + * @{ + */ + +/** 100kHz */ #define I2C_FREQUENCY_100K (0x01980000) +/** 250kHz */ #define I2C_FREQUENCY_250K (0x04000000) +/** 390kHz + * @note: This value is not documented in datasheet. It provides + * ~390kHz clock with correct timing. + */ +#define I2C_FREQUENCY_390K (0x06200000) +/** 400kHz + * @note: According to datasheet, there is HW bug which prevents + * MCU from generating correct timings, therefore it might be + * unusable. Use @ref I2C_FREQUENCY_390K instead, if this affects + * you. + */ #define I2C_FREQUENCY_400K (0x06680000) +/**@}*/ #define I2C_PSEL_OFF (0xffffffff) @@ -109,9 +142,9 @@ BEGIN_DECLS -void i2c_enable(uint32_t i2c); +void i2c_enable(uint32_t i2c, uint32_t mode); void i2c_disable(uint32_t i2c); -void i2c_start_tx(uint32_t i2c, uint8_t data); +void i2c_start_tx(uint32_t i2c); void i2c_start_rx(uint32_t i2c); void i2c_send_stop(uint32_t i2c); void i2c_set_fast_mode(uint32_t i2c); @@ -122,6 +155,7 @@ uint8_t i2c_get_data(uint32_t i2c); void i2c_select_pins(uint32_t i2c, uint32_t scl_pin, uint32_t sda_pin); void i2c_set_address(uint32_t i2c, uint8_t addr); void i2c_resume(uint32_t i2c); +void i2c_set_shorts(uint32_t i2c, uint32_t shorts); END_DECLS diff --git a/lib/nrf/51/Makefile b/lib/nrf/51/Makefile index 9e1688f2..612d5111 100644 --- a/lib/nrf/51/Makefile +++ b/lib/nrf/51/Makefile @@ -37,7 +37,7 @@ ARFLAGS = rcs OBJS += clock_common.o clock.o OBJS += gpio.o -OBJS += i2c.o +OBJS += i2c_common.o OBJS += ppi.o OBJS += rtc.o OBJS += radio_common.o ./radio.o diff --git a/lib/nrf/52/Makefile b/lib/nrf/52/Makefile index a0e4884c..35c2ff3f 100644 --- a/lib/nrf/52/Makefile +++ b/lib/nrf/52/Makefile @@ -37,7 +37,7 @@ ARFLAGS = rcs OBJS += clock_common.o OBJS += gpio.o -OBJS += i2c.o +OBJS += i2c.o i2c_common.o OBJS += ppi.o OBJS += radio_common.o OBJS += rtc.o diff --git a/lib/nrf/52/i2c.c b/lib/nrf/52/i2c.c new file mode 100644 index 00000000..2af32637 --- /dev/null +++ b/lib/nrf/52/i2c.c @@ -0,0 +1,62 @@ +/** @addtogroup i2c_file I2C peripheral API + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2022 Eduard Drusa + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +/**@{*/ + +/** Configure I2C transmit buffer properties + * + * Configures transmit buffer for EasyDMA transaction. This API + * is only available if @ref I2C_MODE_MASTER mode is activated. + * + * Configures linear TX buffer for EasyDMA transmission. + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @param[in] buffer address of buffer start + * @param[in] len length of data in the buffer + */ +void i2c_set_tx_buffer(uint32_t i2c, const uint8_t *buffer, uint8_t len) +{ + I2C_TXDPTR(i2c) = (uint32_t) buffer; + I2C_TXDMAXCNT(i2c) = len; + I2C_TXDLIST(i2c) = 0; +} + +/** Configure I2C receive buffer properties + * + * Configures receive buffer for EasyDMA transaction. This API + * is only available if @ref I2C_MODE_MASTER mode is activated. + * + * Configures linear RX buffer for EasyDMA transmission. + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @param[in] buffer address of buffer start + * @param[in] len length of the buffer + */ +void i2c_set_rx_buffer(uint32_t i2c, uint8_t *buffer, uint8_t len) +{ + I2C_RXDPTR(i2c) = (uint32_t) buffer; + I2C_RXDMAXCNT(i2c) = len; + I2C_RXDLIST(i2c) = 0; +} + + +/** @} */ diff --git a/lib/nrf/common/i2c.c b/lib/nrf/common/i2c_common.c similarity index 57% rename from lib/nrf/common/i2c.c rename to lib/nrf/common/i2c_common.c index 5086bb23..8121774e 100644 --- a/lib/nrf/common/i2c.c +++ b/lib/nrf/common/i2c_common.c @@ -6,6 +6,8 @@ * LGPL License Terms @ref lgpl_license * @author @htmlonly © @endhtmlonly 2016 * Maxim Sloyko + * @author @htmlonly © @endhtmlonly 2021 - 2022 + * Eduard Drusa * */ @@ -35,16 +37,17 @@ /** @brief Enable I2C peripheral * - * @param[in] i2c uint32_t i2c peripheral base + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @param[in] mode i2c @ref i2c_mode */ -void i2c_enable(uint32_t i2c) +void i2c_enable(uint32_t i2c, uint32_t mode) { - I2C_ENABLE(i2c) = I2C_ENABLE_VALUE; + I2C_ENABLE(i2c) = mode; } /** @brief Disable I2C peripheral * - * @param[in] i2c uint32_t i2c peripheral base + * @param[in] i2c i2c peripheral base, see @ref i2c_block */ void i2c_disable(uint32_t i2c) { @@ -53,36 +56,37 @@ void i2c_disable(uint32_t i2c) /** @brief Start I2C transmission. * - * @param[in] i2c uint32_t i2c peripheral base. - * @param[in] data uint8_t the first byte to send. + * Starts STARTTX task, which generates start condition on I2C bus and + * transmits address previously configured by @ref i2c_set_address. + * + * @param[in] i2c i2c peripheral base, see @ref i2c_block. */ -void i2c_start_tx(uint32_t i2c, uint8_t data) +void i2c_start_tx(uint32_t i2c) { - PERIPH_TRIGGER_TASK(I2C_TASK_STARTTX(i2c)); - I2C_TXD(i2c) = data; + I2C_TASK_STARTTX(i2c) = 1; } /** @brief Start I2C reception. * - * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] i2c i2c peripheral base, see @ref i2c_block. */ void i2c_start_rx(uint32_t i2c) { - PERIPH_TRIGGER_TASK(I2C_TASK_STARTRX(i2c)); + I2C_TASK_STARTRX(i2c) = 1; } /** @brief Signal stop on I2C line. * - * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] i2c i2c peripheral base, see @ref i2c_block. */ void i2c_send_stop(uint32_t i2c) { - PERIPH_TRIGGER_TASK(I2C_TASK_STOP(i2c)); + I2C_TASK_STOP(i2c) = 1; } /** @brief Select Fast (400kHz) mode. * - * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] i2c i2c peripheral base, see @ref i2c_block. */ void i2c_set_fast_mode(uint32_t i2c) { @@ -91,7 +95,7 @@ void i2c_set_fast_mode(uint32_t i2c) /** @brief Select Standard (100kHz) mode. * - * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] i2c i2c peripheral base, see @ref i2c_block. */ void i2c_set_standard_mode(uint32_t i2c) { @@ -103,8 +107,8 @@ void i2c_set_standard_mode(uint32_t i2c) * In addition to Standard (100kHz) and Fast (400kHz) modes * this peripheral also supports 250kHz mode. * - * @param[in] i2c uint32_t i2c peripheral base. - * @param[in] freq uint32_t frequency constant. See defines for details + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @param[in] freq frequency constant. See @ref i2c_freq_const for details * and note that this is not actually a frequency in Hz or kHz. */ void i2c_set_frequency(uint32_t i2c, uint32_t freq) @@ -114,8 +118,11 @@ void i2c_set_frequency(uint32_t i2c, uint32_t freq) /** @brief Write Data to TXD register to be sent. * - * @param[in] i2c uint32_t i2c peripheral base. - * @param[in] data uint8_t byte to send next. + * Writes one byte into transmission buffer. This API is only + * available if @ref I2C_MODE_LEGACY is activated. + * + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @param[in] data byte to send next. */ void i2c_send_data(uint32_t i2c, uint8_t data) { @@ -124,8 +131,11 @@ void i2c_send_data(uint32_t i2c, uint8_t data) /** @brief Read Data from RXD register. * - * @param[in] i2c uint32_t i2c peripheral base. - * @returns uint8_t data from RXD register. + * Reads one byte from reception buffer. This API is only + * available if @ref I2C_MODE_LEGACY is activated. + * + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @returns data from RXD register. */ uint8_t i2c_get_data(uint32_t i2c) { @@ -133,15 +143,17 @@ uint8_t i2c_get_data(uint32_t i2c) } /** @brief Select GPIO pins to be used by this peripheral. + * + * Configures GPIO pins assigned to SCL and SDA signals. These pins are only occupied + * by I2C peripheral whenever it is enabled using @ref i2c_enable. It is possible to + * ignore any given signal and not map it to pin by using special value of + * @ref GPIO_UNCONNECTED instead of @ref gpio_pin_id values. * * This needs to be configured when no transaction is in progress. * - * @param[in] i2c i2c peripheral base. - * @param[in] scl_pin SCL pin. Use GPIO defines in @ref gpio_pin_id or GPIO_UNCONNECTED - * if signal shall not be connected to any pin. - * @param[in] sda_pin SDA pin. Use GPIO defines in @ref gpio_pin_id or GPIO_UNCONNECTED - * if signal shall not be connected to any pin. - + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @param[in] scl_pin GPIO pin used for SCL signal + * @param[in] sda_pin GPIO pin used for SDA signal */ void i2c_select_pins(uint32_t i2c, uint32_t scl_pin, uint32_t sda_pin) { @@ -160,8 +172,8 @@ void i2c_select_pins(uint32_t i2c, uint32_t scl_pin, uint32_t sda_pin) /** @brief Set 7bit I2C address of the device you wish to communicate with. * - * @param[in] i2c uint32_t i2c peripheral base. - * @param[in] addr uint8_t device address (7bit). + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @param[in] addr device address (7bit). */ void i2c_set_address(uint32_t i2c, uint8_t addr) { @@ -173,12 +185,22 @@ void i2c_set_address(uint32_t i2c, uint8_t addr) * This function is unusual, but required to implement * i2c exchange with this peripheral. * - * @param[in] i2c uint32_t i2c peripheral base. + * @param[in] i2c i2c peripheral base, see @ref i2c_block */ void i2c_resume(uint32_t i2c) { PERIPH_TRIGGER_TASK(I2C_TASK_RESUME(i2c)); } - +/** Configure event -> task shortcuts + * + * Sets new shortcut configuration bitmask for I2C peripheral. + * + * @param[in] i2c i2c peripheral base, see @ref i2c_block + * @param[in] shorts @ref i2c_shorts activated + */ +void i2c_set_shorts(uint32_t i2c, uint32_t shorts) +{ + I2C_SHORTS(i2c) = shorts; +} /**@}*/ From 20c0cfb6509cc3685448629460444c5270efc7fe Mon Sep 17 00:00:00 2001 From: Stefan Tauner Date: Thu, 7 Apr 2022 02:32:41 +0200 Subject: [PATCH 143/206] ld: fix typo in ram5 definition --- ld/linker.ld.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ld/linker.ld.S b/ld/linker.ld.S index 8cb0ed87..d4943703 100644 --- a/ld/linker.ld.S +++ b/ld/linker.ld.S @@ -185,7 +185,7 @@ SECTIONS .ram5 : { *(.ram5*) . = ALIGN(4); - } >ram4 + } >ram5 #endif #if defined(_XSRAM) From 778318c307cdcde09ff2400f62bc293ddc2e8834 Mon Sep 17 00:00:00 2001 From: Stefan Tauner Date: Thu, 7 Apr 2022 02:33:50 +0200 Subject: [PATCH 144/206] ld: add symbols for starts and ends of all regions This makes the boundaries accessible from within the code, e.g., to set up the MPU. --- ld/linker.ld.S | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ld/linker.ld.S b/ld/linker.ld.S index d4943703..40aefb92 100644 --- a/ld/linker.ld.S +++ b/ld/linker.ld.S @@ -148,64 +148,82 @@ SECTIONS #if defined(_CCM) .ccm : { + _ccm = .; *(.ccmram*) . = ALIGN(4); + _eccm = .; } >ccm #endif #if defined(_RAM1) .ram1 : { + _ram1 = .; *(.ram1*) . = ALIGN(4); + _eram1 = .; } >ram1 #endif #if defined(_RAM2) .ram2 : { + _ram2 = .; *(.ram2*) . = ALIGN(4); + _eram2 = .; } >ram2 #endif #if defined(_RAM3) .ram3 : { + _ram3 = .; *(.ram3*) . = ALIGN(4); + _eram3 = .; } >ram3 #endif #if defined(_RAM4) .ram4 : { + _ram4 = .; *(.ram4*) . = ALIGN(4); + _eram4 = .; } >ram4 #endif #if defined(_RAM5) .ram5 : { + _ram5 = .; *(.ram5*) . = ALIGN(4); + _eram5 = .; } >ram5 #endif #if defined(_XSRAM) .xsram : { + _xsram = .; *(.xsram*) . = ALIGN(4); + _exsram = .; } >xsram #endif #if defined(_XDRAM) .xdram : { + _xdram = .; *(.xdram*) . = ALIGN(4); + _exdram = .; } >xdram #endif #if defined(_NFCRAM) .nfcram : { + _nfcram = .; *(.nfcram*) . = ALIGN(4); + _enfcram = .; } >nfcram #endif From 93e0ccaf26c045f004dbe5a636b7d2262b25d2d4 Mon Sep 17 00:00:00 2001 From: Stefan Tauner Date: Sun, 27 Feb 2022 07:53:28 +0100 Subject: [PATCH 145/206] devices.data: add TI Cortex M4 chips except MSP432 Based on the following chip selection guides: - https://www.ti.com/lit/spmt285 (TM4C) - https://www.ti.com/lit/spmt273 (LM4F) --- ld/devices.data | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ld/devices.data b/ld/devices.data index 2731965d..db2e63c0 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -481,8 +481,24 @@ lm3s3748 lm3fury ROM=128K RAM=64K lm3s6965 lm3fury ROM=256K RAM=64K lm3s8962 lm3fury ROM=256K RAM=64K +################################################################################ +# TI cortex M4 chips + +lm4f???b2* lm4f ROM=32K RAM=12K +lm4f???c4* lm4f ROM=64K RAM=24K +lm4f???e5* lm4f ROM=128K RAM=32K +lm4f???h5* lm4f ROM=256K RAM=32K + +# (Wrong) legacy definition for EK-LM4F120XL board with an LM4F120H5QR lm4f120xl lm4f ROM=128K RAM=32K +tm4c123?c3* tm4c123x ROM=32K RAM=12K +tm4c123?d5* tm4c123x ROM=64K RAM=24K +tm4c123?e6* tm4c123x ROM=128K RAM=32K +tm4c123?h6* tm4c123x ROM=256K RAM=32K + +tm4c129?k* tm4c129x ROM=512K RAM=256K +tm4c129?n* tm4c129x ROM=1024K RAM=256K ################################################################################ # the TI cortex R4F chips @@ -617,6 +633,8 @@ efm32wg END ROM_OFF=0x00000000 RAM_OFF=0x20000000 RAM1_OFF=0x10000000 CPU=cortex lm3fury lm3s lm3sandstorm lm3s lm3s END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft +tm4c123x lm4f +tm4c129x lm4f lm4f END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 From a6927e410c92f40cfc4a3609e905e3a96655114f Mon Sep 17 00:00:00 2001 From: Stefan Tauner Date: Wed, 2 Mar 2022 08:56:43 +0100 Subject: [PATCH 146/206] treewide: Fix some typos --- lib/lm4f/rcc.c | 6 +++--- lib/stm32/common/rcc_common_all.c | 2 +- mk/README | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/lm4f/rcc.c b/lib/lm4f/rcc.c index ee16de6c..af4ac4f7 100644 --- a/lib/lm4f/rcc.c +++ b/lib/lm4f/rcc.c @@ -28,7 +28,7 @@ Alexandru Gagniuc * \brief libopencm3 LM4F Clock control API * - * The LM$F clock API provides functionaliity for manipulating the system clock, + * The LM$F clock API provides functionality for manipulating the system clock, * oscillator, and PLL. Functions are provided for fine-grained control of clock * control registers, while also providing higher level functionality to easily * configure the main system clock source. @@ -98,7 +98,7 @@ Alexandru Gagniuc * @endcode * * If write access is desired (i.e. when changing the system clock via the - * fine-grained mechanisms), then include the following line in your code: + * fine-grained mechanisms), then include the following line in your code: * @code * extern uint32_t lm4f_rcc_sysclk_freq; * @endcode @@ -419,7 +419,7 @@ static uint32_t xtal_to_freq(enum xtal_t xtal) * \brief Configure the system clock source * * Sets up the system clock, including configuring the oscillator source, and - * PLL to acheve the desired system clock frequency. Where applicable, The LM4F + * PLL to achieve the desired system clock frequency. Where applicable, The LM4F * clock API uses the new RCC2 register to configure clock parameters. * * Enables the main oscillator if the clock source is OSCSRC_MOSC. If the main diff --git a/lib/stm32/common/rcc_common_all.c b/lib/stm32/common/rcc_common_all.c index 91c8b41b..0b1f9370 100644 --- a/lib/stm32/common/rcc_common_all.c +++ b/lib/stm32/common/rcc_common_all.c @@ -271,7 +271,7 @@ void rcc_osc_bypass_disable(enum rcc_osc osc) } /* This is a helper to calculate dividers that go 2/4/8/16/64/128/256/512. - * These dividers also use the top bit as an "enable". This is tyipcally + * These dividers also use the top bit as an "enable". This is typically * used for AHB and other system clock prescaler. */ uint16_t rcc_get_div_from_hpre(uint8_t div_val) { if (div_val < 0x8) { diff --git a/mk/README b/mk/README index 87e37e01..11fc2e7d 100644 --- a/mk/README +++ b/mk/README @@ -67,7 +67,7 @@ Variables to tell gcc about project dependencies and input files ---------------------------------------------------------------- LDSCRIPT Linker script file name (can be generated or fixed) -LIBDEPS Array of library filenames that shoud be rebuilt if needed +LIBDEPS Array of library filenames that should be rebuilt if needed LDLIBS Array of libraries to be linked with (array of -l) OBJS Array of object files to be built From 5bcf2a0c355de5d95c029ce8368b39f2b9b0f9f8 Mon Sep 17 00:00:00 2001 From: Stefan Tauner Date: Wed, 2 Mar 2022 09:05:28 +0100 Subject: [PATCH 147/206] stm32l4: fix various problems with rcc_get* functions - rcc_get_i2c_clk_freq: Add support by taking RCC_CCIPR2 into account for I2C4. - rcc_get_timer_clk_freq: Add support for LP timers - rcc_get_usart_clk_freq: Fix APB freq used for LPUART1 and UART1, respectively. --- include/libopencm3/stm32/l4/rcc.h | 9 ++---- lib/stm32/l4/rcc.c | 47 ++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/include/libopencm3/stm32/l4/rcc.h b/include/libopencm3/stm32/l4/rcc.h index a2bf7559..af430107 100644 --- a/include/libopencm3/stm32/l4/rcc.h +++ b/include/libopencm3/stm32/l4/rcc.h @@ -90,6 +90,7 @@ #define RCC_BDCR MMIO32(RCC_BASE + 0x90) #define RCC_CSR MMIO32(RCC_BASE + 0x94) #define RCC_CRRCR MMIO32(RCC_BASE + 0x98) +#define RCC_CCIPR2 MMIO32(RCC_BASE + 0x9C) /* --- RCC_CR values ------------------------------------------------------- */ @@ -636,6 +637,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CCIPR_I2CxSEL_SYS 1 #define RCC_CCIPR_I2CxSEL_HSI16 2 #define RCC_CCIPR_I2CxSEL_MASK 0x3 +#define RCC_CCIPR_I2C4SEL_SHIFT 0 #define RCC_CCIPR_I2C3SEL_SHIFT 16 #define RCC_CCIPR_I2C2SEL_SHIFT 14 #define RCC_CCIPR_I2C1SEL_SHIFT 12 @@ -663,13 +665,6 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CCIPR_USART2SEL_SHIFT 2 #define RCC_CCIPR_USART1SEL_SHIFT 0 -#define RCC_CCIPR_USART1SEL_APB 0 -#define RCC_CCIPR_USART1SEL_SYS 1 -#define RCC_CCIPR_USART1SEL_HSI16 2 -#define RCC_CCIPR_USART1SEL_LSE 3 -#define RCC_CCIPR_USART1SEL_SHIFT 0 -#define RCC_CCIPR_USART1SEL_MASK 0x3 - /* --- RCC_BDCR - Backup domain control register --------------------------- */ #define RCC_BDCR_LSCOSEL (1 << 25) diff --git a/lib/stm32/l4/rcc.c b/lib/stm32/l4/rcc.c index c8429184..d90db8b2 100644 --- a/lib/stm32/l4/rcc.c +++ b/lib/stm32/l4/rcc.c @@ -435,9 +435,10 @@ void rcc_set_rtc_clock_source(enum rcc_osc clk) } } -/* Helper to calculate the frequency of a UART/I2C based on the apb and clksel value. */ -static uint32_t rcc_uart_i2c_clksel_freq_hz(uint32_t apb_clk, uint8_t shift) { - uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_USARTxSEL_MASK; +/* Helper to calculate the frequency of a UART/I2C based on the apb and clksel value. + * For I2C, clock selection 0b11 is reserved while it specifies LSE for UARTs. */ +static uint32_t rcc_uart_i2c_clksel_freq_hz(uint32_t apb_clk, uint8_t shift, uint32_t clock_reg) { + uint8_t clksel = (clock_reg >> shift) & RCC_CCIPR_USARTxSEL_MASK; uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; switch (clksel) { case RCC_CCIPR_USARTxSEL_APB: @@ -446,6 +447,8 @@ static uint32_t rcc_uart_i2c_clksel_freq_hz(uint32_t apb_clk, uint8_t shift) { return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); case RCC_CCIPR_USARTxSEL_HSI16: return 16000000U; + case RCC_CCIPR_USARTxSEL_LSE: + return 32768U; } cm3_assert_not_reached(); } @@ -458,17 +461,17 @@ uint32_t rcc_get_usart_clk_freq(uint32_t usart) { /* Handle values with selectable clocks. */ if (usart == LPUART1_BASE) { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb2_frequency, RCC_CCIPR_LPUART1SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_LPUART1SEL_SHIFT, RCC_CCIPR); } else if (usart == USART1_BASE) { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART1SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb2_frequency, RCC_CCIPR_USART1SEL_SHIFT, RCC_CCIPR); } else if (usart == USART2_BASE) { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART2SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART2SEL_SHIFT, RCC_CCIPR); } else if (usart == USART3_BASE) { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART3SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART3SEL_SHIFT, RCC_CCIPR); } else if (usart == UART4_BASE) { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_UART4SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_UART4SEL_SHIFT, RCC_CCIPR); } else { /* USART5 */ - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_UART5SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_UART5SEL_SHIFT, RCC_CCIPR); } } @@ -479,7 +482,20 @@ uint32_t rcc_get_usart_clk_freq(uint32_t usart) uint32_t rcc_get_timer_clk_freq(uint32_t timer) { /* Handle APB1 timers, and apply multiplier if necessary. */ - if (timer >= TIM2_BASE && timer <= TIM7_BASE) { + if (timer == LPTIM1_BASE || timer == LPTIM2_BASE) { + int shift = (timer == LPTIM1_BASE) ? RCC_CCIPR_LPTIM1SEL_SHIFT : RCC_CCIPR_LPTIM2SEL_SHIFT; + uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_LPTIMxSEL_MASK; + switch (clksel) { + case RCC_CCIPR_LPTIMxSEL_APB: + return rcc_apb1_frequency; + case RCC_CCIPR_LPTIMxSEL_LSI: + return 32000U; + case RCC_CCIPR_LPTIMxSEL_HSI16: + return 16000000U; + case RCC_CCIPR_LPTIMxSEL_LSE: + return 32768U; + } + } else if (timer >= TIM2_BASE && timer <= TIM7_BASE) { uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; return (ppre1 == RCC_CFGR_PPRE1_NODIV) ? rcc_apb1_frequency : 2 * rcc_apb1_frequency; @@ -488,6 +504,7 @@ uint32_t rcc_get_timer_clk_freq(uint32_t timer) return (ppre2 == RCC_CFGR_PPRE2_NODIV) ? rcc_apb2_frequency : 2 * rcc_apb2_frequency; } + cm3_assert_not_reached(); } /*---------------------------------------------------------------------------*/ @@ -497,11 +514,13 @@ uint32_t rcc_get_timer_clk_freq(uint32_t timer) uint32_t rcc_get_i2c_clk_freq(uint32_t i2c) { if (i2c == I2C1_BASE) { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C1SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C1SEL_SHIFT, RCC_CCIPR); } else if (i2c == I2C2_BASE) { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C2SEL_SHIFT); - } else { /* I2C3 */ - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C3SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C2SEL_SHIFT, RCC_CCIPR); + } else if (i2c == I2C3_BASE) { + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C3SEL_SHIFT, RCC_CCIPR); + } else { /* I2C4 */ + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_I2C4SEL_SHIFT, RCC_CCIPR2); } } From c1e4107007bc532e7b980550e72b180384d5bc65 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 13 Apr 2022 20:23:41 +0000 Subject: [PATCH 148/206] lm4f: fix more typos --- lib/lm4f/rcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lm4f/rcc.c b/lib/lm4f/rcc.c index af4ac4f7..6d1bccb8 100644 --- a/lib/lm4f/rcc.c +++ b/lib/lm4f/rcc.c @@ -28,7 +28,7 @@ Alexandru Gagniuc * \brief libopencm3 LM4F Clock control API * - * The LM$F clock API provides functionality for manipulating the system clock, + * The LM4F clock API provides functionality for manipulating the system clock, * oscillator, and PLL. Functions are provided for fine-grained control of clock * control registers, while also providing higher level functionality to easily * configure the main system clock source. From 9209bde784e704f3d48d703b7ac07fd8841e891a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 13 Apr 2022 20:24:18 +0000 Subject: [PATCH 149/206] devices.data: drop invalid TI board name part. As pointed out, this is not an actual part number, but a board id. --- ld/devices.data | 3 --- 1 file changed, 3 deletions(-) diff --git a/ld/devices.data b/ld/devices.data index db2e63c0..33bdc9f5 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -489,9 +489,6 @@ lm4f???c4* lm4f ROM=64K RAM=24K lm4f???e5* lm4f ROM=128K RAM=32K lm4f???h5* lm4f ROM=256K RAM=32K -# (Wrong) legacy definition for EK-LM4F120XL board with an LM4F120H5QR -lm4f120xl lm4f ROM=128K RAM=32K - tm4c123?c3* tm4c123x ROM=32K RAM=12K tm4c123?d5* tm4c123x ROM=64K RAM=24K tm4c123?e6* tm4c123x ROM=128K RAM=32K From 664701d7a7f169235c457a3dd117415647aac61b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 13 Apr 2022 20:31:42 +0000 Subject: [PATCH 150/206] gadget-zero: ti: use correct part name Fixes build breakage from using legacy board name instead of part name. --- tests/gadget-zero/Makefile.tilm4f120xl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gadget-zero/Makefile.tilm4f120xl b/tests/gadget-zero/Makefile.tilm4f120xl index c8a36ff9..99642a3b 100644 --- a/tests/gadget-zero/Makefile.tilm4f120xl +++ b/tests/gadget-zero/Makefile.tilm4f120xl @@ -32,7 +32,7 @@ INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) OPENCM3_DIR=../.. ### This section can go to an arch shared rules eventually... -DEVICE=lm4f120xl +DEVICE=LM4F120H5QR OOCD_FILE = openocd.$(BOARD).cfg include $(OPENCM3_DIR)/mk/genlink-config.mk From d8aa2f17b02d1ae8e6c3cb9f1f64f1d8aaea4f4b Mon Sep 17 00:00:00 2001 From: "me@me.net" Date: Wed, 27 Apr 2022 14:37:27 +0200 Subject: [PATCH 151/206] stm32: timer: Add API to set external clock mode 2 --- .../libopencm3/stm32/common/timer_common_all.h | 8 ++++++++ lib/stm32/common/timer_common_all.c | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/libopencm3/stm32/common/timer_common_all.h b/include/libopencm3/stm32/common/timer_common_all.h index 08939d90..e5ff582d 100644 --- a/include/libopencm3/stm32/common/timer_common_all.h +++ b/include/libopencm3/stm32/common/timer_common_all.h @@ -1143,6 +1143,12 @@ enum tim_et_pol { TIM_ET_FALLING, }; +/** External clock mode 2 */ +enum tim_ecm2_state { + TIM_ECM2_DISABLED, + TIM_ECM2_ENABLED, +}; + /* --- TIM function prototypes --------------------------------------------- */ BEGIN_DECLS @@ -1233,6 +1239,8 @@ void timer_slave_set_prescaler(uint32_t timer, enum tim_ic_psc psc); void timer_slave_set_polarity(uint32_t timer, enum tim_et_pol pol); void timer_slave_set_mode(uint32_t timer, uint8_t mode); void timer_slave_set_trigger(uint32_t timer, uint8_t trigger); +void timer_slave_set_extclockmode2(uint32_t timer_peripheral, + enum tim_ecm2_state state); END_DECLS diff --git a/lib/stm32/common/timer_common_all.c b/lib/stm32/common/timer_common_all.c index cec245a4..220c13fb 100644 --- a/lib/stm32/common/timer_common_all.c +++ b/lib/stm32/common/timer_common_all.c @@ -1864,6 +1864,23 @@ void timer_slave_set_trigger(uint32_t timer_peripheral, uint8_t trigger) TIM_SMCR(timer_peripheral) |= trigger; } +/*---------------------------------------------------------------------------*/ +/** @brief Set External Clock Mode 2 + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] state ::tim_ecm2_state. External Clock Mode 2 state +*/ + +void timer_slave_set_extclockmode2(uint32_t timer_peripheral, + enum tim_ecm2_state state) +{ + if (state) { + TIM_SMCR(timer_peripheral) |= TIM_SMCR_ECE; + } else { + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ECE; + } +} + /* TODO Timer DMA burst */ /**@}*/ From 203202e9390d269ac0d57a6fd3c891f56998a4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Chevigny?= Date: Wed, 4 May 2022 18:56:40 -0400 Subject: [PATCH 152/206] Add nrf51822 device in devices.data --- ld/devices.data | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ld/devices.data b/ld/devices.data index 33bdc9f5..8dc1e6d7 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -521,6 +521,13 @@ pac5527 pac55xx ROM=128K RAM=32K pac5532 pac55xx ROM=128K RAM=32K pac5556 pac55xx ROM=128K RAM=32K +################################################################################ +# nRF51xx Cortex-M0 based chips + +nrf51822aa nrf51sf ROM=256K RAM=16K +nrf51822ab nrf51sf ROM=128K RAM=16K +nrf51822ac nrf51sf ROM=256K RAM=32K + ################################################################################ # nRF52xx Cortex-M4 based chips nrf52805* nrf52sf ROM=192k RAM=24K @@ -650,6 +657,13 @@ vf6xx END CPU=cortex-m4 FPU=hard-fpv4-sp-d16 pac55xx END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 +################################################################################ +# nRF51xx families +# +nrf51sf nrf51 FPU=soft + +nrf51 END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m0 + ################################################################################ # nRF52xx families # @@ -657,5 +671,3 @@ nrf52sf nrf52 FPU=soft nrf52fp nrf52 FPU=hard-fpv4-sp-d16 nrf52 END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m4 - - From e9d87a9cb7e6a687ddbfde085eddb461c89a3c09 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 17 May 2022 11:06:53 +0000 Subject: [PATCH 153/206] stm32: adc-v2-multi: fix JSQR Fixes: https://github.com/libopencm3/libopencm3/issues/1412 Verified against RM0394 (L4), RM0440 (G4) and RM0316 (F3) Signed-off-by: Karl Palsson --- include/libopencm3/stm32/common/adc_common_v2_multi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/common/adc_common_v2_multi.h b/include/libopencm3/stm32/common/adc_common_v2_multi.h index 901c65a6..e32c6b66 100644 --- a/include/libopencm3/stm32/common/adc_common_v2_multi.h +++ b/include/libopencm3/stm32/common/adc_common_v2_multi.h @@ -58,7 +58,7 @@ specific memorymap.h header before including this header file.*/ #define ADC_SQR4(adc) MMIO32((adc) + 0x3C) /* Injected Sequence Register (ADCx_JSQR, x=1..4) JSQR */ -#define ADC_JSQR(adc) MMIO32((adc) + 0x30) +#define ADC_JSQR(adc) MMIO32((adc) + 0x4c) /* Offset Register x (ADCx_OFRy, x=1..4) (y=1..4) OFRy */ #define ADC_OFR1(adc) MMIO32((adc) + 0x60) From 757a0a14ebe224af2799a6123f0a757f93ec7033 Mon Sep 17 00:00:00 2001 From: Stefan Tauner Date: Fri, 1 Apr 2022 14:17:44 +0200 Subject: [PATCH 154/206] doc: cm3: mpu: document defines of individual register fields --- include/libopencm3/cm3/mpu.h | 65 +++++++++++++++++------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/include/libopencm3/cm3/mpu.h b/include/libopencm3/cm3/mpu.h index d47abc60..300d9670 100644 --- a/include/libopencm3/cm3/mpu.h +++ b/include/libopencm3/cm3/mpu.h @@ -46,11 +46,11 @@ * *@{*/ /** MPU_TYPE is always available, even if the MPU is not implemented */ -#define MPU_TYPE MMIO32(MPU_BASE + 0x00) -#define MPU_CTRL MMIO32(MPU_BASE + 0x04) -#define MPU_RNR MMIO32(MPU_BASE + 0x08) -#define MPU_RBAR MMIO32(MPU_BASE + 0x0C) -#define MPU_RASR MMIO32(MPU_BASE + 0x10) +#define MPU_TYPE MMIO32(MPU_BASE + 0x00) /**< See also \ref CM3_mpu_type */ +#define MPU_CTRL MMIO32(MPU_BASE + 0x04) /**< See also \ref CM3_mpu_ctrl */ +#define MPU_RNR MMIO32(MPU_BASE + 0x08) /**< See also \ref CM3_mpu_rnr */ +#define MPU_RBAR MMIO32(MPU_BASE + 0x0C) /**< See also \ref CM3_mpu_rbar */ +#define MPU_RASR MMIO32(MPU_BASE + 0x10) /**< See also \ref CM3_mpu_rasr */ /**@}*/ /* --- MPU values ---------------------------------------------------------- */ @@ -60,23 +60,20 @@ * The MPU_TYPE register is always available, even if the MPU is not implemented. * In that case, the DREGION field will read as 0. *@{*/ -/** v6m/v7m only support a unified MPU (IREGION always 0) */ #define MPU_TYPE_IREGION_LSB 16 -#define MPU_TYPE_IREGION (0xFF << MPU_TYPE_IREGION_LSB) -/** DREGION is non zero if the MPU is available */ +#define MPU_TYPE_IREGION (0xFF << MPU_TYPE_IREGION_LSB) /**< Number of protected instruction regions; always 0 on v6m/v7m */ #define MPU_TYPE_DREGION_LSB 8 -#define MPU_TYPE_DREGION (0xFF << MPU_TYPE_DREGION_LSB) -/** v6m/v7m only support a unifed MPU (Separate always 0) */ -#define MPU_TYPE_SEPARATE (1<<0) +#define MPU_TYPE_DREGION (0xFF << MPU_TYPE_DREGION_LSB) /**< Number of protected data regions */ +#define MPU_TYPE_SEPARATE (1<<0) /**< Indicates if instruction regions are separate from data regions; always 0 on v6m/v7m */ /**@}*/ /** @defgroup CM3_mpu_ctrl MPU CTRL register fields * @ingroup CM3_mpu_defines * Defines for the Control Register. *@{*/ -#define MPU_CTRL_PRIVDEFENA (1<<2) -#define MPU_CTRL_HFNMIENA (1<<1) -#define MPU_CTRL_ENABLE (1<<0) +#define MPU_CTRL_PRIVDEFENA (1<<2) /**< Enable default map in privileged mode */ +#define MPU_CTRL_HFNMIENA (1<<1) /**< Enable MPU during hard fault, NMI, and FAULTMASK handlers */ +#define MPU_CTRL_ENABLE (1<<0) /**< MPU enable */ /**@}*/ /** @defgroup CM3_mpu_rnr MPU RNR register fields @@ -84,7 +81,7 @@ * Defines for the Region Number Register. *@{*/ #define MPU_RNR_REGION_LSB 0 -#define MPU_RNR_REGION (0xFF << MPU_RNR_REGION_LSB) +#define MPU_RNR_REGION (0xFF << MPU_RNR_REGION_LSB) /**< Determines the region affected by RBAR and RASR */ /**@}*/ /** @defgroup CM3_mpu_rbar MPU RBAR register fields @@ -93,9 +90,9 @@ *@{*/ /** minimum size supported is by writing all ones to ADDR, then reading back */ #define MPU_RBAR_ADDR 0xFFFFFFE0 -#define MPU_RBAR_VALID (1<<4) +#define MPU_RBAR_VALID (1<<4) /**< Use REGION to determine region to be accessed instead of MPU_RNR */ #define MPU_RBAR_REGION_LSB 0 -#define MPU_RBAR_REGION (0xF << MPU_RBAR_REGION_LSB) +#define MPU_RBAR_REGION (0xF << MPU_RBAR_REGION_LSB) /**< Region to change if MPU_RBAR_VALID is set */ /**@}*/ /** @defgroup CM3_mpu_rasr MPU RASR register fields @@ -103,31 +100,31 @@ * Defines for the Region Attribute and Size Register. *@{*/ #define MPU_RASR_ATTRS_LSB 16 -#define MPU_RASR_ATTRS (0xFFFF << MPU_RASR_ATTRS_LSB) +#define MPU_RASR_ATTRS (0xFFFF << MPU_RASR_ATTRS_LSB) /** Region attributes */ #define MPU_RASR_SRD_LSB 8 -#define MPU_RASR_SRD (0xFF << MPU_RASR_SRD_LSB) +#define MPU_RASR_SRD (0xFF << MPU_RASR_SRD_LSB) /**< Subregion disable bits */ #define MPU_RASR_SIZE_LSB 1 -#define MPU_RASR_SIZE (0x1F << MPU_RASR_SIZE_LSB) -#define MPU_RASR_ENABLE (1 << 0) +#define MPU_RASR_SIZE (0x1F << MPU_RASR_SIZE_LSB) /**< Region size */ +#define MPU_RASR_ENABLE (1 << 0) /**< Region enable bit */ /** @defgroup mpu_rasr_attributes MPU RASR Attributes * @ingroup CM3_mpu_rasr * Not all attributes are available on v6m. * *@{*/ -#define MPU_RASR_ATTR_XN (1 << 28) -#define MPU_RASR_ATTR_AP (7 << 24) -#define MPU_RASR_ATTR_AP_PNO_UNO (0 << 24) -#define MPU_RASR_ATTR_AP_PRW_UNO (1 << 24) -#define MPU_RASR_ATTR_AP_PRW_URO (2 << 24) -#define MPU_RASR_ATTR_AP_PRW_URW (3 << 24) -#define MPU_RASR_ATTR_AP_PRO_UNO (5 << 24) -#define MPU_RASR_ATTR_AP_PRO_URO (6 << 24) -#define MPU_RASR_ATTR_TEX (7 << 19) -#define MPU_RASR_ATTR_S (1 << 18) -#define MPU_RASR_ATTR_C (1 << 17) -#define MPU_RASR_ATTR_B (1 << 16) -#define MPU_RASR_ATTR_SCB (7 << 16) +#define MPU_RASR_ATTR_XN (1 << 28) /**< Execute never */ +#define MPU_RASR_ATTR_AP (7 << 24) /**< Access permissions mask */ +#define MPU_RASR_ATTR_AP_PNO_UNO (0 << 24) /**< Priv.: no, Unpriv.: no */ +#define MPU_RASR_ATTR_AP_PRW_UNO (1 << 24) /**< Priv.: RW, Unpriv.: no */ +#define MPU_RASR_ATTR_AP_PRW_URO (2 << 24) /**< Priv.: RW, Unpriv.: RO */ +#define MPU_RASR_ATTR_AP_PRW_URW (3 << 24) /**< Priv.: RW, Unpriv.: RW */ +#define MPU_RASR_ATTR_AP_PRO_UNO (5 << 24) /**< Priv.: RO, Unpriv.: no */ +#define MPU_RASR_ATTR_AP_PRO_URO (6 << 24) /**< Priv.: RO, Unpriv.: RO */ +#define MPU_RASR_ATTR_TEX (7 << 19) /**< Type extension (e.g., memory ordering) */ +#define MPU_RASR_ATTR_S (1 << 18) /**< Shareable */ +#define MPU_RASR_ATTR_C (1 << 17) /**< Cacheable */ +#define MPU_RASR_ATTR_B (1 << 16) /**< Bufferable */ +#define MPU_RASR_ATTR_SCB (7 << 16) /**< SCB mask */ /**@}*/ /**@}*/ From 3122c0b33ff4304d0323127911687751ddb8481f Mon Sep 17 00:00:00 2001 From: Vlad Logyin Date: Sun, 28 Nov 2021 11:08:57 +0000 Subject: [PATCH 155/206] stm32l4: rcc: Implement PLL helper as seen in other MCU families Reviewed-by: Karl Palsson --- include/libopencm3/stm32/l4/rcc.h | 104 +++++++++++++++++++++--------- lib/stm32/l4/rcc.c | 102 ++++++++++++++++++++++++++++- 2 files changed, 172 insertions(+), 34 deletions(-) diff --git a/include/libopencm3/stm32/l4/rcc.h b/include/libopencm3/stm32/l4/rcc.h index af430107..f85791c3 100644 --- a/include/libopencm3/stm32/l4/rcc.h +++ b/include/libopencm3/stm32/l4/rcc.h @@ -39,16 +39,25 @@ #ifndef LIBOPENCM3_RCC_H #define LIBOPENCM3_RCC_H -/* --- RCC registers ------------------------------------------------------- */ +#include +/** @defgroup rcc_registers RCC Registers + * @brief Reset / Clock Control Registers + @{*/ + /** Clock control register */ #define RCC_CR MMIO32(RCC_BASE + 0x00) #define RCC_ICSCR MMIO32(RCC_BASE + 0x04) + /** Clock Configuration register */ #define RCC_CFGR MMIO32(RCC_BASE + 0x08) +/** PLL Configuration register */ #define RCC_PLLCFGR MMIO32(RCC_BASE + 0x0c) #define RCC_PLLSAI1_CFGR MMIO32(RCC_BASE + 0x10) #define RCC_PLLSAI2_CFGR MMIO32(RCC_BASE + 0x14) +/** Clock interrupt enable register */ #define RCC_CIER MMIO32(RCC_BASE + 0x18) +/** Clock interrupt flag resiger */ #define RCC_CIFR MMIO32(RCC_BASE + 0x1c) +/** Clock interrupt clear register */ #define RCC_CICR MMIO32(RCC_BASE + 0x20) #define RCC_AHB1RSTR_OFFSET 0x28 #define RCC_AHB1RSTR MMIO32(RCC_BASE + RCC_AHB1RSTR_OFFSET) @@ -87,13 +96,18 @@ #define RCC_APB2SMENR_OFFSET 0x80 #define RCC_APB2SMENR MMIO32(RCC_BASE + RCC_APB2SMENR_OFFSET) #define RCC_CCIPR MMIO32(RCC_BASE + 0x88) +/** Backup Domain control register */ #define RCC_BDCR MMIO32(RCC_BASE + 0x90) +/** Clock control and status register */ #define RCC_CSR MMIO32(RCC_BASE + 0x94) #define RCC_CRRCR MMIO32(RCC_BASE + 0x98) #define RCC_CCIPR2 MMIO32(RCC_BASE + 0x9C) +/** @}*/ -/* --- RCC_CR values ------------------------------------------------------- */ - +/** @defgroup rcc_cr_values RCC_CR values + * @ingroup rcc_registers + * @brief Clock Control register values + @{*/ #define RCC_CR_PLLSAI2RDY (1 << 29) #define RCC_CR_PLLSAI2ON (1 << 28) #define RCC_CR_PLLSAI1RDY (1 << 27) @@ -108,6 +122,8 @@ #define RCC_CR_HSIRDY (1 << 10) #define RCC_CR_HSIKERON (1 << 9) #define RCC_CR_HSION (1 << 8) +/** @}*/ + /** @defgroup rcc_cr_msirange MSI Range * @ingroup STM32L4xx_rcc_defines * @brief Range of the MSI oscillator @@ -180,36 +196,35 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CFGR_STOPWUCK_MSI (0 << 15) #define RCC_CFGR_STOPWUCK_HSI16 (1 << 15) -/* PPRE2: APB high-speed prescaler (APB2) */ -#define RCC_CFGR_PPRE2_NODIV 0x0 -#define RCC_CFGR_PPRE2_DIV2 0x4 -#define RCC_CFGR_PPRE2_DIV4 0x5 -#define RCC_CFGR_PPRE2_DIV8 0x6 -#define RCC_CFGR_PPRE2_DIV16 0x7 -#define RCC_CFGR_PPRE2_MASK 0x7 -#define RCC_CFGR_PPRE2_SHIFT 11 +#define RCC_CFGR_PPRE1_SHIFT 8 +#define RCC_CFGR_PPRE1_MASK 0x7 +#define RCC_CFGR_PPRE2_SHIFT 11 +#define RCC_CFGR_PPRE2_MASK 0x7 +/** @defgroup rcc_cfgr_apbxpre RCC_CFGR APBx prescale factors + * These can be used for both APB1 and APB2 prescaling + * @{ + */ +#define RCC_CFGR_PPRE_NODIV 0x0 +#define RCC_CFGR_PPRE_DIV2 0x4 +#define RCC_CFGR_PPRE_DIV4 0x5 +#define RCC_CFGR_PPRE_DIV8 0x6 +#define RCC_CFGR_PPRE_DIV16 0x7 +/**@}*/ -/* PPRE1: APB low-speed prescaler (APB1) */ -#define RCC_CFGR_PPRE1_NODIV 0x0 -#define RCC_CFGR_PPRE1_DIV2 0x4 -#define RCC_CFGR_PPRE1_DIV4 0x5 -#define RCC_CFGR_PPRE1_DIV8 0x6 -#define RCC_CFGR_PPRE1_DIV16 0x7 -#define RCC_CFGR_PPRE1_MASK 0x7 -#define RCC_CFGR_PPRE1_SHIFT 8 - -/* HPRE: AHB prescaler */ -#define RCC_CFGR_HPRE_NODIV 0x0 -#define RCC_CFGR_HPRE_DIV2 0x8 -#define RCC_CFGR_HPRE_DIV4 0x9 -#define RCC_CFGR_HPRE_DIV8 0xa -#define RCC_CFGR_HPRE_DIV16 0xb -#define RCC_CFGR_HPRE_DIV64 0xc -#define RCC_CFGR_HPRE_DIV128 0xd -#define RCC_CFGR_HPRE_DIV256 0xe -#define RCC_CFGR_HPRE_DIV512 0xf -#define RCC_CFGR_HPRE_MASK 0xf -#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE_MASK 0xf +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale factors +@{*/ +#define RCC_CFGR_HPRE_NODIV 0x0 +#define RCC_CFGR_HPRE_DIV2 (0x8 + 0) +#define RCC_CFGR_HPRE_DIV4 (0x8 + 1) +#define RCC_CFGR_HPRE_DIV8 (0x8 + 2) +#define RCC_CFGR_HPRE_DIV16 (0x8 + 3) +#define RCC_CFGR_HPRE_DIV64 (0x8 + 4) +#define RCC_CFGR_HPRE_DIV128 (0x8 + 5) +#define RCC_CFGR_HPRE_DIV256 (0x8 + 6) +#define RCC_CFGR_HPRE_DIV512 (0x8 + 7) +/**@}*/ /* SWS: System clock switch status */ #define RCC_CFGR_SWS_MSI 0x0 @@ -725,6 +740,30 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CSR_LSIRDY (1 << 1) #define RCC_CSR_LSION (1 << 0) +struct rcc_clock_scale { + uint8_t pllm; + uint16_t plln; + uint8_t pllp; + uint8_t pllq; + uint8_t pllr; + uint8_t pll_source; + uint32_t flash_config; + uint8_t hpre; + uint8_t ppre1; + uint8_t ppre2; + enum pwr_vos_scale voltage_scale; + uint32_t ahb_frequency; + uint32_t apb1_frequency; + uint32_t apb2_frequency; +}; + +enum rcc_clock_config_entry { + RCC_CLOCK_VRANGE1_80MHZ, + RCC_CLOCK_CONFIG_END +}; + +extern const struct rcc_clock_scale rcc_hsi16_configs[RCC_CLOCK_CONFIG_END]; + /* --- Variable definitions ------------------------------------------------ */ extern uint32_t rcc_ahb_frequency; @@ -981,6 +1020,7 @@ void rcc_set_ppre1(uint32_t ppre1); void rcc_set_hpre(uint32_t hpre); void rcc_set_main_pll(uint32_t source, uint32_t pllm, uint32_t plln, uint32_t pllp, uint32_t pllq, uint32_t pllr); uint32_t rcc_system_clock_source(void); +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); void rcc_set_msi_range(uint32_t msi_range); void rcc_set_msi_range_standby(uint32_t msi_range); void rcc_pll_output_enable(uint32_t pllout); diff --git a/lib/stm32/l4/rcc.c b/lib/stm32/l4/rcc.c index d90db8b2..c35a1896 100644 --- a/lib/stm32/l4/rcc.c +++ b/lib/stm32/l4/rcc.c @@ -38,12 +38,34 @@ /**@{*/ #include #include +#include +#include /* Set the default clock frequencies after reset. */ uint32_t rcc_ahb_frequency = 4000000; uint32_t rcc_apb1_frequency = 4000000; uint32_t rcc_apb2_frequency = 4000000; +const struct rcc_clock_scale rcc_hsi16_configs[RCC_CLOCK_CONFIG_END] = { + { /* 80MHz PLL from HSI16 VR1 */ + .pllm = 4, + .plln = 40, + .pllp = RCC_PLLCFGR_PLLP_DIV7, + .pllq = RCC_PLLCFGR_PLLQ_DIV6, + .pllr = RCC_PLLCFGR_PLLR_DIV2, + .pll_source = RCC_PLLCFGR_PLLSRC_HSI16, + .hpre = RCC_CFGR_HPRE_NODIV, + .ppre1 = RCC_CFGR_PPRE_NODIV, + .ppre2 = RCC_CFGR_PPRE_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_LATENCY_4WS, + .ahb_frequency = 80000000, + .apb1_frequency = 80000000, + .apb2_frequency = 80000000, + }, +}; + void rcc_osc_ready_int_clear(enum rcc_osc osc) { switch (osc) { @@ -341,6 +363,82 @@ uint32_t rcc_system_clock_source(void) return (RCC_CFGR >> RCC_CFGR_SWS_SHIFT) & RCC_CFGR_SWS_MASK; } +/** + * Setup clocks to run from PLL. + * + * The arguments provide the pll source, multipliers, dividers, all that's + * needed to establish a system clock. + * + * @param clock clock information structure. + */ +void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) +{ + /* Enable internal high-speed oscillator (HSI16). */ + rcc_osc_on(RCC_HSI16); + rcc_wait_for_osc_ready(RCC_HSI16); + + /* Select HSI16 as SYSCLK source. */ + rcc_set_sysclk_source(RCC_PLLCFGR_PLLSRC_HSI16); + + /* Enable external high-speed oscillator (HSE). */ + if (clock->pll_source == RCC_PLLCFGR_PLLSRC_HSE) { + rcc_osc_on(RCC_HSE); + rcc_wait_for_osc_ready(RCC_HSE); + } + + /* Set the VOS scale mode */ + rcc_periph_clock_enable(RCC_PWR); + pwr_set_vos_scale(clock->voltage_scale); + + /* + * Set prescalers for AHB, ADC, APB1, APB2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + /* Disable PLL oscillator before changing its configuration. */ + rcc_osc_off(RCC_PLL); + + /* Configure the PLL oscillator. */ + rcc_set_main_pll(clock->pll_source, clock->pllm, clock->plln, + clock->pllp, clock->pllq, clock->pllr); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(RCC_PLL); + rcc_wait_for_osc_ready(RCC_PLL); + + /* Configure flash settings. */ + if (clock->flash_config & FLASH_ACR_DCEN) { + flash_dcache_enable(); + } else { + flash_dcache_disable(); + } + if (clock->flash_config & FLASH_ACR_ICEN) { + flash_icache_enable(); + } else { + flash_icache_disable(); + } + flash_set_ws(clock->flash_config); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_PLL); + + /* Wait for PLL clock to be selected. */ + rcc_wait_for_sysclk_status(RCC_PLL); + + /* Set the peripheral clock frequencies used. */ + rcc_ahb_frequency = clock->ahb_frequency; + rcc_apb1_frequency = clock->apb1_frequency; + rcc_apb2_frequency = clock->apb2_frequency; + + /* Disable internal high-speed oscillator. */ + if (clock->pll_source == RCC_PLLCFGR_PLLSRC_HSE) { + rcc_osc_off(RCC_HSI16); + } +} + /** * Set the msi run time range. * Can only be called when MSI is either OFF, or when MSI is on _and_ @@ -497,11 +595,11 @@ uint32_t rcc_get_timer_clk_freq(uint32_t timer) } } else if (timer >= TIM2_BASE && timer <= TIM7_BASE) { uint8_t ppre1 = (RCC_CFGR >> RCC_CFGR_PPRE1_SHIFT) & RCC_CFGR_PPRE1_MASK; - return (ppre1 == RCC_CFGR_PPRE1_NODIV) ? rcc_apb1_frequency + return (ppre1 == RCC_CFGR_PPRE_NODIV) ? rcc_apb1_frequency : 2 * rcc_apb1_frequency; } else { uint8_t ppre2 = (RCC_CFGR >> RCC_CFGR_PPRE2_SHIFT) & RCC_CFGR_PPRE2_MASK; - return (ppre2 == RCC_CFGR_PPRE2_NODIV) ? rcc_apb2_frequency + return (ppre2 == RCC_CFGR_PPRE_NODIV) ? rcc_apb2_frequency : 2 * rcc_apb2_frequency; } cm3_assert_not_reached(); From 1e71f18be2a8899e979c4cfd07e1b66ec71eaa6d Mon Sep 17 00:00:00 2001 From: Oskar Date: Fri, 27 May 2022 15:22:07 +0200 Subject: [PATCH 156/206] stm32g4: i2c: enable common peripheral code. --- include/libopencm3/stm32/g4/i2c.h | 34 +++++++++++++++++++++++++++++++ include/libopencm3/stm32/i2c.h | 3 ++- lib/stm32/g4/Makefile | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 include/libopencm3/stm32/g4/i2c.h diff --git a/include/libopencm3/stm32/g4/i2c.h b/include/libopencm3/stm32/g4/i2c.h new file mode 100644 index 00000000..7c17d831 --- /dev/null +++ b/include/libopencm3/stm32/g4/i2c.h @@ -0,0 +1,34 @@ +/** @defgroup i2c_defines I2C Defines + * + * @ingroup STM32G4xx_defines + * + * @brief Defined Constants and Types for the STM32G4xx I2C + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_I2C_H +#define LIBOPENCM3_I2C_H + +#include + +#endif + diff --git a/include/libopencm3/stm32/i2c.h b/include/libopencm3/stm32/i2c.h index 880ca49e..90b19889 100644 --- a/include/libopencm3/stm32/i2c.h +++ b/include/libopencm3/stm32/i2c.h @@ -40,7 +40,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined." #endif - diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 70318c6f..8a51849b 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -43,6 +43,7 @@ OBJS += dmamux.o OBJS += fdcan.o fdcan_common.o OBJS += flash.o flash_common_all.o flash_common_f.o flash_common_idcache.o OBJS += gpio_common_all.o gpio_common_f0234.o +OBJS += i2c_common_v2.o OBJS += opamp_common_all.o opamp_common_v2.o OBJS += pwr.o OBJS += rcc.o rcc_common_all.o From 467522778329d6f41781a6c951b77d6ff6744de6 Mon Sep 17 00:00:00 2001 From: Oskar Date: Thu, 2 Jun 2022 09:44:20 +0200 Subject: [PATCH 157/206] stm32g4: rng: enable common code support Also fixes an error in the memory map exposed by enabling this. Reviewed-by: Karl Palsson --- include/libopencm3/stm32/g4/memorymap.h | 4 +-- include/libopencm3/stm32/g4/rng.h | 40 +++++++++++++++++++++++++ include/libopencm3/stm32/rng.h | 2 ++ lib/stm32/g4/Makefile | 1 + 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 include/libopencm3/stm32/g4/rng.h diff --git a/include/libopencm3/stm32/g4/memorymap.h b/include/libopencm3/stm32/g4/memorymap.h index 7da6e578..837160e4 100644 --- a/include/libopencm3/stm32/g4/memorymap.h +++ b/include/libopencm3/stm32/g4/memorymap.h @@ -115,8 +115,8 @@ #define DAC2_BASE (PERIPH_BASE_AHB2 + 0x0c00) #define DAC3_BASE (PERIPH_BASE_AHB2 + 0x1000) #define DAC4_BASE (PERIPH_BASE_AHB2 + 0x1400) -#define AES_BASE (PERIPH_BASE_AHB2 + 0x6000) -#define RNG_BASE (PERIPH_BASE_AHB2 + 0x6800) +#define AES_BASE (PERIPH_BASE_AHB2 + 0x60000) +#define RNG_BASE (PERIPH_BASE_AHB2 + 0x60800) #define FMC_BASE (0xa0000000U) #define QUADSPI_BASE (0xa0001000U) diff --git a/include/libopencm3/stm32/g4/rng.h b/include/libopencm3/stm32/g4/rng.h new file mode 100644 index 00000000..44706ffa --- /dev/null +++ b/include/libopencm3/stm32/g4/rng.h @@ -0,0 +1,40 @@ +/** @defgroup rng_defines RNG Defines + * + * @ingroup STM32G4xx_defines + * + * @brief Defined Constants and Types for the STM32G4xx RNG Control + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + * */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ +#ifndef LIBOPENCM3_RNG_H +#define LIBOPENCM3_RNG_H + +#include + +/* --- RNG_CR values ------------------------------------------------------- */ + +/** Clock error detection : CED = 0 : Detection Enabled */ +#define RNG_CR_CED (1 << 5) + +#endif +/**@}*/ diff --git a/include/libopencm3/stm32/rng.h b/include/libopencm3/stm32/rng.h index 01f1b104..68a1c2f2 100644 --- a/include/libopencm3/stm32/rng.h +++ b/include/libopencm3/stm32/rng.h @@ -34,6 +34,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined." #endif diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 8a51849b..38423565 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -47,6 +47,7 @@ OBJS += i2c_common_v2.o OBJS += opamp_common_all.o opamp_common_v2.o OBJS += pwr.o OBJS += rcc.o rcc_common_all.o +OBJS += rng_common_v1.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o timer_common_f0234.o OBJS += quadspi_common_v1.o From 44e142d4f97863e669737707a1a22bf40ed49bbc Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 5 Jul 2022 16:52:43 +0000 Subject: [PATCH 158/206] cm3: scb: C11 keyword compliance Avoid use of the gnu specific "asm" keyword, and use the __asm__ keyword, as used everywhere else in the library. This fixes compilation in C11, and unifies all uses of asm literals in the codebase. Reported-by: @dragonmux Fixes: https://github.com/libopencm3/libopencm3/pull/1425 Signed-off-by: Karl Palsson --- include/libopencm3/cm3/scb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/cm3/scb.h b/include/libopencm3/cm3/scb.h index aafe70c6..74ac623b 100644 --- a/include/libopencm3/cm3/scb.h +++ b/include/libopencm3/cm3/scb.h @@ -549,7 +549,7 @@ struct scb_exception_stack_frame { #define SCB_GET_EXCEPTION_STACK_FRAME(f) \ do { \ - asm volatile ("mov %[frameptr], sp" \ + __asm__ volatile ("mov %[frameptr], sp" \ : [frameptr]"=r" (f)); \ } while (0) From c82c7406aa57948d1adabfdc51e8577ae37e99d4 Mon Sep 17 00:00:00 2001 From: hepoun <43733554+hepoun@users.noreply.github.com> Date: Thu, 8 Sep 2022 12:36:53 +0200 Subject: [PATCH 159/206] stm32:dmamux: Fix request generator reset There was reset of DMAMUX request multiplexer channel instead of the DMAMUX request generator channel. --- lib/stm32/common/dmamux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stm32/common/dmamux.c b/lib/stm32/common/dmamux.c index 4b520e17..e7b9d73f 100644 --- a/lib/stm32/common/dmamux.c +++ b/lib/stm32/common/dmamux.c @@ -231,7 +231,7 @@ Reset Request Generator Channel Configuration and interrupt flags. */ void dmamux_reset_request_generator_channel(uint32_t dmamux, uint8_t rg_channel) { - DMAMUX_CxCR(dmamux, rg_channel) = 0; + DMAMUX_RGxCR(dmamux, rg_channel) = 0; dmamux_clear_request_generator_trigger_overrun_interrupt(dmamux, rg_channel); } From b37811915e9c3de44a6ec69f8f49c42d8c731468 Mon Sep 17 00:00:00 2001 From: neoxic Date: Thu, 15 Sep 2022 21:36:38 -0700 Subject: [PATCH 160/206] stm32:dmamux: fix individual DMAMUX register aliases DMAMUXn_* Argument 'dmamux_base' is set by an alias and hence is always unused. --- .../stm32/common/dmamux_common_all.h | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/libopencm3/stm32/common/dmamux_common_all.h b/include/libopencm3/stm32/common/dmamux_common_all.h index f8b1a528..23c3df2c 100644 --- a/include/libopencm3/stm32/common/dmamux_common_all.h +++ b/include/libopencm3/stm32/common/dmamux_common_all.h @@ -34,24 +34,24 @@ #define DMAMUX2_CxCR(dma_channel) DMAMUX_CxCR(DMAMUX2, (dma_channel)) #define DMAMUX_CSR(dmamux_base) MMIO32((dmamux_base) + 0x80) -#define DMAMUX1_CSR(dmamux_base) DMAMUX_CSR(DMAMUX1) -#define DMAMUX2_CSR(dmamux_base) DMAMUX_CSR(DMAMUX2) +#define DMAMUX1_CSR DMAMUX_CSR(DMAMUX1) +#define DMAMUX2_CSR DMAMUX_CSR(DMAMUX2) #define DMAMUX_CFR(dmamux_base) MMIO32((dmamux_base) + 0x84) -#define DMAMUX1_CFR(dmamux_base) DMAMUX_CFR(DMAMUX1) -#define DMAMUX2_CFR(dmamux_base) DMAMUX_CFR(DMAMUX2) +#define DMAMUX1_CFR DMAMUX_CFR(DMAMUX1) +#define DMAMUX2_CFR DMAMUX_CFR(DMAMUX2) #define DMAMUX_RGxCR(dmamux_base, rg_channel) MMIO32((dmamux_base) + 0x100 + 0x04 * ((rg_channel) - 1)) -#define DMAMUX1_RGxCR(dmamux_base, rg_channel) DMAMUX_RGxCR(DMAMUX1, (rg_channel)) -#define DMAMUX2_RGxCR(dmamux_base, rg_channel) DMAMUX_RGxCR(DMAMUX2, (rg_channel)) +#define DMAMUX1_RGxCR(rg_channel) DMAMUX_RGxCR(DMAMUX1, (rg_channel)) +#define DMAMUX2_RGxCR(rg_channel) DMAMUX_RGxCR(DMAMUX2, (rg_channel)) #define DMAMUX_RGSR(dmamux_base) MMIO32((dmamux_base) + 0x140) -#define DMAMUX1_RGSR(dmamux_base) DMAMUX_RSGR(DMAMUX1) -#define DMAMUX2_RGSR(dmamux_base) DMAMUX_RSGR(DMAMUX2) +#define DMAMUX1_RGSR DMAMUX_RSGR(DMAMUX1) +#define DMAMUX2_RGSR DMAMUX_RSGR(DMAMUX2) #define DMAMUX_RGCFR(dmamux_base) MMIO32((dmamux_base) + 0x144) -#define DMAMUX1_RGCFR(dmamux_base) DMAMUX_RGCFR(DMAMUX1) -#define DMAMUX2_RGCFR(dmamux_base) DMAMUX_RGCFR(DMAMUX2) +#define DMAMUX1_RGCFR DMAMUX_RGCFR(DMAMUX1) +#define DMAMUX2_RGCFR DMAMUX_RGCFR(DMAMUX2) /** @defgroup dmamux_cxcr CxCR DMA request line multiplexer channel x control register @{*/ From 0a132c0f6cba20491a1c9e8f5a1b841e180167eb Mon Sep 17 00:00:00 2001 From: neoxic Date: Thu, 15 Sep 2022 21:46:43 -0700 Subject: [PATCH 161/206] stm32: dmamux: Fix tabs as tab size 8 --- .../stm32/common/dmamux_common_all.h | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/libopencm3/stm32/common/dmamux_common_all.h b/include/libopencm3/stm32/common/dmamux_common_all.h index 23c3df2c..9e872739 100644 --- a/include/libopencm3/stm32/common/dmamux_common_all.h +++ b/include/libopencm3/stm32/common/dmamux_common_all.h @@ -30,28 +30,28 @@ /**@{*/ #define DMAMUX_CxCR(dmamux_base, dma_channel) MMIO32((dmamux_base) + 0x04 * ((dma_channel) - 1)) -#define DMAMUX1_CxCR(dma_channel) DMAMUX_CxCR(DMAMUX1, (dma_channel)) -#define DMAMUX2_CxCR(dma_channel) DMAMUX_CxCR(DMAMUX2, (dma_channel)) +#define DMAMUX1_CxCR(dma_channel) DMAMUX_CxCR(DMAMUX1, (dma_channel)) +#define DMAMUX2_CxCR(dma_channel) DMAMUX_CxCR(DMAMUX2, (dma_channel)) -#define DMAMUX_CSR(dmamux_base) MMIO32((dmamux_base) + 0x80) -#define DMAMUX1_CSR DMAMUX_CSR(DMAMUX1) -#define DMAMUX2_CSR DMAMUX_CSR(DMAMUX2) +#define DMAMUX_CSR(dmamux_base) MMIO32((dmamux_base) + 0x80) +#define DMAMUX1_CSR DMAMUX_CSR(DMAMUX1) +#define DMAMUX2_CSR DMAMUX_CSR(DMAMUX2) -#define DMAMUX_CFR(dmamux_base) MMIO32((dmamux_base) + 0x84) -#define DMAMUX1_CFR DMAMUX_CFR(DMAMUX1) -#define DMAMUX2_CFR DMAMUX_CFR(DMAMUX2) +#define DMAMUX_CFR(dmamux_base) MMIO32((dmamux_base) + 0x84) +#define DMAMUX1_CFR DMAMUX_CFR(DMAMUX1) +#define DMAMUX2_CFR DMAMUX_CFR(DMAMUX2) #define DMAMUX_RGxCR(dmamux_base, rg_channel) MMIO32((dmamux_base) + 0x100 + 0x04 * ((rg_channel) - 1)) -#define DMAMUX1_RGxCR(rg_channel) DMAMUX_RGxCR(DMAMUX1, (rg_channel)) -#define DMAMUX2_RGxCR(rg_channel) DMAMUX_RGxCR(DMAMUX2, (rg_channel)) +#define DMAMUX1_RGxCR(rg_channel) DMAMUX_RGxCR(DMAMUX1, (rg_channel)) +#define DMAMUX2_RGxCR(rg_channel) DMAMUX_RGxCR(DMAMUX2, (rg_channel)) -#define DMAMUX_RGSR(dmamux_base) MMIO32((dmamux_base) + 0x140) -#define DMAMUX1_RGSR DMAMUX_RSGR(DMAMUX1) -#define DMAMUX2_RGSR DMAMUX_RSGR(DMAMUX2) +#define DMAMUX_RGSR(dmamux_base) MMIO32((dmamux_base) + 0x140) +#define DMAMUX1_RGSR DMAMUX_RSGR(DMAMUX1) +#define DMAMUX2_RGSR DMAMUX_RSGR(DMAMUX2) -#define DMAMUX_RGCFR(dmamux_base) MMIO32((dmamux_base) + 0x144) -#define DMAMUX1_RGCFR DMAMUX_RGCFR(DMAMUX1) -#define DMAMUX2_RGCFR DMAMUX_RGCFR(DMAMUX2) +#define DMAMUX_RGCFR(dmamux_base) MMIO32((dmamux_base) + 0x144) +#define DMAMUX1_RGCFR DMAMUX_RGCFR(DMAMUX1) +#define DMAMUX2_RGCFR DMAMUX_RGCFR(DMAMUX2) /** @defgroup dmamux_cxcr CxCR DMA request line multiplexer channel x control register @{*/ From 2f29614133dbf34d5aa088cf8d6a1a6c74fb58c6 Mon Sep 17 00:00:00 2001 From: andrej Date: Mon, 19 Sep 2022 11:28:57 +0200 Subject: [PATCH 162/206] stm32: Support CRC, SYSCFG and USART on G4 --- include/libopencm3/stm32/crc.h | 2 + include/libopencm3/stm32/g4/crc.h | 33 +++++++++++++++++ include/libopencm3/stm32/g4/syscfg.h | 50 +++++++++++++++++++++++++ include/libopencm3/stm32/g4/usart.h | 55 ++++++++++++++++++++++++++++ include/libopencm3/stm32/syscfg.h | 2 + include/libopencm3/stm32/usart.h | 2 + lib/stm32/g4/Makefile | 2 + 7 files changed, 146 insertions(+) create mode 100644 include/libopencm3/stm32/g4/crc.h create mode 100644 include/libopencm3/stm32/g4/syscfg.h create mode 100644 include/libopencm3/stm32/g4/usart.h diff --git a/include/libopencm3/stm32/crc.h b/include/libopencm3/stm32/crc.h index 07498669..54157b18 100644 --- a/include/libopencm3/stm32/crc.h +++ b/include/libopencm3/stm32/crc.h @@ -40,6 +40,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #else # error "stm32 family not defined." #endif diff --git a/include/libopencm3/stm32/g4/crc.h b/include/libopencm3/stm32/g4/crc.h new file mode 100644 index 00000000..3b464191 --- /dev/null +++ b/include/libopencm3/stm32/g4/crc.h @@ -0,0 +1,33 @@ +/** @defgroup crc_defines CRC Defines + * + * @brief Defined Constants and Types for the STM32G4xx CRC Generator + * + * @ingroup STM32G4xx_defines + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRC_H +#define LIBOPENCM3_CRC_H + +#include + +#endif diff --git a/include/libopencm3/stm32/g4/syscfg.h b/include/libopencm3/stm32/g4/syscfg.h new file mode 100644 index 00000000..e490032f --- /dev/null +++ b/include/libopencm3/stm32/g4/syscfg.h @@ -0,0 +1,50 @@ +/** @defgroup syscfg_defines SYSCFG Defines + * + * @ingroup STM32G4xx_defines + * + * @brief Defined Constants and Types for the STM32G4xx Sysconfig + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + * + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SYSCFG_H +#define LIBOPENCM3_SYSCFG_H + +#define SYSCFG_MEMRM MMIO32(SYSCFG_BASE + 0x00) + +#define SYSCFG_PMC MMIO32(SYSCFG_BASE + 0x04) + +/* External interrupt configuration registers [0..3] (SYSCFG_EXTICR[1..4]) */ +#define SYSCFG_EXTICR(i) MMIO32(SYSCFG_BASE + 0x08 + (i)*4) +#define SYSCFG_EXTICR1 SYSCFG_EXTICR(0) +#define SYSCFG_EXTICR2 SYSCFG_EXTICR(1) +#define SYSCFG_EXTICR3 SYSCFG_EXTICR(2) +#define SYSCFG_EXTICR4 SYSCFG_EXTICR(3) + +#define SYSCFG_SWPR MMIO32(SYSCFG_BASE + 0x20) + +/* --- SYSCFG_EXTICR Values -------------------------------------------------*/ + +#define SYSCFG_EXTICR_FIELDSIZE 4 + +#endif diff --git a/include/libopencm3/stm32/g4/usart.h b/include/libopencm3/stm32/g4/usart.h new file mode 100644 index 00000000..a4c0474d --- /dev/null +++ b/include/libopencm3/stm32/g4/usart.h @@ -0,0 +1,55 @@ +/** @defgroup usart_defines USART Defines + * + * @brief Defined Constants and Types for the STM32G4xx USART + * + * @ingroup STM32G4xx_defines + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_USART_H +#define LIBOPENCM3_USART_H + +#include +#include + +/**@{*/ + +/** @defgroup usart_reg_base USART register base addresses + * Holds all the U(S)ART peripherals supported. + * @{ + */ +#define USART1 USART1_BASE +#define USART2 USART2_BASE +#define USART3 USART3_BASE +#define UART4 UART4_BASE +#define UART5 UART5_BASE +/**@}*/ + +BEGIN_DECLS + +END_DECLS + +/**@}*/ + +#endif + diff --git a/include/libopencm3/stm32/syscfg.h b/include/libopencm3/stm32/syscfg.h index a3c3bfdd..7a7d4756 100644 --- a/include/libopencm3/stm32/syscfg.h +++ b/include/libopencm3/stm32/syscfg.h @@ -38,6 +38,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include #else diff --git a/include/libopencm3/stm32/usart.h b/include/libopencm3/stm32/usart.h index c6cb5f96..3e835598 100644 --- a/include/libopencm3/stm32/usart.h +++ b/include/libopencm3/stm32/usart.h @@ -40,6 +40,8 @@ # include #elif defined(STM32G0) # include +#elif defined(STM32G4) +# include #elif defined(STM32H7) # include #else diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index 38423565..bcb3166b 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -37,6 +37,7 @@ ARFLAGS = rcs OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o OBJS += crs_common_all.o +OBJS += crc_common_all.o crc_v2.o OBJS += dac_common_all.o dac_common_v2.o OBJS += dma_common_l1f013.o OBJS += dmamux.o @@ -51,6 +52,7 @@ OBJS += rng_common_v1.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o timer_common_f0234.o OBJS += quadspi_common_v1.o +OBJS += usart_common_v2.o usart_common_all.o OBJS += usb.o usb_control.o usb_standard.o OBJS += usb_audio.o From 5980c58f9b72bf302f64da76bdf105a85b9d1903 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 19 Sep 2022 12:59:05 +0000 Subject: [PATCH 163/206] stm32g4: syscfg: fix doxygen Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g4/syscfg.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/include/libopencm3/stm32/g4/syscfg.h b/include/libopencm3/stm32/g4/syscfg.h index e490032f..53f73980 100644 --- a/include/libopencm3/stm32/g4/syscfg.h +++ b/include/libopencm3/stm32/g4/syscfg.h @@ -7,6 +7,7 @@ * @version 1.0.0 * * LGPL License Terms @ref lgpl_license + * @{ * */ @@ -27,14 +28,16 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_SYSCFG_H -#define LIBOPENCM3_SYSCFG_H +#pragma once + +/** @defgroup syscfg_registers SYSCFG registers +@{*/ #define SYSCFG_MEMRM MMIO32(SYSCFG_BASE + 0x00) #define SYSCFG_PMC MMIO32(SYSCFG_BASE + 0x04) -/* External interrupt configuration registers [0..3] (SYSCFG_EXTICR[1..4]) */ +/** External interrupt configuration registers [0..3] (SYSCFG_EXTICR[1..4]) */ #define SYSCFG_EXTICR(i) MMIO32(SYSCFG_BASE + 0x08 + (i)*4) #define SYSCFG_EXTICR1 SYSCFG_EXTICR(0) #define SYSCFG_EXTICR2 SYSCFG_EXTICR(1) @@ -42,9 +45,8 @@ #define SYSCFG_EXTICR4 SYSCFG_EXTICR(3) #define SYSCFG_SWPR MMIO32(SYSCFG_BASE + 0x20) - -/* --- SYSCFG_EXTICR Values -------------------------------------------------*/ +/**@}*/ #define SYSCFG_EXTICR_FIELDSIZE 4 -#endif +/**@}*/ From d8d33ca36d93aa3c713d7e8afac5aaf11b4113bf Mon Sep 17 00:00:00 2001 From: Oskar Date: Mon, 19 Sep 2022 12:59:05 +0000 Subject: [PATCH 164/206] stm32: cordic: add new peripheral Review-URL: https://github.com/libopencm3/libopencm3/pull/1418 Reviewed-by: Karl Palsson Edits: removed non-existant u5 code, squished to a single commit, whitespace cleanup. --- .../stm32/common/cordic_common_v1.h | 169 ++++++ include/libopencm3/stm32/cordic.h | 29 ++ include/libopencm3/stm32/g4/cordic.h | 34 ++ lib/stm32/common/cordic_common_v1.c | 486 ++++++++++++++++++ lib/stm32/g4/Makefile | 1 + 5 files changed, 719 insertions(+) create mode 100644 include/libopencm3/stm32/common/cordic_common_v1.h create mode 100644 include/libopencm3/stm32/cordic.h create mode 100644 include/libopencm3/stm32/g4/cordic.h create mode 100644 lib/stm32/common/cordic_common_v1.c diff --git a/include/libopencm3/stm32/common/cordic_common_v1.h b/include/libopencm3/stm32/common/cordic_common_v1.h new file mode 100644 index 00000000..4fcbc1c4 --- /dev/null +++ b/include/libopencm3/stm32/common/cordic_common_v1.h @@ -0,0 +1,169 @@ +/** @addtogroup cordic_defines + +@author @htmlonly © @endhtmlonly 2022 Oskar H. Maier + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2022 Oskar H. Maier + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA CORDIC.H +The order of header inclusion is important. cordic.h includes the device +specific memorymap.h header before including this header file.*/ + +/** @cond */ +#ifdef LIBOPENCM3_CORDIC_H +/** @endcond */ +#ifndef LIBOPENCM3_CORDIC_COMMON_V1_H +#define LIBOPENCM3_CORDIC_COMMON_V1_H + +/** @defgroup cordic_registers CORDIC registers +@{*/ +/* ----- CORDIC registers ----- */ +/** CORDIC control/status register */ +#define CORDIC_CSR MMIO32(CORDIC_BASE + 0x00) +/** CORDIC argument register */ +#define CORDIC_WDATA MMIO32(CORDIC_BASE + 0x04) +/** CORDIC result register */ +#define CORDIC_RDATA MMIO32(CORDIC_BASE + 0x08) +/**@}*/ + +/* ----- Register values ----- */ + +/* ----- CORDIC_CSR Values ----- */ +/** @defgroup cordic_csr CSR CORDIC control/status register +@{*/ +/** RRDY: result ready flag */ +#define CORDIC_CSR_RRDY (0x1 << 31) +/** ARGSIZE: Width of input data */ +#define CORDIC_CSR_ARGSIZE (0x1 << 22) +/** RESSIZE: Width of result data */ +#define CORDIC_CSR_RESSIZE (0x1 << 21) +/** NARGS: Number of input data writes */ +#define CORDIC_CSR_NARGS (0x1 << 20) +/** NRES: Number of result data reads */ +#define CORDIC_CSR_NRES (0x1 << 19) +/** DMAWEN: DMA write enable */ +#define CORDIC_CSR_DMAWEN (0x1 << 18) +/** DMAREN: DMA write enable */ +#define CORDIC_CSR_DMAREN (0x1 << 17) +/** DMAREN: Interrupt enable */ +#define CORDIC_CSR_IEN (0x1 << 16) + +/** @defgroup cordic_csr_scale SCALE: Scaling factor +@{*/ +#define CORDIC_CSR_SCALE_1 (0x0) +#define CORDIC_CSR_SCALE_2 (0x1) +#define CORDIC_CSR_SCALE_4 (0x2) +#define CORDIC_CSR_SCALE_8 (0x3) +#define CORDIC_CSR_SCALE_16 (0x4) +#define CORDIC_CSR_SCALE_32 (0x5) +#define CORDIC_CSR_SCALE_64 (0x6) +#define CORDIC_CSR_SCALE_128 (0x7) +/**@}*/ +#define CORDIC_CSR_SCALE_SHIFT (8) +#define CORDIC_CSR_SCALE_MASK (0x7 << CORDIC_CSR_SCALE_SHIFT) + +/** @defgroup cordic_csr_precision PRECISION: Precision of CORDIC operation (number of iterations) +@{*/ +#define CORDIC_CSR_PRECISION_ITER_04 (0x1) +#define CORDIC_CSR_PRECISION_ITER_08 (0x2) +#define CORDIC_CSR_PRECISION_ITER_12 (0x3) +#define CORDIC_CSR_PRECISION_ITER_16 (0x4) +#define CORDIC_CSR_PRECISION_ITER_20 (0x5) +#define CORDIC_CSR_PRECISION_ITER_24 (0x6) +#define CORDIC_CSR_PRECISION_ITER_28 (0x7) +#define CORDIC_CSR_PRECISION_ITER_32 (0x8) +#define CORDIC_CSR_PRECISION_ITER_36 (0x9) +#define CORDIC_CSR_PRECISION_ITER_40 (0xA) +#define CORDIC_CSR_PRECISION_ITER_44 (0xB) +#define CORDIC_CSR_PRECISION_ITER_48 (0xC) +#define CORDIC_CSR_PRECISION_ITER_52 (0xD) +#define CORDIC_CSR_PRECISION_ITER_56 (0xE) +#define CORDIC_CSR_PRECISION_ITER_60 (0xF) +/**@}*/ +#define CORDIC_CSR_PRECISION_SHIFT (4) +#define CORDIC_CSR_PRECISION_MASK (0xF << CORDIC_CSR_PRECISION_SHIFT) + +/** @defgroup cordic_csr_function FUNCTION: CORDIC operation to be performed +@{*/ +#define CORDIC_CSR_FUNC_COS (0x0) +#define CORDIC_CSR_FUNC_SIN (0x1) +#define CORDIC_CSR_FUNC_PHASE (0x2) +#define CORDIC_CSR_FUNC_MODULUS (0x3) +#define CORDIC_CSR_FUNC_ATAN (0x4) +#define CORDIC_CSR_FUNC_COSH (0x5) +#define CORDIC_CSR_FUNC_SINH (0x6) +#define CORDIC_CSR_FUNC_ATANH (0x7) +#define CORDIC_CSR_FUNC_COSINE (0x8) +#define CORDIC_CSR_FUNC_SQRT (0x9) +/**@}*/ +#define CORDIC_CSR_FUNC_SHIFT (0) +#define CORDIC_CSR_FUNC_MASK (0xF << CORDIC_CSR_FUNC_SHIFT) + +/**@}*/ + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +bool cordic_is_result_ready(void); +void cordic_set_argument_width_32bit(void); +void cordic_set_argument_width_16bit(void); +void cordic_set_result_width_32bit(void); +void cordic_set_result_width_16bit(void); +void cordic_set_number_of_arguments_1(void); +void cordic_set_number_of_arguments_2(void); +void cordic_set_number_of_results_1(void); +void cordic_set_number_of_results_2(void); +void cordic_enable_dma_write(void); +void cordic_disable_dma_write(void); +void cordic_enable_dma_read(void); +void cordic_disable_dma_read(void); +void cordic_enable_interrupt(void); +void cordic_set_scaling_factor(uint8_t n); +void cordic_set_precision(uint8_t precision); +void cordic_set_function(uint8_t function); +void cordic_write_16bit_argument(uint16_t argument); +void cordic_write_16bit_arguments(uint16_t argument1, uint16_t argument2); +void cordic_write_32bit_argument(uint32_t argument); +uint16_t cordic_read_16bit_result(void); +void cordic_read_16bit_results(uint16_t *result1, uint16_t *result2); +uint32_t cordic_read_32bit_result(void); +void cordic_configure_for_cos_16bit(void); +void cordic_configure_for_cos_32bit(void); +void cordic_configure_for_sin_16bit(void); +void cordic_configure_for_sin_32bit(void); +int16_t cordic_cos_16bit(int16_t x); +int32_t cordic_cos_32bit(int32_t x); +int16_t cordic_sin_16bit(int16_t x); +int32_t cordic_sin_32bit(int32_t x); +void cordic_cos_16bit_async(int16_t x); +void cordic_cos_32bit_async(int32_t x); +void cordic_sin_16bit_async(int16_t x); +void cordic_sin_32bit_async(int32_t x); +END_DECLS + +#endif +/** @cond */ +#endif +/** @endcond */ +/**@}*/ diff --git a/include/libopencm3/stm32/cordic.h b/include/libopencm3/stm32/cordic.h new file mode 100644 index 00000000..335b22af --- /dev/null +++ b/include/libopencm3/stm32/cordic.h @@ -0,0 +1,29 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +#if defined(STM32G4) +# include +#elif defined(STM32U5) +# include +#else +# error "stm32 family not defined." +#endif diff --git a/include/libopencm3/stm32/g4/cordic.h b/include/libopencm3/stm32/g4/cordic.h new file mode 100644 index 00000000..449d7477 --- /dev/null +++ b/include/libopencm3/stm32/g4/cordic.h @@ -0,0 +1,34 @@ +/** @defgroup cordic_defines CORDIC Defines + * + * @brief Defined Constants and Types for the STM32G4xx CORDIC + * + * @ingroup STM32G4xx_defines + * + * @version 1.0.0 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CORDIC_H +#define LIBOPENCM3_CORDIC_H + +#include + +#endif diff --git a/lib/stm32/common/cordic_common_v1.c b/lib/stm32/common/cordic_common_v1.c new file mode 100644 index 00000000..53266b16 --- /dev/null +++ b/lib/stm32/common/cordic_common_v1.c @@ -0,0 +1,486 @@ +/** @addtogroup cordic_file CORDIC peripheral API +@ingroup peripheral_apis + +@author @htmlonly © @endhtmlonly +2022 Oskar H. Maier + +This library supports the CORDIC co-processor in the STM32 series of +ARM Cortex Microcontrollers by ST Microelectronics. This peripheral +computes trigonometric and hyperbolic functions and converts between +cartesian and polar coordinates. + + + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2022 Oskar H. Maier + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + + +/** @brief Read CORDIC result ready flag + * + * This flag is set by hardware when a CORDIC operation completes. + * It is automatically cleared when all results have been read. + * + * @returns Result ready flag. + */ +bool cordic_is_result_ready(void) { + return CORDIC_CSR & CORDIC_CSR_RRDY; +} + +/** @brief Set CORDIC to 32 bit argument data width. + * + * When configured this way, argument(s) are expected with 32 bit width. + * Two write operations are required for operations with two arguments. + * + */ +void cordic_set_argument_width_32bit(void) { + CORDIC_CSR &= ~CORDIC_CSR_ARGSIZE; +} + +/** @brief Set CORDIC to 16 bit argument data width. + * + * When configured this way, argument(s) are expected with 16 bit width. + * Only one 32 bit write operation is required even for operations with two arguments + * (in this case lower 16 bits contain argument 1, higher 16 bits contain argument 2). + * + */ +void cordic_set_argument_width_16bit(void) { + CORDIC_CSR |= CORDIC_CSR_ARGSIZE; +} + +/** @brief Set CORDIC to 32 bit result data width. + * + * When configured this way, results(s) are written with 32 bit width. + * Two read operations are required for operations with two results. + * + */ +void cordic_set_result_width_32bit(void) { + CORDIC_CSR &= ~CORDIC_CSR_RESSIZE; +} + +/** @brief Set CORDIC to 16 bit result data width. + * + * When configured this way, results are written with 16 bit width. + * Only one 32 bit read operation is required even for operations with two results + * (in this case lower 16 bits contain result 1, higher 16 bits contain result 2). + * + */ +void cordic_set_result_width_16bit(void) { + CORDIC_CSR |= CORDIC_CSR_RESSIZE; +} + +/** @brief Set number of CORDIC arguments to one 32 bit argument or two 16 bit arguments. + * + * Use this option for CORDIC operations with only one argument and CORDIC operations + * with two 16 bit arguments. In this case the operation is triggered + * as soon as one 32bit write to the CORDIC_WDATA register occurred. + * + */ +void cordic_set_number_of_arguments_1(void) { + CORDIC_CSR &= ~CORDIC_CSR_NARGS; +} + +/** @brief Set number of CORDIC arguments to two 32 bit arguments. + * + * Use this option for CORDIC operations with two 32 bit arguments. + * In this case the operation is triggered as soon as two 32bit + * writes to the CORDIC_WDATA register occurred. + * + */ +void cordic_set_number_of_arguments_2(void) { + CORDIC_CSR |= CORDIC_CSR_NARGS; +} + +/** @brief Set number of CORDIC results to one 32 bit result or two 16 bit results. + * + * Use this option for CORDIC operations with only one result and CORDIC operations + * with two 16 bit results. In this case the result ready flag is cleared and a new operation + * can be started as soon as one 32bit read from the CORDIC_RDATA register occurred. + * + */ +void cordic_set_number_of_results_1(void) { + CORDIC_CSR &= ~CORDIC_CSR_NRES; +} + +/** @brief Set number of CORDIC results to two 32 bit results. + * + * Use this option for CORDIC operations with two 32 bit results. + * In this case the result ready flag is cleared and a new operation can be started + * as soon as two 32 bit reads from the CORDIC_RDATA register occurred. + * + */ +void cordic_set_number_of_results_2(void) { + CORDIC_CSR |= CORDIC_CSR_NRES; +} + +/** @brief Enable DMA for writes to CORDIC_WDATA + * + * When enabled, the peripheral will continue to generate DMA requests + * when new arguments can be loaded into the CORDIC_WDATA register. + * + */ +void cordic_enable_dma_write(void) { + CORDIC_CSR |= CORDIC_CSR_DMAWEN; +} + +/** @brief Disable DMA for writes to CORDIC_WDATA + * + * When disabled, the peripheral will not generate DMA requests + * when new arguments can be loaded into the CORDIC_WDATA register. + * + */ +void cordic_disable_dma_write(void) { + CORDIC_CSR &= ~CORDIC_CSR_DMAWEN; +} + +/** @brief Enable DMA for read from CORDIC_RDATA + * + * When enabled, the peripheral will continue to generate DMA requests + * when new results can be read from the CORDIC_RDATA register. + * + */ +void cordic_enable_dma_read(void) { + CORDIC_CSR |= CORDIC_CSR_DMAREN; +} + +/** @brief Disable DMA for read from CORDIC_RDATA + * + * When disabled, the peripheral will not generate DMA requests + * when new results can be read from the CORDIC_RDATA register. + * + */ +void cordic_disable_dma_read(void) { + CORDIC_CSR &= ~CORDIC_CSR_DMAREN; +} + +/** @brief Enable interrupt when result is ready + * + * When enabled, the peripheral will generate an interrupt + * when the CORDIC_CSR_RRDY flag is set. + * + */ +void cordic_enable_interrupt(void) { + CORDIC_CSR |= CORDIC_CSR_IEN; +} + +/** @brief Set scaling factor for CORDIC operations + * + * For some operations, the arguments can be multiplied by a factor of 2^-n + * to fit in the argument range. The result must then be multiplied by 2^n. + * @param[in] n scaling factor of type @ref cordic_csr_scale + * + */ +void cordic_set_scaling_factor(uint8_t n) { + CORDIC_CSR = (CORDIC_CSR & ~CORDIC_CSR_SCALE_MASK) | (n << CORDIC_CSR_SCALE_SHIFT); +} + +/** @brief Set precision for CORDIC operations + * + * The speed of CORDIC operations can be increased by lowering the + * number of iterations. This will decrease precision. + * @param[in] precision precision of type @ref cordic_csr_precision + * + */ +void cordic_set_precision(uint8_t precision) { + CORDIC_CSR = (CORDIC_CSR & ~CORDIC_CSR_PRECISION_MASK) | (precision << CORDIC_CSR_PRECISION_SHIFT); +} + +/** @brief Set CORDIC operation type + * + * Select what operation the CORDIC peripheral performs. + * @param[in] function function of type @ref cordic_csr_function + * + */ +void cordic_set_function(uint8_t function) { + CORDIC_CSR = (CORDIC_CSR & ~CORDIC_CSR_FUNC_MASK) | (function << CORDIC_CSR_FUNC_SHIFT); +} + +/** @brief Write single 16 bit argument + * + * Use this function to set one single 16 bit argument. + * The upper 16 bit of the 32 bit result register + * (that is the second argument) will be set to zero. + * @param[in] argument argument + * + */ +void cordic_write_16bit_argument(uint16_t argument) { + CORDIC_WDATA = argument; +} + +/** @brief Write two 16 bit arguments + * + * Use this function to set write 16 bit arguments to the 32 bit CORDIC_WDATA register. + * @param[in] argument1 argument1 + * @param[in] argument2 argument2 + * + */ +void cordic_write_16bit_arguments(uint16_t argument1, uint16_t argument2) { + CORDIC_WDATA = argument2 << 16 | argument1; +} + +/** @brief Write single 32 bit argument + * + * Use this function to write a 32 bit argument to the CORDIC_WDATA register. + * If the operation needs two arguments call cordic_set_number_of_arguments_2() + * before and then use this function twice to write both arguments. + * @param[in] argument argument + * + */ +void cordic_write_32bit_argument(uint32_t argument) { + CORDIC_WDATA = argument; +} + +/** @brief Read single 16 bit result + * + * Use this function to read one single 16 bit result contained + * in the lower 16 bit of the CORDIC_RDATA register. + * @returns result + * + */ +uint16_t cordic_read_16bit_result(void) { + return CORDIC_RDATA; +} + +/** @brief Read two 16 bit results + * + * Use this function to read both 16 bit results contained + * in the 32 bit CORDIC_RDATA register. + * @param[out] result1 First result is written to this address + * @param[out] result2 Second result is written to this address + * + */ +void cordic_read_16bit_results(uint16_t *result1, uint16_t *result2) { + uint32_t temp = CORDIC_RDATA; + *result1 = temp; + *result2 = temp >> 16; +} + +/** @brief Read 32 bit result + * + * Use this function to read the 32 bit CORDIC_RDATA register. + * @returns result + * + */ +uint32_t cordic_read_32bit_result(void) { + return CORDIC_RDATA; +} + +/** @brief Configure cordic for 16 bit cosine + * + * Configures cordic peripheral to perform 16 bit cosine operation without triggering it + * + */ +void cordic_configure_for_cos_16bit(void) { + cordic_set_function(CORDIC_CSR_FUNC_COS); + cordic_set_precision(CORDIC_CSR_PRECISION_ITER_20); + cordic_set_argument_width_16bit(); + cordic_set_result_width_16bit(); + cordic_set_number_of_arguments_1(); + cordic_set_number_of_results_1(); + /* scale is not applicable for cos */ +} + +/** @brief Configure cordic for 32 bit cosine + * + * Configures cordic peripheral to perform 32 bit cosine operation without triggering it + * + */ +void cordic_configure_for_cos_32bit(void) { + cordic_set_function(CORDIC_CSR_FUNC_COS); + cordic_set_precision(CORDIC_CSR_PRECISION_ITER_28); + cordic_set_argument_width_32bit(); + cordic_set_result_width_32bit(); + cordic_set_number_of_arguments_1(); + cordic_set_number_of_results_1(); + /* scale is not applicable for cos */ +} + +/** @brief Configure cordic for 16 bit sine + * + * Configures cordic peripheral to perform 16 bit sine operation without triggering it + * + */ +void cordic_configure_for_sin_16bit(void) { + cordic_set_function(CORDIC_CSR_FUNC_SIN); + cordic_set_precision(CORDIC_CSR_PRECISION_ITER_20); + cordic_set_argument_width_16bit(); + cordic_set_result_width_16bit(); + cordic_set_number_of_arguments_1(); + cordic_set_number_of_results_1(); + /* scale is not applicable for sin */ +} + +/** @brief Configure cordic for 32 bit sine + * + * Configures cordic peripheral to perform 32 bit sine operation without triggering it + * + */ +void cordic_configure_for_sin_32bit(void) { + cordic_set_function(CORDIC_CSR_FUNC_SIN); + cordic_set_precision(CORDIC_CSR_PRECISION_ITER_28); + cordic_set_argument_width_32bit(); + cordic_set_result_width_32bit(); + cordic_set_number_of_arguments_1(); + cordic_set_number_of_results_1(); + /* scale is not applicable for sin */ +} + +/** @brief Compute 16 bit cosine using CORDIC (blocking) + * + * Convenience function to calculate 32767*cos(x/32767*pi). + * This implementation can be sped up in most applications by configuring the peripheral only once + * and then trigger subsequent operations by writing new arguments to the CORDIC_WDATA register. + * Additionally, sine and cosine are always computed in a single operation. + * Read the second result to obtain the other value. + * @param[in] x argument + * @returns result + * + */ +int16_t cordic_cos_16bit(int16_t x) { + cordic_configure_for_cos_16bit(); + cordic_write_16bit_arguments((uint16_t) x, 0x7FFF); + + /* this while loop can be omitted but that will stall the + processor while it waits for the CORDIC_RDATA register */ + while(!cordic_is_result_ready()); + + return cordic_read_16bit_result(); +} + +/** @brief Compute 16 bit cosine using CORDIC (non blocking) + * + * Convenience function to calculate 32767*cos(x/32767*pi). + * Result can be obtained from result register using cordic_read_16bit_result(). + * + * @param[in] x argument + * + */ +void cordic_cos_16bit_async(int16_t x) { + cordic_configure_for_cos_16bit(); + cordic_write_16bit_arguments((uint16_t) x, 0x7FFF); +} + +/** @brief Compute 32 bit cosine using CORDIC (blocking) + * + * Convenience function to calculate 2147483647*cos(x/2147483647*pi). + * This implementation can be sped up in most applications by configuring the peripheral only once + * and then trigger subsequent operations by writing new arguments to the CORDIC_WDATA register. + * Additionally, sine and cosine are always computed in a single operation. + * Read the second result to obtain the other value. + * @param[in] x argument + * @returns result + * + */ +int32_t cordic_cos_32bit(int32_t x) { + cordic_configure_for_cos_32bit(); + cordic_write_32bit_argument((uint32_t) x); + + while(!cordic_is_result_ready()); + + return cordic_read_32bit_result(); +} + +/** @brief Compute 32 bit cosine using CORDIC (non blocking) + * + * Convenience function to calculate 2147483647*cos(x/2147483647*pi). + * Result can be obtained from result register using cordic_read_32bit_result(). + * + * @param[in] x argument + * + */ +void cordic_cos_32bit_async(int32_t x) { + cordic_configure_for_cos_32bit(); + cordic_write_32bit_argument((uint32_t) x); +} + +/** @brief Compute 16 bit sine using CORDIC (blocking) + * + * Convenience function to calculate 32767*sin(x/32767*pi). + * This implementation can be sped up in most applications by configuring the peripheral only once + * and then trigger subsequent operations by writing new arguments to the CORDIC_WDATA register. + * Additionally, sine and cosine are always computed in a single operation. + * Read the second result to obtain the other value. + * @param[in] x argument + * @returns result + * + */ +int16_t cordic_sin_16bit(int16_t x) { + cordic_configure_for_sin_16bit(); + cordic_write_16bit_arguments((uint16_t) x, 0x7FFF); + + /* this while loop can be omitted but that will stall the + processor while it waits for the CORDIC_RDATA register */ + while(!cordic_is_result_ready()); + + return cordic_read_16bit_result(); +} + +/** @brief Compute 16 bit sine using CORDIC (non blocking) + * + * Convenience function to calculate 32767*sin(x/32767*pi). + * Result can be obtained from result register using cordic_read_16bit_result(). + * + * @param[in] x argument + * + */ +void cordic_sin_16bit_async(int16_t x) { + cordic_configure_for_sin_16bit(); + cordic_write_16bit_arguments((uint16_t) x, 0x7FFF); +} + +/** @brief Compute 32 bit sine using CORDIC (blocking) + * + * Convenience function to calculate 2147483647*sin(x/2147483647*pi). + * This implementation can be sped up in most applications by configuring the peripheral only once + * and then trigger subsequent operations by writing new arguments to the CORDIC_WDATA register. + * Additionally, sine and cosine are always computed in a single operation. + * Read the second result to obtain the other value. + * @param[in] x argument + * @returns result + * + */ +int32_t cordic_sin_32bit(int32_t x) { + cordic_configure_for_sin_32bit(); + cordic_write_32bit_argument((uint32_t) x); + + /* this while loop can be omitted but that will stall the + processor while it waits for the CORDIC_RDATA register */ + while(!cordic_is_result_ready()); + + return cordic_read_32bit_result(); +} + +/** @brief Compute 32 bit sine using CORDIC (non blocking) + * + * Convenience function to calculate 2147483647*sin(x/2147483647*pi). + * Result can be obtained from result register using cordic_read_32bit_result(). + * + * @param[in] x argument + * + */ +void cordic_sin_32bit_async(int32_t x) { + cordic_configure_for_sin_32bit(); + cordic_write_32bit_argument((uint32_t) x); +} diff --git a/lib/stm32/g4/Makefile b/lib/stm32/g4/Makefile index bcb3166b..c6924130 100644 --- a/lib/stm32/g4/Makefile +++ b/lib/stm32/g4/Makefile @@ -36,6 +36,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o +OBJS += cordic_common_v1.o OBJS += crs_common_all.o OBJS += crc_common_all.o crc_v2.o OBJS += dac_common_all.o dac_common_v2.o From 5db7e87e6e5e2d8ba08e651be9117d36c710ae50 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 27 Oct 2022 21:36:29 +0000 Subject: [PATCH 165/206] doxygen: stm32:cordic: add a title --- lib/stm32/common/cordic_common_v1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/stm32/common/cordic_common_v1.c b/lib/stm32/common/cordic_common_v1.c index 53266b16..89c27d57 100644 --- a/lib/stm32/common/cordic_common_v1.c +++ b/lib/stm32/common/cordic_common_v1.c @@ -1,6 +1,7 @@ /** @addtogroup cordic_file CORDIC peripheral API @ingroup peripheral_apis +@brief HW accelerated maths trig/hyperbolic operations. @author @htmlonly © @endhtmlonly 2022 Oskar H. Maier From 0b414ff64977c8b06ddd90fd80813d94bcd03110 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 27 Oct 2022 21:56:50 +0000 Subject: [PATCH 166/206] stm32g0: adc: only clear desired flags in ADC_ISR Verified against RM0444rev5. Fixes: https://github.com/libopencm3/libopencm3/issues/1443 Signed-off-by: Karl Palsson --- lib/stm32/g0/adc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/stm32/g0/adc.c b/lib/stm32/g0/adc.c index 7d4d1c93..73fb0dbf 100644 --- a/lib/stm32/g0/adc.c +++ b/lib/stm32/g0/adc.c @@ -160,24 +160,24 @@ void adc_set_regular_sequence(uint32_t adc, uint8_t length, uint8_t channel[]) /* Setup scandir, if needed, waiting for configuration be applied.. */ if (stepdn && (!(ADC_CFGR1(adc) & ADC_CFGR1_SCANDIR))) { - ADC_ISR(adc) &= ~ADC_ISR_CCRDY; + ADC_ISR(adc) = ADC_ISR_CCRDY; ADC_CFGR1(adc) |= ADC_CFGR1_SCANDIR; while (!(ADC_ISR(adc) & ADC_ISR_CCRDY)); } else if (stepup && ((ADC_CFGR1(adc) & ADC_CFGR1_SCANDIR))) { - ADC_ISR(adc) &= ~ADC_ISR_CCRDY; + ADC_ISR(adc) = ADC_ISR_CCRDY; ADC_CFGR1(adc) &= ~ADC_CFGR1_SCANDIR; while (!(ADC_ISR(adc) & ADC_ISR_CCRDY)); } /* Setup ADC in simple, not configurable, mode, if needed. */ if ((ADC_CFGR1(adc) & ADC_CFGR1_CHSELRMOD)) { - ADC_ISR(adc) &= ~ADC_ISR_CCRDY; + ADC_ISR(adc) = ADC_ISR_CCRDY; ADC_CFGR1(adc) &= ~ADC_CFGR1_CHSELRMOD; while (!(ADC_ISR(adc) & ADC_ISR_CCRDY)); } if (ADC_CHSELR(adc) != reg32) { - ADC_ISR(adc) &= ~ADC_ISR_CCRDY; + ADC_ISR(adc) = ADC_ISR_CCRDY; ADC_CHSELR(adc) = reg32; while (!(ADC_ISR(adc) & ADC_ISR_CCRDY)); } From e1ec3e4e185c7169e0c2f298fd7641e2ef9fc7c1 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 7 Nov 2022 14:37:30 +0000 Subject: [PATCH 167/206] stm32: rcc: clarify flash_prefetch_enable documentation It's not globally enabled by default, and it has consumption impacts as well. Reported on IRC. --- include/libopencm3/stm32/common/flash_common_all.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/libopencm3/stm32/common/flash_common_all.h b/include/libopencm3/stm32/common/flash_common_all.h index ad7b5560..acbfcb97 100644 --- a/include/libopencm3/stm32/common/flash_common_all.h +++ b/include/libopencm3/stm32/common/flash_common_all.h @@ -25,14 +25,18 @@ BEGIN_DECLS /** - * This buffer is used for instruction fetches and is enabled by default after - * reset. + * This buffer is used for instruction fetches and may or may not be + * enabled by default, depending on platform. (F1: yes, most others: no) * * Note carefully the clock restrictions under which the prefetch buffer may be * enabled or disabled. Changes are normally made while the clock is running in * the power-on low frequency mode before being set to a higher speed mode. * - * See the reference manual for details. + * Note carefully that prefetch may also results in increased consumption + * and can only improve performance on "mostly linear" workloads where there + * is at least one flash wait state. + * + * See the reference manual for your particular target for more details. */ void flash_prefetch_enable(void); From 7c09d0d14c99d5be56436a3864038212812bcd2a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 17 Nov 2022 21:15:47 +0000 Subject: [PATCH 168/206] stm32f3: enable RTC Fixes: https://github.com/libopencm3/libopencm3/issues/1446 Fixes: 18f4d7c1b7 stm32f3: rtc: include correct shared header No testing on real hardware, but the docs imply that this should have always had the "basic" rtc-v2 peripheral. Signed-off-by: Karl Palsson --- include/libopencm3/stm32/f3/rtc.h | 4 ++-- lib/stm32/f3/Makefile | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/libopencm3/stm32/f3/rtc.h b/include/libopencm3/stm32/f3/rtc.h index b7cbbb4d..1899a4ad 100644 --- a/include/libopencm3/stm32/f3/rtc.h +++ b/include/libopencm3/stm32/f3/rtc.h @@ -32,8 +32,8 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_RTC_F3_H -#define LIBOPENCM3_RTC_F3_H +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H #include diff --git a/lib/stm32/f3/Makefile b/lib/stm32/f3/Makefile index f4e471cb..359dc743 100644 --- a/lib/stm32/f3/Makefile +++ b/lib/stm32/f3/Makefile @@ -49,6 +49,7 @@ OBJS += iwdg_common_all.o OBJS += opamp_common_all.o opamp_common_v1.o OBJS += pwr_common_v1.o OBJS += rcc.o rcc_common_all.o +OBJS += rtc_common_l1f024.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o timer_common_f0234.o OBJS += usart_common_v2.o usart_common_all.o From de96f0f4aa6269a5c8337e7ef6027755d3919c9c Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 29 Nov 2022 14:10:03 +0000 Subject: [PATCH 169/206] stm32g0: adc: fix setting sampling time on all channels Fixes: https://github.com/libopencm3/libopencm3/issues/1448 Signed-off-by: Karl Palsson --- lib/stm32/g0/adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stm32/g0/adc.c b/lib/stm32/g0/adc.c index 73fb0dbf..fea1b8be 100644 --- a/lib/stm32/g0/adc.c +++ b/lib/stm32/g0/adc.c @@ -69,7 +69,7 @@ void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time) reg32 = ADC_SMPR1(adc); /* set all channels on ADC_SMPR_SMPSEL_SMP1 first @ref adc_smpr_smpsel sample time selection, and clear its value */ - reg32 &= ~((ADC_SMPR_SMPSEL_MASK << ADC_SMPR_SMP1_SHIFT) | (ADC_SMPR_SMP1_MASK << ADC_SMPR_SMP1_SHIFT)); + reg32 &= ~((ADC_SMPR_SMPSEL_MASK << ADC_SMPR_SMPSEL_SHIFT) | (ADC_SMPR_SMP1_MASK << ADC_SMPR_SMP1_SHIFT)); /* setup ADC_SMPR_SMPSEL_SMP1 sample time */ reg32 |= (time << ADC_SMPR_SMP1_SHIFT); ADC_SMPR1(adc) = reg32; From 84a59d925dfd1d28754f7bff57033feba5f91909 Mon Sep 17 00:00:00 2001 From: Sebastien Lorquet Date: Thu, 5 Jan 2023 12:13:23 +0100 Subject: [PATCH 170/206] devices.data: stm32h7: fix fpu and mem offsets Filed via: https://github.com/libopencm3/libopencm3/pull/1451 We've decided that the 1 based numbering is saner, and should be the new norm going forwards, even though SAM3 and LPC both use zero based numbering. Reviewed-by: Karl Palsson --- ld/devices.data | 2 +- mk/genlink-config.mk | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ld/devices.data b/ld/devices.data index 8dc1e6d7..57729c05 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -593,7 +593,7 @@ stm32l1 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft stm32l4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 RAM2_OFF=0x10000000 RAM3_OFF=0x20040000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 stm32g0 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m0plus FPU=soft stm32g4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16 -stm32h7 END ROM_OFF=0x08000000 ROM1_OFF=0x08100000 RAM_OFF=0x24000000 RAM1_OFF=0x30000000 RAM2_OFF=0x30020000 RAM3_OFF=0x30040000 RAM4_OFF=0x38000000 CCM_OFF=0x20000000 CPU=cortex-m7 FPU=hard-fpv5-d16 +stm32h7 END ROM_OFF=0x08000000 ROM2_OFF=0x08100000 RAM_OFF=0x24000000 RAM2_OFF=0x30000000 RAM3_OFF=0x30020000 RAM4_OFF=0x30040000 RAM5_OFF=0x38000000 CCM_OFF=0x20000000 CPU=cortex-m7 FPU=hard-fpv5-d16 stm32w END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft stm32t END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft diff --git a/mk/genlink-config.mk b/mk/genlink-config.mk index 4686fe6d..3f323611 100644 --- a/mk/genlink-config.mk +++ b/mk/genlink-config.mk @@ -41,6 +41,8 @@ ifeq ($(genlink_fpu),soft) ARCH_FLAGS += -msoft-float else ifeq ($(genlink_fpu),hard-fpv4-sp-d16) ARCH_FLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 +else ifeq ($(genlink_fpu),hard-fpv5-d16) +ARCH_FLAGS += -mfloat-abi=hard -mfpu=fpv5-d16 else ifeq ($(genlink_fpu),hard-fpv5-sp-d16) ARCH_FLAGS += -mfloat-abi=hard -mfpu=fpv5-sp-d16 else From 5796f41caaa7352cdd7c171d2876d230ef2cd25d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 13 Jan 2023 00:33:34 +0000 Subject: [PATCH 171/206] [BREAKING] stm32g0: add/rename missing periphs/irqs Updated to RM0444_rev5 Breaking: renames some irqs to be more specific and better match with refman. We're still in the "between" tags, so break all the toys! Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g0/irq.json | 14 +++++++------- include/libopencm3/stm32/g0/memorymap.h | 18 ++++++++++++++++-- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/libopencm3/stm32/g0/irq.json b/include/libopencm3/stm32/g0/irq.json index aa43cbc1..7a7fc52b 100644 --- a/include/libopencm3/stm32/g0/irq.json +++ b/include/libopencm3/stm32/g0/irq.json @@ -16,20 +16,20 @@ "tim1_brk_up_trg_com", "tim1_cc", "tim2", - "tim3", + "tim34", "tim6_dac_lptim1", "tim7_lptim2", "tim14", "tim15", - "tim16", - "tim17", + "tim16_fdcan_it0", + "tim17_fdcan_it1", "i2c1", - "i2c2", + "i2c23", "spi1", - "spi2", + "spi23", "usart1", - "usart2", - "usart3_usart4_lpuart1", + "usart2_lpuart2", + "usart3456_lpuart1", "cec", "aes_rng" ], diff --git a/include/libopencm3/stm32/g0/memorymap.h b/include/libopencm3/stm32/g0/memorymap.h index 1bf07989..40845624 100644 --- a/include/libopencm3/stm32/g0/memorymap.h +++ b/include/libopencm3/stm32/g0/memorymap.h @@ -30,6 +30,7 @@ /* APB */ #define TIM2_BASE (PERIPH_BASE_APB + 0x0000) #define TIM3_BASE (PERIPH_BASE_APB + 0x0400) +#define TIM4_BASE (PERIPH_BASE_APB + 0x0800) #define TIM6_BASE (PERIPH_BASE_APB + 0x1000) #define TIM7_BASE (PERIPH_BASE_APB + 0x1400) #define TIM14_BASE (PERIPH_BASE_APB + 0x2000) @@ -37,28 +38,40 @@ #define WWDG_BASE (PERIPH_BASE_APB + 0x2c00) #define IWDG_BASE (PERIPH_BASE_APB + 0x3000) #define SPI2_BASE (PERIPH_BASE_APB + 0x3800) +#define SPI3_BASE (PERIPH_BASE_APB + 0x3c00) #define USART2_BASE (PERIPH_BASE_APB + 0x4400) #define USART3_BASE (PERIPH_BASE_APB + 0x4800) #define USART4_BASE (PERIPH_BASE_APB + 0x4C00) +#define USART5_BASE (PERIPH_BASE_APB + 0x5000) #define I2C1_BASE (PERIPH_BASE_APB + 0x5400) #define I2C2_BASE (PERIPH_BASE_APB + 0x5800) +#define USB_BASE (PERIPH_BASE_APB + 0x5c00) +#define FDCAN1_BASE (PERIPH_BASE_APB + 0x6400) +#define FDCAN2_BASE (PERIPH_BASE_APB + 0x6800) +#define CRS_BASE (PERIPH_BASE_APB + 0x6c00) #define POWER_CONTROL_BASE (PERIPH_BASE_APB + 0x7000) #define DAC_BASE (PERIPH_BASE_APB + 0x7400) #define CEC_BASE (PERIPH_BASE_APB + 0x7800) #define LPTIM1_BASE (PERIPH_BASE_APB + 0x7c00) #define LPUART1_BASE (PERIPH_BASE_APB + 0x8000) +#define LPUART2_BASE (PERIPH_BASE_APB + 0x8400) +#define I2C3_BASE (PERIPH_BASE_APB + 0x8800) #define LPTIM2_BASE (PERIPH_BASE_APB + 0x9400) +#define USB_RAM1_BASE (PERIPH_BASE_APB + 0x9800) +#define USB_RAM2_BASE (PERIPH_BASE_APB + 0x9c00) #define UCPD1_BASE (PERIPH_BASE_APB + 0xA000) #define UCPD2_BASE (PERIPH_BASE_APB + 0xA400) #define TAMP_BASE (PERIPH_BASE_APB + 0xB000) +#define FDCANMSG_BASE (PERIPH_BASE_APB + 0xB400) #define SYSCFG_BASE (PERIPH_BASE_APB + 0x10000) -#define VREFBUF_BASE (PERIPH_BASE_APB + 0x10030) -#define SYSCFG_ITLINE_BASE (PERIPH_BASE_APB + 0x10080) +#define VREFBUF_BASE (PERIPH_BASE_APB + 0x10030) +#define SYSCFG_ITLINE_BASE (PERIPH_BASE_APB + 0x10080) #define COMP_BASE (PERIPH_BASE_APB + 0x10200) #define ADC1_BASE (PERIPH_BASE_APB + 0x12400) #define TIM1_BASE (PERIPH_BASE_APB + 0x12C00) #define SPI1_BASE (PERIPH_BASE_APB + 0x13000) #define USART1_BASE (PERIPH_BASE_APB + 0x13800) +#define USART6_BASE (PERIPH_BASE_APB + 0x13c00) #define TIM15_BASE (PERIPH_BASE_APB + 0x14000) #define TIM16_BASE (PERIPH_BASE_APB + 0x14400) #define TIM17_BASE (PERIPH_BASE_APB + 0x14800) @@ -66,6 +79,7 @@ /* AHB */ #define DMA1_BASE (PERIPH_BASE_AHB + 0x00000) +#define DMA2_BASE (PERIPH_BASE_AHB + 0x00400) #define DMAMUX_BASE (PERIPH_BASE_AHB + 0x00800) #define RCC_BASE (PERIPH_BASE_AHB + 0x01000) #define EXTI_BASE (PERIPH_BASE_AHB + 0x01800) From 2c180d84315cd242a3913614f36653ff43d94abb Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 13 Jan 2023 02:04:18 +0000 Subject: [PATCH 172/206] stm32g0: rcc: add missing periphs A bunch of periphs on newer parts weren't defined. Add their enable/reset bit definitions so they can be used. Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g0/rcc.h | 65 ++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/include/libopencm3/stm32/g0/rcc.h b/include/libopencm3/stm32/g0/rcc.h index 40441ee1..c67e8983 100644 --- a/include/libopencm3/stm32/g0/rcc.h +++ b/include/libopencm3/stm32/g0/rcc.h @@ -305,7 +305,9 @@ #define RCC_AHBRSTR_AESRST (1 << 16) #define RCC_AHBRSTR_CRCRST (1 << 12) #define RCC_AHBRSTR_FLASHRST (1 << 8) -#define RCC_AHBRSTR_DMARST (1 << 0) +#define RCC_AHBRSTR_DMA2RST (1 << 1) +#define RCC_AHBRSTR_DMA1RST (1 << 0) +#define RCC_AHBRSTR_DMARST RCC_AHBRSTR_DMA1RST /**@}*/ /** @defgroup rcc_apb1rstr_rst RCC_APBRSTRx reset values (full set) @@ -319,15 +321,25 @@ #define RCC_APBRSTR1_DBGRST (1 << 27) #define RCC_APBRSTR1_UCPD2RST (1 << 26) #define RCC_APBRSTR1_UCPD1RST (1 << 25) +#define RCC_APBRSTR1_CECRST (1 << 24) +#define RCC_APBRSTR1_I2C3RST (1 << 23) #define RCC_APBRSTR1_I2C2RST (1 << 22) #define RCC_APBRSTR1_I2C1RST (1 << 21) #define RCC_APBRSTR1_LPUART1RST (1 << 20) #define RCC_APBRSTR1_USART4RST (1 << 19) #define RCC_APBRSTR1_USART3RST (1 << 18) #define RCC_APBRSTR1_USART2RST (1 << 17) +#define RCC_APBRSTR1_CRSRST (1 << 16) +#define RCC_APBRSTR1_SPI3RST (1 << 15) #define RCC_APBRSTR1_SPI2RST (1 << 14) +#define RCC_APBRSTR1_USBRST (1 << 13) +#define RCC_APBRSTR1_FDCANRST (1 << 12) +#define RCC_APBRSTR1_USART6RST (1 << 9) +#define RCC_APBRSTR1_USART5RST (1 << 8) +#define RCC_APBRSTR1_LPUART2RST (1 << 7) #define RCC_APBRSTR1_TIM7RST (1 << 5) #define RCC_APBRSTR1_TIM6RST (1 << 4) +#define RCC_APBRSTR1_TIM4RST (1 << 2) #define RCC_APBRSTR1_TIM3RST (1 << 1) #define RCC_APBRSTR1_TIM2RST (1 << 0) /**@}*/ @@ -337,7 +349,6 @@ #define RCC_APBRSTR2_ADCRST (1 << 20) #define RCC_APBRSTR2_TIM17RST (1 << 18) #define RCC_APBRSTR2_TIM16RST (1 << 17) -#define RCC_APBRSTR2_TIM16RST (1 << 17) #define RCC_APBRSTR2_TIM15RST (1 << 16) #define RCC_APBRSTR2_TIM14RST (1 << 15) #define RCC_APBRSTR2_USART1RST (1 << 14) @@ -353,7 +364,9 @@ #define RCC_AHBENR_AESEN (1 << 16) #define RCC_AHBENR_CRCEN (1 << 12) #define RCC_AHBENR_FLASHEN (1 << 8) -#define RCC_AHBENR_DMAEN (1 << 0) +#define RCC_AHBENR_DMA2EN (1 << 1) +#define RCC_AHBENR_DMA1EN (1 << 0) +#define RCC_AHBENR_DMAEN RCC_AHBENR_DMA1EN /**@}*/ /** @defgroup rcc_apb1enr_en RCC_APBENRx enable values (full set) @@ -652,8 +665,9 @@ enum rcc_periph_clken { RCC_AES = _REG_BIT(RCC_AHBENR_OFFSET, 16), RCC_CRC = _REG_BIT(RCC_AHBENR_OFFSET, 12), RCC_FLASH = _REG_BIT(RCC_AHBENR_OFFSET, 8), - RCC_DMA = _REG_BIT(RCC_AHBENR_OFFSET, 0), - RCC_DMA1 = _REG_BIT(RCC_AHBENR_OFFSET, 0), /* Compatibility */ + RCC_DMA2 = _REG_BIT(RCC_AHBENR_OFFSET, 1), + RCC_DMA1 = _REG_BIT(RCC_AHBENR_OFFSET, 0), + RCC_DMA = _REG_BIT(RCC_AHBENR_OFFSET, 0), /* Compatibility */ RCC_LPTIM1 = _REG_BIT(RCC_APBENR1_OFFSET, 31), RCC_LPTIM2 = _REG_BIT(RCC_APBENR1_OFFSET, 30), @@ -663,15 +677,26 @@ enum rcc_periph_clken { RCC_UCPD2 = _REG_BIT(RCC_APBENR1_OFFSET, 26), RCC_UCPD1 = _REG_BIT(RCC_APBENR1_OFFSET, 25), RCC_CEC = _REG_BIT(RCC_APBENR1_OFFSET, 24), + RCC_I2C3 = _REG_BIT(RCC_APBENR1_OFFSET, 23), RCC_I2C2 = _REG_BIT(RCC_APBENR1_OFFSET, 22), RCC_I2C1 = _REG_BIT(RCC_APBENR1_OFFSET, 21), RCC_LPUART1 = _REG_BIT(RCC_APBENR1_OFFSET, 20), RCC_USART4 = _REG_BIT(RCC_APBENR1_OFFSET, 19), RCC_USART3 = _REG_BIT(RCC_APBENR1_OFFSET, 18), RCC_USART2 = _REG_BIT(RCC_APBENR1_OFFSET, 17), + RCC_CRS = _REG_BIT(RCC_APBENR1_OFFSET, 16), + RCC_SPI3 = _REG_BIT(RCC_APBENR1_OFFSET, 15), RCC_SPI2 = _REG_BIT(RCC_APBENR1_OFFSET, 14), + RCC_USB = _REG_BIT(RCC_APBENR1_OFFSET, 13), + RCC_FDCAN = _REG_BIT(RCC_APBENR1_OFFSET, 12), + RCC_WWDG = _REG_BIT(RCC_APBENR1_OFFSET, 11), + RCC_RTCAPB = _REG_BIT(RCC_APBENR1_OFFSET, 10), + RCC_USART6 = _REG_BIT(RCC_APBENR1_OFFSET, 9), + RCC_USART5 = _REG_BIT(RCC_APBENR1_OFFSET, 8), + RCC_LPUART2 = _REG_BIT(RCC_APBENR1_OFFSET, 7), RCC_TIM7 = _REG_BIT(RCC_APBENR1_OFFSET, 5), RCC_TIM6 = _REG_BIT(RCC_APBENR1_OFFSET, 4), + RCC_TIM4 = _REG_BIT(RCC_APBENR1_OFFSET, 2), RCC_TIM3 = _REG_BIT(RCC_APBENR1_OFFSET, 1), RCC_TIM2 = _REG_BIT(RCC_APBENR1_OFFSET, 0), @@ -695,9 +720,11 @@ enum rcc_periph_clken { SCC_RNG = _REG_BIT(RCC_AHBSMENR_OFFSET, 18), SCC_AES = _REG_BIT(RCC_AHBSMENR_OFFSET, 16), SCC_CRC = _REG_BIT(RCC_AHBSMENR_OFFSET, 12), + SCC_SRAM = _REG_BIT(RCC_AHBSMENR_OFFSET, 9), SCC_FLASH = _REG_BIT(RCC_AHBSMENR_OFFSET, 8), - SCC_DMA = _REG_BIT(RCC_AHBSMENR_OFFSET, 0), - SCC_DMA1 = _REG_BIT(RCC_AHBSMENR_OFFSET, 0), /* Compatibility */ + SCC_DMA2 = _REG_BIT(RCC_AHBSMENR_OFFSET, 1), + SCC_DMA1 = _REG_BIT(RCC_AHBSMENR_OFFSET, 0), + SCC_DMA = _REG_BIT(RCC_AHBSMENR_OFFSET, 0), /* Compatibility */ SCC_LPTIM1 = _REG_BIT(RCC_APBSMENR1_OFFSET, 31), SCC_LPTIM2 = _REG_BIT(RCC_APBSMENR1_OFFSET, 30), @@ -707,13 +734,23 @@ enum rcc_periph_clken { SCC_UCPD2 = _REG_BIT(RCC_APBSMENR1_OFFSET, 26), SCC_UCPD1 = _REG_BIT(RCC_APBSMENR1_OFFSET, 25), SCC_CEC = _REG_BIT(RCC_APBSMENR1_OFFSET, 24), + SCC_I2C3 = _REG_BIT(RCC_APBSMENR1_OFFSET, 23), SCC_I2C2 = _REG_BIT(RCC_APBSMENR1_OFFSET, 22), SCC_I2C1 = _REG_BIT(RCC_APBSMENR1_OFFSET, 21), SCC_LPUART1 = _REG_BIT(RCC_APBSMENR1_OFFSET, 20), SCC_USART4 = _REG_BIT(RCC_APBSMENR1_OFFSET, 19), SCC_USART3 = _REG_BIT(RCC_APBSMENR1_OFFSET, 18), SCC_USART2 = _REG_BIT(RCC_APBSMENR1_OFFSET, 17), + SCC_CRS = _REG_BIT(RCC_APBSMENR1_OFFSET, 16), + SCC_SPI3 = _REG_BIT(RCC_APBSMENR1_OFFSET, 15), SCC_SPI2 = _REG_BIT(RCC_APBSMENR1_OFFSET, 14), + SCC_USB = _REG_BIT(RCC_APBSMENR1_OFFSET, 13), + SCC_FDCAN = _REG_BIT(RCC_APBSMENR1_OFFSET, 12), + SCC_WWDG = _REG_BIT(RCC_APBSMENR1_OFFSET, 11), + SCC_RTCAPB = _REG_BIT(RCC_APBSMENR1_OFFSET, 10), + SCC_USART6 = _REG_BIT(RCC_APBSMENR1_OFFSET, 9), + SCC_USART5 = _REG_BIT(RCC_APBSMENR1_OFFSET, 8), + SCC_LPUART2 = _REG_BIT(RCC_APBSMENR1_OFFSET, 7), SCC_TIM7 = _REG_BIT(RCC_APBSMENR1_OFFSET, 5), SCC_TIM6 = _REG_BIT(RCC_APBSMENR1_OFFSET, 4), SCC_TIM3 = _REG_BIT(RCC_APBSMENR1_OFFSET, 1), @@ -742,8 +779,9 @@ enum rcc_periph_rst { RST_AES = _REG_BIT(RCC_AHBRSTR_OFFSET, 16), RST_CRC = _REG_BIT(RCC_AHBRSTR_OFFSET, 12), RST_FLASH = _REG_BIT(RCC_AHBRSTR_OFFSET, 8), - RST_DMA = _REG_BIT(RCC_AHBRSTR_OFFSET, 0), - RST_DMA1 = _REG_BIT(RCC_AHBRSTR_OFFSET, 0), /* Compatibility */ + RST_DMA2 = _REG_BIT(RCC_AHBRSTR_OFFSET, 1), + RST_DMA1 = _REG_BIT(RCC_AHBRSTR_OFFSET, 0), + RST_DMA = _REG_BIT(RCC_AHBRSTR_OFFSET, 0), /* Compatibility */ RST_LPTIM1 = _REG_BIT(RCC_APBRSTR1_OFFSET, 31), RST_LPTIM2 = _REG_BIT(RCC_APBRSTR1_OFFSET, 30), @@ -753,15 +791,24 @@ enum rcc_periph_rst { RST_UCPD2 = _REG_BIT(RCC_APBRSTR1_OFFSET, 26), RST_UCPD1 = _REG_BIT(RCC_APBRSTR1_OFFSET, 25), RST_CEC = _REG_BIT(RCC_APBRSTR1_OFFSET, 24), + RST_I2C3 = _REG_BIT(RCC_APBRSTR1_OFFSET, 23), RST_I2C2 = _REG_BIT(RCC_APBRSTR1_OFFSET, 22), RST_I2C1 = _REG_BIT(RCC_APBRSTR1_OFFSET, 21), RST_LPUART1 = _REG_BIT(RCC_APBRSTR1_OFFSET, 20), RST_USART4 = _REG_BIT(RCC_APBRSTR1_OFFSET, 19), RST_USART3 = _REG_BIT(RCC_APBRSTR1_OFFSET, 18), RST_USART2 = _REG_BIT(RCC_APBRSTR1_OFFSET, 17), + RST_CRS = _REG_BIT(RCC_APBRSTR1_OFFSET, 16), + RST_SPI3 = _REG_BIT(RCC_APBRSTR1_OFFSET, 15), RST_SPI2 = _REG_BIT(RCC_APBRSTR1_OFFSET, 14), + RST_USB = _REG_BIT(RCC_APBRSTR1_OFFSET, 13), + RST_FDCAN = _REG_BIT(RCC_APBRSTR1_OFFSET, 12), + RST_USART6 = _REG_BIT(RCC_APBRSTR1_OFFSET, 9), + RST_USART5 = _REG_BIT(RCC_APBRSTR1_OFFSET, 8), + RST_LPUART2 = _REG_BIT(RCC_APBRSTR1_OFFSET, 7), RST_TIM7 = _REG_BIT(RCC_APBRSTR1_OFFSET, 5), RST_TIM6 = _REG_BIT(RCC_APBRSTR1_OFFSET, 4), + RST_TIM4 = _REG_BIT(RCC_APBRSTR1_OFFSET, 2), RST_TIM3 = _REG_BIT(RCC_APBRSTR1_OFFSET, 1), RST_TIM2 = _REG_BIT(RCC_APBRSTR1_OFFSET, 0), From b3bdf025d76dbc65d3ab33db15f67af0505722a1 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 13 Jan 2023 01:37:41 +0000 Subject: [PATCH 173/206] stm32: i2c: drop i2c_reset() It's simply a wrapper around rcc_reset_pulse already. Just drop it. See 034dbf20ff8c54dcbe for the same deletion for timers. Signed-off-by: Karl Palsson --- .../libopencm3/stm32/common/i2c_common_v1.h | 1 - .../libopencm3/stm32/common/i2c_common_v2.h | 1 - lib/stm32/common/i2c_common_v1.c | 34 ------------------ lib/stm32/common/i2c_common_v2.c | 36 ------------------- 4 files changed, 72 deletions(-) diff --git a/include/libopencm3/stm32/common/i2c_common_v1.h b/include/libopencm3/stm32/common/i2c_common_v1.h index 8e62324b..5d37a7c2 100644 --- a/include/libopencm3/stm32/common/i2c_common_v1.h +++ b/include/libopencm3/stm32/common/i2c_common_v1.h @@ -385,7 +385,6 @@ enum i2c_speeds { BEGIN_DECLS -void i2c_reset(uint32_t i2c); void i2c_peripheral_enable(uint32_t i2c); void i2c_peripheral_disable(uint32_t i2c); void i2c_send_start(uint32_t i2c); diff --git a/include/libopencm3/stm32/common/i2c_common_v2.h b/include/libopencm3/stm32/common/i2c_common_v2.h index 316d0f1e..725ccf64 100644 --- a/include/libopencm3/stm32/common/i2c_common_v2.h +++ b/include/libopencm3/stm32/common/i2c_common_v2.h @@ -402,7 +402,6 @@ enum i2c_speeds { BEGIN_DECLS -void i2c_reset(uint32_t i2c); void i2c_peripheral_enable(uint32_t i2c); void i2c_peripheral_disable(uint32_t i2c); void i2c_send_start(uint32_t i2c); diff --git a/lib/stm32/common/i2c_common_v1.c b/lib/stm32/common/i2c_common_v1.c index 59f75886..ea3db68e 100644 --- a/lib/stm32/common/i2c_common_v1.c +++ b/lib/stm32/common/i2c_common_v1.c @@ -41,40 +41,6 @@ register access, Error conditions /**@{*/ -/*---------------------------------------------------------------------------*/ -/** @brief I2C Reset. - -The I2C peripheral and all its associated configuration registers are placed in -the reset condition. The reset is effected via the RCC peripheral reset system. - -@param[in] i2c Unsigned int32. I2C peripheral identifier @ref i2c_reg_base. -*/ - -void i2c_reset(uint32_t i2c) -{ - switch (i2c) { - case I2C1: - rcc_periph_reset_pulse(RST_I2C1); - break; -#if defined(I2C2_BASE) - case I2C2: - rcc_periph_reset_pulse(RST_I2C2); - break; -#endif -#if defined(I2C3_BASE) - case I2C3: - rcc_periph_reset_pulse(RST_I2C3); - break; -#endif -#if defined(I2C4_BASE) - case I2C4: - rcc_periph_reset_pulse(RST_I2C4); - break; -#endif - default: - break; - } -} /*---------------------------------------------------------------------------*/ /** @brief I2C Peripheral Enable. diff --git a/lib/stm32/common/i2c_common_v2.c b/lib/stm32/common/i2c_common_v2.c index 426219c6..301c9d55 100644 --- a/lib/stm32/common/i2c_common_v2.c +++ b/lib/stm32/common/i2c_common_v2.c @@ -24,42 +24,6 @@ /**@{*/ -/*---------------------------------------------------------------------------*/ -/** @brief I2C Reset. - * - * The I2C peripheral and all its associated configuration registers are placed - * in the reset condition. The reset is effected via the RCC peripheral reset - * system. - * - * @param[in] i2c Unsigned int32. I2C peripheral identifier @ref i2c_reg_base. - */ - -void i2c_reset(uint32_t i2c) -{ - switch (i2c) { - case I2C1: - rcc_periph_reset_pulse(RST_I2C1); - break; -#if defined(I2C2_BASE) - case I2C2: - rcc_periph_reset_pulse(RST_I2C2); - break; -#endif -#if defined(I2C3_BASE) - case I2C3: - rcc_periph_reset_pulse(RST_I2C3); - break; -#endif -#if defined(I2C4_BASE) - case I2C4: - rcc_periph_reset_pulse(RST_I2C4); - break; -#endif - default: - break; - } -} - /*---------------------------------------------------------------------------*/ /** @brief I2C Peripheral Enable. * From df654d7f28365217822078a0f13a7eb7b6d7b7cb Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 13 Jan 2023 01:42:35 +0000 Subject: [PATCH 174/206] stm32: spi: drop spi_reset() It's simply a wrapper around rcc_reset_pulse already. Just drop it. See 034dbf20ff8c54dcbe for the same deletion for timers. Signed-off-by: Karl Palsson --- .../libopencm3/stm32/common/spi_common_all.h | 1 - lib/stm32/common/spi_common_all.c | 47 ------------------- 2 files changed, 48 deletions(-) diff --git a/include/libopencm3/stm32/common/spi_common_all.h b/include/libopencm3/stm32/common/spi_common_all.h index da19e627..319b8c6f 100644 --- a/include/libopencm3/stm32/common/spi_common_all.h +++ b/include/libopencm3/stm32/common/spi_common_all.h @@ -344,7 +344,6 @@ specific memorymap.h header before including this header file.*/ BEGIN_DECLS -void spi_reset(uint32_t spi_peripheral); void spi_enable(uint32_t spi); void spi_disable(uint32_t spi); uint16_t spi_clean_disable(uint32_t spi); diff --git a/lib/stm32/common/spi_common_all.c b/lib/stm32/common/spi_common_all.c index cc9b60ad..10fcd58e 100644 --- a/lib/stm32/common/spi_common_all.c +++ b/lib/stm32/common/spi_common_all.c @@ -56,53 +56,6 @@ LSB first. /**@{*/ -/*---------------------------------------------------------------------------*/ -/** @brief SPI Reset. - -The SPI peripheral and all its associated configuration registers are placed in -the reset condition. The reset is effected via the RCC peripheral reset system. - -@param[in] spi_peripheral Unsigned int32. SPI peripheral identifier @ref -spi_reg_base. -*/ - -void spi_reset(uint32_t spi_peripheral) -{ switch (spi_peripheral) { -#if defined(SPI1_BASE) - case SPI1_BASE: - rcc_periph_reset_pulse(RST_SPI1); - break; -#endif -#if defined(SPI2_BASE) - case SPI2_BASE: - rcc_periph_reset_pulse(RST_SPI2); - break; -#endif -#if defined(SPI3_BASE) - case SPI3_BASE: - rcc_periph_reset_pulse(RST_SPI3); - break; -#endif -#if defined(SPI4_BASE) - case SPI4_BASE: - rcc_periph_reset_pulse(RST_SPI4); - break; -#endif -#if defined(SPI5_BASE) - case SPI5_BASE: - rcc_periph_reset_pulse(RST_SPI5); - break; -#endif -#if defined(SPI6_BASE) - case SPI6_BASE: - rcc_periph_reset_pulse(RST_SPI6); - break; -#endif - default: - break; - } -} - /* TODO: Error handling? */ /*---------------------------------------------------------------------------*/ /** @brief SPI Enable. From 88e91c9a7cced8096c53fb942dcff1d7bdf6c91b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 13 Jan 2023 02:06:34 +0000 Subject: [PATCH 175/206] stm32:rcc: update _get_clock (uart/i2c) to handle all cases Adds handling for missing cases. While i2c only has 3 cases, uarts have all 4, so make sure they're handled properly. Removes duplicated/redundant definitions. Adds doxygen wrappers, even if only for internal use. Fixes: e41ac6ea711c86f stm32: added peripheral clock get helpers for all stm32 Signed-of-by: Karl Palsson --- include/libopencm3/stm32/f0/rcc.h | 38 ++++++++----------- include/libopencm3/stm32/f3/rcc.h | 39 +++++++------------ include/libopencm3/stm32/f7/rcc.h | 33 ++++++++-------- include/libopencm3/stm32/g0/rcc.h | 45 ++++++++++------------ include/libopencm3/stm32/l0/rcc.h | 62 ++++++++++++++++++------------- lib/stm32/f0/rcc.c | 14 ++++--- lib/stm32/f3/rcc.c | 14 ++++--- lib/stm32/f7/rcc.c | 20 +++++----- lib/stm32/g0/rcc.c | 34 ++++++++++------- lib/stm32/h7/rcc.c | 16 +++++--- lib/stm32/l0/rcc.c | 28 +++++++------- 11 files changed, 175 insertions(+), 168 deletions(-) diff --git a/include/libopencm3/stm32/f0/rcc.h b/include/libopencm3/stm32/f0/rcc.h index ea5b4062..f795272e 100644 --- a/include/libopencm3/stm32/f0/rcc.h +++ b/include/libopencm3/stm32/f0/rcc.h @@ -385,36 +385,30 @@ Control /**@}*/ /* --- RCC_CFGR3 values ---------------------------------------------------- */ +/** @defgroup rcc_cfgr3_uart_choices UART for clock source selecting + * @note This is only used internally. + * @{ + */ #define RCC_CFGR3_USART3SW_SHIFT 18 -#define RCC_CFGR3_USART3SW (3 << RCC_CFGR3_USART2SW_SHIFT) -#define RCC_CFGR3_USART3SW_PCLK (0 << RCC_CFGR3_USART2SW_SHIFT) -#define RCC_CFGR3_USART3SW_SYSCLK (1 << RCC_CFGR3_USART2SW_SHIFT) -#define RCC_CFGR3_USART3SW_LSE (2 << RCC_CFGR3_USART2SW_SHIFT) -#define RCC_CFGR3_USART3SW_HSI (3 << RCC_CFGR3_USART2SW_SHIFT) - #define RCC_CFGR3_USART2SW_SHIFT 16 -#define RCC_CFGR3_USART2SW (3 << RCC_CFGR3_USART2SW_SHIFT) -#define RCC_CFGR3_USART2SW_PCLK (0 << RCC_CFGR3_USART2SW_SHIFT) -#define RCC_CFGR3_USART2SW_SYSCLK (1 << RCC_CFGR3_USART2SW_SHIFT) -#define RCC_CFGR3_USART2SW_LSE (2 << RCC_CFGR3_USART2SW_SHIFT) -#define RCC_CFGR3_USART2SW_HSI (3 << RCC_CFGR3_USART2SW_SHIFT) +#define RCC_CFGR3_USART1SW_SHIFT 0 +/**@}*/ + +/** @defgroup rcc_cfgr3_uart_clksel UART Clock source selections + * @{ + */ +#define RCC_CFGR3_USARTxSW_PCLK 0x0 +#define RCC_CFGR3_USARTxSW_SYSCLK 0x1 +#define RCC_CFGR3_USARTxSW_LSE 0x2 +#define RCC_CFGR3_USARTxSW_HSI 0x3 +/**@}*/ +#define RCC_CFGR3_USARTxSW_MASK 0x3 #define RCC_CFGR3_ADCSW (1 << 8) #define RCC_CFGR3_USBSW (1 << 7) #define RCC_CFGR3_CECSW (1 << 6) #define RCC_CFGR3_I2C1SW (1 << 4) -#define RCC_CFGR3_USART1SW_SHIFT 0 -#define RCC_CFGR3_USART1SW (3 << RCC_CFGR3_USART1SW_SHIFT) -#define RCC_CFGR3_USART1SW_PCLK (0 << RCC_CFGR3_USART1SW_SHIFT) -#define RCC_CFGR3_USART1SW_SYSCLK (1 << RCC_CFGR3_USART1SW_SHIFT) -#define RCC_CFGR3_USART1SW_LSE (2 << RCC_CFGR3_USART1SW_SHIFT) -#define RCC_CFGR3_USART1SW_HSI (3 << RCC_CFGR3_USART1SW_SHIFT) - -#define RCC_CFGR3_USARTxSW_MASK 3 - -/* --- RCC_CFGR3 values ---------------------------------------------------- */ - #define RCC_CR2_HSI48CAL_SHIFT 24 #define RCC_CR2_HSI48CAL (0xFF << RCC_CR2_HSI48CAL_SHIFT) #define RCC_CR2_HSI48RDY (1 << 17) diff --git a/include/libopencm3/stm32/f3/rcc.h b/include/libopencm3/stm32/f3/rcc.h index e7839437..1a7a6e0c 100644 --- a/include/libopencm3/stm32/f3/rcc.h +++ b/include/libopencm3/stm32/f3/rcc.h @@ -405,36 +405,25 @@ #define RCC_CFGR3_TIM1SW (1 << 8) #define RCC_CFGR3_I2C2SW (1 << 5) #define RCC_CFGR3_I2C1SW (1 << 4) -/* UART5SW: UART5 clock source selection */ +/** @defgroup rcc_cfgr3_uart_choices UART for clock sour selecting + * @{ + */ #define RCC_CFGR3_UART5SW_SHIFT 22 -#define RCC_CFGR3_UART5SW_PCLK 0x0 -#define RCC_CFGR3_UART5SW_SYSCLK 0x1 -#define RCC_CFGR3_UART5SW_LSE 0x2 -#define RCC_CFGR3_UART5SW_HSI 0x3 -/* UART4SW: UART4 clock source selection */ #define RCC_CFGR3_UART4SW_SHIFT 20 -#define RCC_CFGR3_UART4SW_PCLK 0x0 -#define RCC_CFGR3_UART4SW_SYSCLK 0x1 -#define RCC_CFGR3_UART4SW_LSE 0x2 -#define RCC_CFGR3_UART4SW_HSI 0x3 -/* UART3SW: UART3 clock source selection */ #define RCC_CFGR3_UART3SW_SHIFT 18 -#define RCC_CFGR3_UART3SW_PCLK 0x0 -#define RCC_CFGR3_UART3SW_SYSCLK 0x1 -#define RCC_CFGR3_UART3SW_LSE 0x2 -#define RCC_CFGR3_UART3SW_HSI 0x3 -/* UART2SW: UART2 clock source selection */ #define RCC_CFGR3_UART2SW_SHIFT 16 -#define RCC_CFGR3_UART2SW_PCLK 0x0 -#define RCC_CFGR3_UART2SW_SYSCLK 0x1 -#define RCC_CFGR3_UART2SW_LSE 0x2 -#define RCC_CFGR3_UART2SW_HSI 0x3 -/* UART1SW: UART1 clock source selection */ #define RCC_CFGR3_UART1SW_SHIFT 0 -#define RCC_CFGR3_UART1SW_PCLK 0x0 -#define RCC_CFGR3_UART1SW_SYSCLK 0x1 -#define RCC_CFGR3_UART1SW_LSE 0x2 -#define RCC_CFGR3_UART1SW_HSI 0x3 +/**@}*/ + +/** @defgroup rcc_cfgr3_uart_clksel UART Clock source selections + * @note This is only used internally. + * @{ + */ +#define RCC_CFGR3_UARTxSW_PCLK 0x0 +#define RCC_CFGR3_UARTxSW_SYSCLK 0x1 +#define RCC_CFGR3_UARTxSW_LSE 0x2 +#define RCC_CFGR3_UARTxSW_HSI 0x3 +/**@}*/ /* Shared mask for UART clock source. */ #define RCC_CFGR3_UARTxSW_MASK 0x3 diff --git a/include/libopencm3/stm32/f7/rcc.h b/include/libopencm3/stm32/f7/rcc.h index 2f3bcc73..06e48786 100644 --- a/include/libopencm3/stm32/f7/rcc.h +++ b/include/libopencm3/stm32/f7/rcc.h @@ -622,33 +622,36 @@ #define RCC_DCKCFGR2_CECSEL (1<<26) #define RCC_DCKCFGR2_LPTIM1SEL_MASK 0x3 #define RCC_DCKCFGR2_LPTIM1SEL_SHIFT 24 -#define RCC_DCKCFGR2_I2C4SEL_MASK 0x3 +#define RCC_DCKCFGR2_I2CxSEL_MASK 0x3 #define RCC_DCKCFGR2_I2C4SEL_SHIFT 22 -#define RCC_DCKCFGR2_I2C3SEL_MASK 0x3 #define RCC_DCKCFGR2_I2C3SEL_SHIFT 20 -#define RCC_DCKCFGR2_I2C2SEL_MASK 0x3 #define RCC_DCKCFGR2_I2C2SEL_SHIFT 18 -#define RCC_DCKCFGR2_I2C1SEL_MASK 0x3 #define RCC_DCKCFGR2_I2C1SEL_SHIFT 16 -#define RCC_DCKCFGR2_UART8SEL_MASK 0x3 + +#define RCC_DCKCFGR2_UARTxSEL_MASK 0x3 +/** @defgroup rcc_dckcfgr2_uart_choices UART for clock source selecting + * @note This is only used internally. + * @{ + */ #define RCC_DCKCFGR2_UART8SEL_SHIFT 14 -#define RCC_DCKCFGR2_UART7SEL_MASK 0x3 #define RCC_DCKCFGR2_UART7SEL_SHIFT 12 -#define RCC_DCKCFGR2_USART6SEL_MASK 0x3 #define RCC_DCKCFGR2_USART6SEL_SHIFT 10 -#define RCC_DCKCFGR2_UART5SEL_MASK 0x3 #define RCC_DCKCFGR2_UART5SEL_SHIFT 8 -#define RCC_DCKCFGR2_UART4SEL_MASK 0x3 #define RCC_DCKCFGR2_UART4SEL_SHIFT 6 -#define RCC_DCKCFGR2_UART3SEL_MASK 0x3 #define RCC_DCKCFGR2_UART3SEL_SHIFT 4 -#define RCC_DCKCFGR2_UART2SEL_MASK 0x3 #define RCC_DCKCFGR2_UART2SEL_SHIFT 2 -#define RCC_DCKCFGR2_UART1SEL_MASK 0x3 #define RCC_DCKCFGR2_UART1SEL_SHIFT 0 -#define RCC_DCKCFGR2_UARTxSEL_PCLK 0 -#define RCC_DCKCFGR2_UARTxSEL_SYSCLK 1 -#define RCC_DCKCFGR2_UARTxSEL_HSI 2 +/**@}*/ + +/** @defgroup rcc_dckcfgr2_uart_clksel UART Clock source selections + * @{ + */ +#define RCC_DCKCFGR2_UARTxSEL_PCLK 0x0 +#define RCC_DCKCFGR2_UARTxSEL_SYSCLK 0x1 +#define RCC_DCKCFGR2_UARTxSEL_HSI 0x2 +#define RCC_DCKCFGR2_UARTxSEL_LSE 0x3 +/**@}*/ + extern uint32_t rcc_ahb_frequency; diff --git a/include/libopencm3/stm32/g0/rcc.h b/include/libopencm3/stm32/g0/rcc.h index c67e8983..4081ce5b 100644 --- a/include/libopencm3/stm32/g0/rcc.h +++ b/include/libopencm3/stm32/g0/rcc.h @@ -537,23 +537,25 @@ #define RCC_CCIPR_I2S1SEL_I2S_CKIN 3 /**@}*/ -#define RCC_CCIPR_I2C1SEL_MASK 0x3 +#define RCC_CCIPR_I2CxSEL_MASK 0x3 #define RCC_CCIPR_I2C1SEL_SHIFT 12 +#define RCC_CCIPR_I2C2SEL_SHIFT 14 /** @defgroup rcc_ccipr_i2c1sel I2C1SEL I2C1 Clock source selection @{*/ -#define RCC_CCIPR_I2C1SEL_PCLK 0 -#define RCC_CCIPR_I2C1SEL_SYSCLK 1 -#define RCC_CCIPR_I2C1SEL_HSI16 2 +#define RCC_CCIPR_I2CxSEL_PCLK 0 +#define RCC_CCIPR_I2CxSEL_SYSCLK 1 +#define RCC_CCIPR_I2CxSEL_HSI16 2 /**@}*/ -#define RCC_CCIPR_LPUART1SEL_MASK 0x3 +#define RCC_CCIPR_LPUARTxSEL_MASK 0x3 #define RCC_CCIPR_LPUART1SEL_SHIFT 10 -/** @defgroup rcc_ccipr_lpuart1sel LPUART1SEL LPUART1 Clock source selection +#define RCC_CCIPR_LPUART2SEL_SHIFT 8 +/** @defgroup rcc_ccipr_lpuartxsel LPUARTxSEL LPUART1 Clock source selection @{*/ -#define RCC_CCIPR_LPUART1SEL_PCLK 0 -#define RCC_CCIPR_LPUART1SEL_SYSCLK 1 -#define RCC_CCIPR_LPUART1SEL_HSI16 2 -#define RCC_CCIPR_LPUART1SEL_LSE 3 +#define RCC_CCIPR_LPUARTxSEL_PCLK 0 +#define RCC_CCIPR_LPUARTxSEL_SYSCLK 1 +#define RCC_CCIPR_LPUARTxSEL_HSI16 2 +#define RCC_CCIPR_LPUARTxSEL_LSE 3 /**@}*/ #define RCC_CCIPR_CECSEL_MASK 0x1 @@ -564,25 +566,18 @@ #define RCC_CCIPR_CECSEL_LSE 1 /**@}*/ -#define RCC_CCIPR_USART2SEL_MASK 0x3 +#define RCC_CCIPR_USARTxSEL_MASK RCC_CCIPR_LPUARTxSEL_MASK +#define RCC_CCIPR_USART3SEL_SHIFT 4 #define RCC_CCIPR_USART2SEL_SHIFT 2 -/** @defgroup rcc_ccipr_usart2sel USART2SEL USART2 Clock source selection +#define RCC_CCIPR_USART1SEL_SHIFT 0 +/** @defgroup rcc_ccipr_usartxsel USARTxSEL USARTx Clock source selection @{*/ -#define RCC_CCIPR_USART2SEL_PCLK 0 -#define RCC_CCIPR_USART2SEL_SYSCLK 1 -#define RCC_CCIPR_USART2SEL_HSI16 2 -#define RCC_CCIPR_USART2SEL_LSE 3 +#define RCC_CCIPR_USARTxSEL_PCLK RCC_CCIPR_LPUARTxSEL_PCLK +#define RCC_CCIPR_USARTxSEL_SYSCLK RCC_CCIPR_LPUARTxSEL_SYSCLK +#define RCC_CCIPR_USARTxSEL_HSI16 RCC_CCIPR_LPUARTxSEL_HSI16 +#define RCC_CCIPR_USARTxSEL_LSE RCC_CCIPR_LPUARTxSEL_LSE /**@}*/ -#define RCC_CCIPR_USART1SEL_MASK 0x3 -#define RCC_CCIPR_USART1SEL_SHIFT 0 -/** @defgroup rcc_ccipr_usart1sel USART1SEL USART1 Clock source selection -@{*/ -#define RCC_CCIPR_USART1SEL_PCLK 0 -#define RCC_CCIPR_USART1SEL_SYSCLK 1 -#define RCC_CCIPR_USART1SEL_HSI16 2 -#define RCC_CCIPR_USART1SEL_LSE 3 -/**@}*/ /**@}*/ /** @defgroup rcc_bdcr BDCR Backup Domain Control Register diff --git a/include/libopencm3/stm32/l0/rcc.h b/include/libopencm3/stm32/l0/rcc.h index 6aa9d4b4..e378ee2c 100644 --- a/include/libopencm3/stm32/l0/rcc.h +++ b/include/libopencm3/stm32/l0/rcc.h @@ -443,38 +443,48 @@ #define RCC_CCIPR_LPTIM1SEL_SHIFT 18 #define RCC_CCIPR_LPTIM1SEL_MASK 0x3 -#define RCC_CCIPR_I2C3SEL_APB 0 -#define RCC_CCIPR_I2C3SEL_SYS 1 -#define RCC_CCIPR_I2C3SEL_HSI16 2 +/** @defgroup rcc_ccipr_i2c_clksel I2C Clock source selections + * @{ + */ +#define RCC_CCIPR_I2CxSEL_PCLK 0 +#define RCC_CCIPR_I2CxSEL_SYSCLK 1 +#define RCC_CCIPR_I2CxSEL_HSI 2 +/**@}*/ +#define RCC_CCIPR_I2CxSEL_MASK 0x3 + +/** @defgroup rcc_ccipr_i2c_choices I2C for clock source selecting + * @note This is only used internally. + * @{ + */ #define RCC_CCIPR_I2C3SEL_SHIFT 16 -#define RCC_CCIPR_I2C3SEL_MASK 0x3 - -#define RCC_CCIPR_I2C1SEL_APB 0 -#define RCC_CCIPR_I2C1SEL_SYS 1 -#define RCC_CCIPR_I2C1SEL_HSI16 2 #define RCC_CCIPR_I2C1SEL_SHIFT 12 -#define RCC_CCIPR_I2C1SEL_MASK 0x3 +/**@}*/ -#define RCC_CCIPR_LPUART1SEL_APB 0 -#define RCC_CCIPR_LPUART1SEL_SYS 1 -#define RCC_CCIPR_LPUART1SEL_HSI16 2 -#define RCC_CCIPR_LPUART1SEL_LSE 3 +/** @defgroup rcc_ccipr_uart_clksel UART Clock source selections + * @{ + */ +#define RCC_CCIPR_USARTxSEL_PCLK 0 +#define RCC_CCIPR_USARTxSEL_SYSCLK 1 +#define RCC_CCIPR_USARTxSEL_HSI 2 +#define RCC_CCIPR_USARTxSEL_LSE 3 +/**@}*/ + +#define RCC_CCIPR_LPUARTxSEL_PCLK RCC_CCIPR_USARTxSEL_PCLK +#define RCC_CCIPR_LPUARTxSEL_SYSCK RCC_CCIPR_USARTxSEL_SYSCLK +#define RCC_CCIPR_LPUARTxSEL_HSI RCC_CCIPR_USARTxSEL_HSI +#define RCC_CCIPR_LPUARTxSEL_LSE RCC_CCIPR_USARTxSEL_LSE + +#define RCC_CCIPR_LPUARTxSEL_MASK 0x3 +#define RCC_CCIPR_USARTxSEL_MASK RCC_CCIPR_LPUARTxSEL_MASK + +/** @defgroup rcc_ccipr_uart_choices UART for clock source selecting + * @note This is only used internally. + * @{ + */ #define RCC_CCIPR_LPUART1SEL_SHIFT 10 -#define RCC_CCIPR_LPUART1SEL_MASK 0x3 - -#define RCC_CCIPR_USART2SEL_APB 0 -#define RCC_CCIPR_USART2SEL_SYS 1 -#define RCC_CCIPR_USART2SEL_HSI16 2 -#define RCC_CCIPR_USART2SEL_LSE 3 #define RCC_CCIPR_USART2SEL_SHIFT 2 -#define RCC_CCIPR_USART2SEL_MASK 0x3 - -#define RCC_CCIPR_USART1SEL_APB 0 -#define RCC_CCIPR_USART1SEL_SYS 1 -#define RCC_CCIPR_USART1SEL_HSI16 2 -#define RCC_CCIPR_USART1SEL_LSE 3 #define RCC_CCIPR_USART1SEL_SHIFT 0 -#define RCC_CCIPR_USART1SEL_MASK 0x3 +/**@}*/ /* --- RCC_CSRT - Control/Status register */ diff --git a/lib/stm32/f0/rcc.c b/lib/stm32/f0/rcc.c index 5a679124..19ca3c89 100644 --- a/lib/stm32/f0/rcc.c +++ b/lib/stm32/f0/rcc.c @@ -630,12 +630,14 @@ static uint32_t rcc_get_usart_clksel_freq(uint8_t shift) { uint8_t clksel = (RCC_CFGR3 >> shift) & RCC_CFGR3_USARTxSW_MASK; uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; switch (clksel) { - case RCC_CFGR3_USART1SW_PCLK: - return rcc_apb1_frequency; - case RCC_CFGR3_USART1SW_SYSCLK: - return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); - case RCC_CFGR3_USART1SW_HSI: - return 8000000U; + case RCC_CFGR3_USARTxSW_PCLK: + return rcc_apb1_frequency; + case RCC_CFGR3_USARTxSW_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CFGR3_USARTxSW_LSE: + return 32768; + case RCC_CFGR3_USARTxSW_HSI: + return 8000000U; } cm3_assert_not_reached(); } diff --git a/lib/stm32/f3/rcc.c b/lib/stm32/f3/rcc.c index 831ce263..eeff7ca6 100644 --- a/lib/stm32/f3/rcc.c +++ b/lib/stm32/f3/rcc.c @@ -498,12 +498,14 @@ static uint32_t rcc_get_usart_clksel_freq(uint32_t apb_clk, uint8_t shift) { uint8_t clksel = (RCC_CFGR3 >> shift) & RCC_CFGR3_UARTxSW_MASK; uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; switch (clksel) { - case RCC_CFGR3_UART1SW_PCLK: - return apb_clk; - case RCC_CFGR3_UART1SW_SYSCLK: - return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); - case RCC_CFGR3_UART1SW_HSI: - return 8000000U; + case RCC_CFGR3_UARTxSW_PCLK: + return apb_clk; + case RCC_CFGR3_UARTxSW_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CFGR3_UARTxSW_LSE: + return 32768; + case RCC_CFGR3_UARTxSW_HSI: + return 8000000U; } cm3_assert_not_reached(); } diff --git a/lib/stm32/f7/rcc.c b/lib/stm32/f7/rcc.c index 99a697d4..9324ae10 100644 --- a/lib/stm32/f7/rcc.c +++ b/lib/stm32/f7/rcc.c @@ -485,18 +485,20 @@ void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock) } static uint32_t rcc_usart_i2c_clksel_freq(uint32_t apb_clk, uint8_t shift) { - uint8_t clksel = (RCC_DCKCFGR2 >> shift) & RCC_DCKCFGR2_UART1SEL_MASK; + uint8_t clksel = (RCC_DCKCFGR2 >> shift) & RCC_DCKCFGR2_UARTxSEL_MASK; uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; switch (clksel) { - case RCC_DCKCFGR2_UARTxSEL_PCLK: - return apb_clk; - case RCC_DCKCFGR2_UARTxSEL_SYSCLK: - return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); - case RCC_DCKCFGR2_UARTxSEL_HSI: - return 16000000U; - default: - cm3_assert_not_reached(); + case RCC_DCKCFGR2_UARTxSEL_PCLK: + return apb_clk; + case RCC_DCKCFGR2_UARTxSEL_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + /* This case is only valid for uarts, not for i2c! */ + case RCC_DCKCFGR2_UARTxSEL_LSE: + return 32768; + case RCC_DCKCFGR2_UARTxSEL_HSI: + return 16000000U; } + cm3_assert_not_reached(); } /*---------------------------------------------------------------------------*/ diff --git a/lib/stm32/g0/rcc.c b/lib/stm32/g0/rcc.c index 9e05bb93..edd6da99 100644 --- a/lib/stm32/g0/rcc.c +++ b/lib/stm32/g0/rcc.c @@ -532,11 +532,11 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel) break; case USART2_BASE: shift = RCC_CCIPR_USART2SEL_SHIFT; - mask = RCC_CCIPR_USART2SEL_MASK; + mask = RCC_CCIPR_USARTxSEL_MASK; break; case USART1_BASE: shift = RCC_CCIPR_USART1SEL_SHIFT; - mask = RCC_CCIPR_USART1SEL_MASK; + mask = RCC_CCIPR_USARTxSEL_MASK; break; default: cm3_assert_not_reached(); @@ -548,15 +548,17 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel) } static uint32_t rcc_get_clksel_freq(uint8_t shift) { - uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_USART1SEL_MASK; + uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_USARTxSEL_MASK; uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; switch (clksel) { - case RCC_CCIPR_USART1SEL_PCLK: - return rcc_apb1_frequency; - case RCC_CCIPR_USART1SEL_SYSCLK: - return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); - case RCC_CCIPR_USART1SEL_HSI16: - return 16000000U; + case RCC_CCIPR_USARTxSEL_PCLK: + return rcc_apb1_frequency; + case RCC_CCIPR_USARTxSEL_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CCIPR_USARTxSEL_LSE: + return 32768; + case RCC_CCIPR_USARTxSEL_HSI16: + return 16000000U; } cm3_assert_not_reached(); } @@ -571,11 +573,14 @@ uint32_t rcc_get_usart_clk_freq(uint32_t usart) return rcc_get_clksel_freq(RCC_CCIPR_USART1SEL_SHIFT); } else if (usart == USART2_BASE) { return rcc_get_clksel_freq(RCC_CCIPR_USART2SEL_SHIFT); + } else if (usart == USART3_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_USART3SEL_SHIFT); } else if (usart == LPUART1_BASE) { return rcc_get_clksel_freq(RCC_CCIPR_LPUART1SEL_SHIFT); - } else { - return rcc_apb1_frequency; + } else if (usart == LPUART2_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_LPUART2SEL_SHIFT); } + cm3_assert_not_reached(); } /*---------------------------------------------------------------------------*/ @@ -593,13 +598,14 @@ uint32_t rcc_get_timer_clk_freq(uint32_t timer __attribute__((unused))) /** @brief Get the peripheral clock speed for the I2C device at base specified. * @param i2c Base address of I2C to get clock frequency for. */ -uint32_t rcc_get_i2c_clk_freq(uint32_t i2c __attribute__((unused))) +uint32_t rcc_get_i2c_clk_freq(uint32_t i2c) { if (i2c == I2C1_BASE) { return rcc_get_clksel_freq(RCC_CCIPR_I2C1SEL_SHIFT); - } else { - return rcc_apb1_frequency; + } else if (i2c == I2C2_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_I2C2SEL_SHIFT); } + cm3_assert_not_reached(); } /*---------------------------------------------------------------------------*/ diff --git a/lib/stm32/h7/rcc.c b/lib/stm32/h7/rcc.c index 30f3b4bb..34dbd8c4 100644 --- a/lib/stm32/h7/rcc.c +++ b/lib/stm32/h7/rcc.c @@ -277,17 +277,21 @@ uint32_t rcc_get_usart_clk_freq(uint32_t usart) } /* Based on extracted clksel value, return the clock. */ - if (clksel == RCC_D2CCIP2R_USARTSEL_PCLK) { + switch(clksel) { + case RCC_D2CCIP2R_USARTSEL_PCLK: return pclk; - } else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL2Q) { + case RCC_D2CCIP2R_USARTSEL_PLL2Q: return rcc_clock_tree.pll2.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP2R_USARTSEL_PLL3Q) { + case RCC_D2CCIP2R_USARTSEL_PLL3Q: return rcc_clock_tree.pll3.q_mhz * HZ_PER_MHZ; - } else if (clksel == RCC_D2CCIP2R_USARTSEL_HSI) { + case RCC_D2CCIP2R_USARTSEL_HSI: return RCC_HSI_BASE_FREQUENCY; - } else { - return 0U; + case RCC_D2CCIP2R_USARTSEL_CSI: + return 4000000; + case RCC_D2CCIP2R_USARTSEL_LSE: + return 32768; } + cm3_assert_not_reached(); } uint32_t rcc_get_timer_clk_freq(uint32_t timer __attribute__((unused))) diff --git a/lib/stm32/l0/rcc.c b/lib/stm32/l0/rcc.c index 01e84ac0..1b5632f5 100644 --- a/lib/stm32/l0/rcc.c +++ b/lib/stm32/l0/rcc.c @@ -420,7 +420,7 @@ void rcc_set_lptim1_sel(uint32_t lptim1_sel) */ void rcc_set_lpuart1_sel(uint32_t lpuart1_sel) { - RCC_CCIPR &= ~(RCC_CCIPR_LPUART1SEL_MASK << RCC_CCIPR_LPTIM1SEL_SHIFT); + RCC_CCIPR &= ~(RCC_CCIPR_LPUARTxSEL_MASK << RCC_CCIPR_LPTIM1SEL_SHIFT); RCC_CCIPR |= (lpuart1_sel << RCC_CCIPR_LPTIM1SEL_SHIFT); } @@ -431,7 +431,7 @@ void rcc_set_lpuart1_sel(uint32_t lpuart1_sel) */ void rcc_set_usart1_sel(uint32_t usart1_sel) { - RCC_CCIPR &= ~(RCC_CCIPR_USART1SEL_MASK << RCC_CCIPR_USART1SEL_SHIFT); + RCC_CCIPR &= ~(RCC_CCIPR_USARTxSEL_MASK << RCC_CCIPR_USART1SEL_SHIFT); RCC_CCIPR |= (usart1_sel << RCC_CCIPR_USART1SEL_SHIFT); } @@ -442,7 +442,7 @@ void rcc_set_usart1_sel(uint32_t usart1_sel) */ void rcc_set_usart2_sel(uint32_t usart2_sel) { - RCC_CCIPR &= ~(RCC_CCIPR_USART2SEL_MASK << RCC_CCIPR_USART2SEL_SHIFT); + RCC_CCIPR &= ~(RCC_CCIPR_USARTxSEL_MASK << RCC_CCIPR_USART2SEL_SHIFT); RCC_CCIPR |= (usart2_sel << RCC_CCIPR_USART2SEL_SHIFT); } @@ -464,27 +464,27 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel) case I2C3_BASE: shift = RCC_CCIPR_I2C3SEL_SHIFT; - mask = RCC_CCIPR_I2C3SEL_MASK; + mask = RCC_CCIPR_I2CxSEL_MASK; break; case I2C1_BASE: shift = RCC_CCIPR_I2C1SEL_SHIFT; - mask = RCC_CCIPR_I2C1SEL_MASK; + mask = RCC_CCIPR_I2CxSEL_MASK; break; case LPUART1_BASE: shift = RCC_CCIPR_LPUART1SEL_SHIFT; - mask = RCC_CCIPR_LPUART1SEL_MASK; + mask = RCC_CCIPR_LPUARTxSEL_MASK; break; case USART2_BASE: shift = RCC_CCIPR_USART2SEL_SHIFT; - mask = RCC_CCIPR_USART2SEL_MASK; + mask = RCC_CCIPR_USARTxSEL_MASK; break; case USART1_BASE: shift = RCC_CCIPR_USART1SEL_SHIFT; - mask = RCC_CCIPR_USART1SEL_MASK; + mask = RCC_CCIPR_USARTxSEL_MASK; break; default: @@ -498,14 +498,14 @@ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel) /* Helper to calculate the frequency of a clksel based clock. */ static uint32_t rcc_uart_i2c_clksel_freq_hz(uint32_t apb_clk, uint8_t shift) { - uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_I2C1SEL_MASK; + uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_I2CxSEL_MASK; uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; switch (clksel) { - case RCC_CCIPR_USART1SEL_APB: + case RCC_CCIPR_USARTxSEL_PCLK: return apb_clk; - case RCC_CCIPR_USART1SEL_SYS: + case RCC_CCIPR_USARTxSEL_SYSCLK: return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); - case RCC_CCIPR_USART1SEL_HSI16: + case RCC_CCIPR_USARTxSEL_HSI: return 16000000U; } cm3_assert_not_reached(); @@ -520,9 +520,9 @@ uint32_t rcc_get_usart_clk_freq(uint32_t usart) if (usart == LPUART1_BASE) { return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_LPUART1SEL_SHIFT); } else if (usart == USART1_BASE) { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb2_frequency, RCC_CCIPR_USART1SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb2_frequency, RCC_CCIPR_USART1SEL_SHIFT); } else { - return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART2SEL_SHIFT); + return rcc_uart_i2c_clksel_freq_hz(rcc_apb1_frequency, RCC_CCIPR_USART2SEL_SHIFT); } } From 88f4d111ba574c3ec9abd86b54795e68c32cff25 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 24 Jan 2023 21:25:40 +0000 Subject: [PATCH 176/206] README: update toolchain recommendations This hadn't been touched in a while, and we now need gcc6+ Fixes: https://github.com/libopencm3/libopencm3/issues/1459 Signed-off-by: Karl Palsson --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 906d8ab1..691c0f01 100644 --- a/README.md +++ b/README.md @@ -80,15 +80,15 @@ After that you can navigate to the folder where you've extracted libopencm3 and Toolchain --------- -The most heavily tested toolchain is "gcc-arm-embedded" -https://launchpad.net/gcc-arm-embedded +The most heavily tested toolchain is ["gcc-arm-embedded"](https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain) +This used to be available at https://launchpad.net/gcc-arm-embedded Other toolchains _should_ work, but they have not been nearly as well tested. Toolchains targeting Linux, such as "gcc-arm-linux-gnu" or the like are _not_ appropriate. -_NOTE_: We recommend that you use gcc-arm-embedded version 4.8 2014q3 or newer -to build all platforms covered by libopencm3 successfully. +_NOTE_: GCC version 6 or later is required, as we're using attributes on enumerators +to help mark deprecations. Building -------- From d262e70fc382785712ee2b7bce350073048515af Mon Sep 17 00:00:00 2001 From: neoxic Date: Wed, 1 Feb 2023 21:40:56 +0000 Subject: [PATCH 177/206] stm32g4/g0: adc: fix clock prescalers CCR register definitions were completely wrong, both decimal/hex mixups, and straightup transcriptions from the reference manual errors. Unify the styles for both g0 and g4, using the same (duplicated) function for both implmentations. Reviewed-by: Karl Palsson --- include/libopencm3/stm32/g0/adc.h | 8 ++++---- include/libopencm3/stm32/g4/adc.h | 32 ++++++++++++++++--------------- lib/stm32/g4/adc.c | 11 ++++++----- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/include/libopencm3/stm32/g0/adc.h b/include/libopencm3/stm32/g0/adc.h index af595931..b241024d 100644 --- a/include/libopencm3/stm32/g0/adc.h +++ b/include/libopencm3/stm32/g0/adc.h @@ -95,8 +95,8 @@ /** @defgroup adc_ccr_presc ADC clock prescaler *@{*/ #define ADC_CCR_PRESC_NODIV (0x0) -#define ADC_CCR_PRESC_DIV1 (0x1) -#define ADC_CCR_PRESC_DIV2 (0x2) +#define ADC_CCR_PRESC_DIV2 (0x1) +#define ADC_CCR_PRESC_DIV4 (0x2) #define ADC_CCR_PRESC_DIV6 (0x3) #define ADC_CCR_PRESC_DIV8 (0x4) #define ADC_CCR_PRESC_DIV10 (0x5) @@ -104,8 +104,8 @@ #define ADC_CCR_PRESC_DIV16 (0x7) #define ADC_CCR_PRESC_DIV32 (0x8) #define ADC_CCR_PRESC_DIV64 (0x9) -#define ADC_CCR_PRESC_DIV128 (0x10) -#define ADC_CCR_PRESC_DIV256 (0x11) +#define ADC_CCR_PRESC_DIV128 (0xa) +#define ADC_CCR_PRESC_DIV256 (0xb) /**@}*/ /**@}*/ diff --git a/include/libopencm3/stm32/g4/adc.h b/include/libopencm3/stm32/g4/adc.h index b9a0cd25..fdb09779 100644 --- a/include/libopencm3/stm32/g4/adc.h +++ b/include/libopencm3/stm32/g4/adc.h @@ -459,25 +459,25 @@ #define ADC_CSR_ADRDY_MST (1 << 0) -/*-------- ADC_CCR values ------------*/ +/** @addtogroup adc_ccr +@{*/ -/* Bits 21:18 PRESC[21:18]: ADC Prescaler */ #define ADC_CCR_PRESC_MASK (0xf) #define ADC_CCR_PRESC_SHIFT (18) /** @defgroup adc_ccr_presc ADC clock prescaler *@{*/ -#define ADC_CCR_PRESC_NODIV (0x0 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV1 (0x1 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV2 (0x2 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV6 (0x3 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV8 (0x4 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV10 (0x5 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV12 (0x6 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV16 (0x7 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV32 (0x8 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV64 (0x9 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV128 (0x10 << ADC_CCR_PRESC_SHIFT) -#define ADC_CCR_PRESC_DIV256 (0x11 << ADC_CCR_PRESC_SHIFT) +#define ADC_CCR_PRESC_NODIV (0x0) +#define ADC_CCR_PRESC_DIV2 (0x1) +#define ADC_CCR_PRESC_DIV4 (0x2) +#define ADC_CCR_PRESC_DIV6 (0x3) +#define ADC_CCR_PRESC_DIV8 (0x4) +#define ADC_CCR_PRESC_DIV10 (0x5) +#define ADC_CCR_PRESC_DIV12 (0x6) +#define ADC_CCR_PRESC_DIV16 (0x7) +#define ADC_CCR_PRESC_DIV32 (0x8) +#define ADC_CCR_PRESC_DIV64 (0x9) +#define ADC_CCR_PRESC_DIV128 (0xa) +#define ADC_CCR_PRESC_DIV256 (0xb) /**@}*/ /* CKMODE[1:0]: ADC clock mode */ @@ -500,6 +500,8 @@ /* DELAY: Delay between 2 sampling phases */ #define ADC_CCR_DELAY_SHIFT 8 +/**@}*/ + /* DUAL[4:0]: Dual ADC mode selection */ /****************************************************************************/ /** @defgroup adc_multi_mode ADC Multi mode selection @@ -594,7 +596,7 @@ bool adc_eos_injected(uint32_t adc); uint32_t adc_read_injected(uint32_t adc, uint8_t reg); void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset); void adc_set_clk_source(uint32_t adc, uint32_t source); -void adc_set_clk_prescale(uint32_t adc, uint32_t prescaler); +void adc_set_clk_prescale(uint32_t adc, uint32_t prescale); void adc_set_multi_mode(uint32_t adc, uint32_t mode); void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, uint32_t polarity); diff --git a/lib/stm32/g4/adc.c b/lib/stm32/g4/adc.c index b859b3bf..00acb6d8 100644 --- a/lib/stm32/g4/adc.c +++ b/lib/stm32/g4/adc.c @@ -540,13 +540,14 @@ void adc_set_clk_source(uint32_t adc, uint32_t source) * The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. * * @param adc peripheral of choice @ref adc_reg_base - * @param[in] prescale Unsigned int32. Prescale value for ADC Clock @ref - * adc_ccr_adcpre + * @param[in] prescale Prescale value for ADC Clock @ref adc_ccr_presc */ -void adc_set_clk_prescale(uint32_t adc, uint32_t ckmode) +void adc_set_clk_prescale(uint32_t adc, uint32_t prescale) { - uint32_t reg32 = ((ADC_CCR(adc) & ~ADC_CCR_CKMODE_MASK) | ckmode); - ADC_CCR(adc) = reg32; + uint32_t reg32 = ADC_CCR(adc); + + reg32 &= ~(ADC_CCR_PRESC_MASK << ADC_CCR_PRESC_SHIFT); + ADC_CCR(adc) = (reg32 | (prescale << ADC_CCR_PRESC_SHIFT)); } /*---------------------------------------------------------------------------*/ From 7bd0f4097bdff3d2ccbd02bb282fb95b4e7acdf5 Mon Sep 17 00:00:00 2001 From: neoxic Date: Thu, 2 Feb 2023 21:28:59 +0000 Subject: [PATCH 178/206] stm32g0:adc: drop non-existant ADC_OR register Reviewed-by: Karl Palsson --- include/libopencm3/stm32/g0/adc.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/libopencm3/stm32/g0/adc.h b/include/libopencm3/stm32/g0/adc.h index b241024d..296f4e9d 100644 --- a/include/libopencm3/stm32/g0/adc.h +++ b/include/libopencm3/stm32/g0/adc.h @@ -64,9 +64,6 @@ /** ADC_CALFACT Calibration factor register */ #define ADC_CALFACT(adc) MMIO32((adc) + 0xB4) - -/** ADC_OR Option register */ -#define ADC_OR(adc) MMIO32((adc) + 0xD0) /**@}*/ /* --- Register values -------------------------------------------------------*/ From 69e4ade399103522c5456c8ade0f801c23a6c791 Mon Sep 17 00:00:00 2001 From: neoxic Date: Thu, 2 Feb 2023 21:55:27 +0000 Subject: [PATCH 179/206] stm32:f0/g0/l0: adc: Add EXTSEL defines Add definitions for all the specific options, as is done for other families. Reviewed-by: Karl Palsson (Added extra g0 definitions that were missed) --- include/libopencm3/stm32/f0/adc.h | 8 ++++++++ include/libopencm3/stm32/g0/adc.h | 11 +++++++++++ include/libopencm3/stm32/l0/adc.h | 13 +++++++++++++ 3 files changed, 32 insertions(+) diff --git a/include/libopencm3/stm32/f0/adc.h b/include/libopencm3/stm32/f0/adc.h index 543bd5ae..0510fd2c 100644 --- a/include/libopencm3/stm32/f0/adc.h +++ b/include/libopencm3/stm32/f0/adc.h @@ -80,6 +80,14 @@ #define ADC_CFGR1_EXTSEL_SHIFT 6 #define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) #define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) +/** @defgroup adc_cfgr1_extsel ADC external trigger selection values + *@{*/ +#define ADC_CFGR1_EXTSEL_TIM1_TRGO 0x0 +#define ADC_CFGR1_EXTSEL_TIM1_CC4 0x1 +#define ADC_CFGR1_EXTSEL_TIM2_TRGO 0x2 +#define ADC_CFGR1_EXTSEL_TIM3_TRGO 0x3 +#define ADC_CFGR1_EXTSEL_TIM15_TRGO 0x4 +/**@}*/ /* ADC_CFGR2 Values ---------------------------------------------------------*/ diff --git a/include/libopencm3/stm32/g0/adc.h b/include/libopencm3/stm32/g0/adc.h index 296f4e9d..95a7aa2b 100644 --- a/include/libopencm3/stm32/g0/adc.h +++ b/include/libopencm3/stm32/g0/adc.h @@ -125,6 +125,17 @@ #define ADC_CFGR1_EXTSEL_SHIFT 6 #define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) #define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) +/** @defgroup adc_cfgr1_extsel ADC external trigger selection values + *@{*/ +#define ADC_CFGR1_EXTSEL_TIM1_TRGO2 0x0 +#define ADC_CFGR1_EXTSEL_TIM1_CC4 0x1 +#define ADC_CFGR1_EXTSEL_TIM2_TRGO 0x2 +#define ADC_CFGR1_EXTSEL_TIM3_TRGO 0x3 +#define ADC_CFGR1_EXTSEL_TIM15_TRGO 0x4 +#define ADC_CFGR1_EXTSEL_TIM6_TRGO 0x5 +#define ADC_CFGR1_EXTSEL_TIM4_TRGO 0x6 +#define ADC_CFGR1_EXTSEL_EXTI11 0x7 +/**@}*/ /** CHSELRMOD: Mode Selection of the ADC_CHSELR register */ #define ADC_CFGR1_CHSELRMOD (1 << 21) diff --git a/include/libopencm3/stm32/l0/adc.h b/include/libopencm3/stm32/l0/adc.h index 102ada5e..93066f67 100644 --- a/include/libopencm3/stm32/l0/adc.h +++ b/include/libopencm3/stm32/l0/adc.h @@ -67,6 +67,19 @@ #define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) #define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) +/** @defgroup adc_cfgr1_extsel ADC external trigger selection values + *@{*/ +#define ADC_CFGR1_EXTSEL_TIM6_TRGO 0x0 +#define ADC_CFGR1_EXTSEL_TIM21_CH2 0x1 +#define ADC_CFGR1_EXTSEL_TIM2_TRGO 0x2 +#define ADC_CFGR1_EXTSEL_TIM2_CH4 0x3 +#define ADC_CFGR1_EXTSEL_TIM21_TRGO 0x4 +#define ADC_CFGR1_EXTSEL_TIM22_TRGO 0x4 +#define ADC_CFGR1_EXTSEL_TIM2_CH3 0x5 +#define ADC_CFGR1_EXTSEL_TIM3_TRGO 0x6 +#define ADC_CFGR1_EXTSEL_EXTI11 0x7 +/**@}*/ + /* ADC_CFGR2 Values ---------------------------------------------------------*/ #define ADC_CFGR2_CKMODE_SHIFT 30 From e54650fba43bd7aa72b52398d9ee4ea88f03e60e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 Feb 2023 22:47:44 +0000 Subject: [PATCH 180/206] stm32f0: adc: external trigger selection to unshifted Cleanup one function at a time. Use the correct doxygen references, use unshifted forms in user facing apis. Yes, only the trigger at the moment, as the polarity is shared. Signed-off-by: Karl Palsson --- include/libopencm3/stm32/f0/adc.h | 3 +-- lib/stm32/f0/adc.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/libopencm3/stm32/f0/adc.h b/include/libopencm3/stm32/f0/adc.h index 0510fd2c..9aeddd14 100644 --- a/include/libopencm3/stm32/f0/adc.h +++ b/include/libopencm3/stm32/f0/adc.h @@ -78,8 +78,7 @@ /* EXTSEL[2:0]: External trigger selection for regular group */ #define ADC_CFGR1_EXTSEL_SHIFT 6 -#define ADC_CFGR1_EXTSEL (0x7 << ADC_CFGR1_EXTSEL_SHIFT) -#define ADC_CFGR1_EXTSEL_VAL(x) ((x) << ADC_CFGR1_EXTSEL_SHIFT) +#define ADC_CFGR1_EXTSEL_MASK 0x7 /** @defgroup adc_cfgr1_extsel ADC external trigger selection values *@{*/ #define ADC_CFGR1_EXTSEL_TIM1_TRGO 0x0 diff --git a/lib/stm32/f0/adc.c b/lib/stm32/f0/adc.c index c6165e39..d8ae6a4e 100644 --- a/lib/stm32/f0/adc.c +++ b/lib/stm32/f0/adc.c @@ -155,18 +155,18 @@ void adc_set_operation_mode(uint32_t adc, enum adc_opmode opmode) * 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 base address (@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 + * @param[in] adc peripheral of choice (@ref adc_reg_base) + * @param[in] trigger external trigger @ref adc_cfgr1_extsel + * @param[in] polarity Trigger polarity @ref adc_cfgr1_exten */ - void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, uint32_t polarity) { - ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_EXTSEL) | trigger; - ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_EXTEN_MASK) | polarity; + uint32_t reg = ADC_CFGR1(adc); + reg &= ~(ADC_CFGR1_EXTSEL_MASK << ADC_CFGR1_EXTSEL_SHIFT); + reg &= ~(ADC_CFGR1_EXTEN_MASK); + reg |= polarity | (trigger << ADC_CFGR1_EXTSEL_SHIFT); + ADC_CFGR1(adc) = reg; } /*---------------------------------------------------------------------------*/ From b8bdc87d2d552dfe9751a24d4ebcc320742bc273 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 Feb 2023 23:15:54 +0000 Subject: [PATCH 181/206] trivial: stm32f0:crc fix typo in doxygen Signed-off-by: Karl Palsson --- include/libopencm3/stm32/f0/crc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/f0/crc.h b/include/libopencm3/stm32/f0/crc.h index fb8ff8f2..0f9047ef 100644 --- a/include/libopencm3/stm32/f0/crc.h +++ b/include/libopencm3/stm32/f0/crc.h @@ -1,6 +1,6 @@ /** @defgroup crc_defines CRC Defines * - * @brief libopencm3 Defined Constants and Types for the STM32F1xx CRC + * @brief Defined Constants and Types for the STM32Fxx CRC * Generator * * @ingroup STM32F0xx_defines From 130075a12dfb1fd538b22d63067f23ad0e2e2010 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 Feb 2023 23:16:31 +0000 Subject: [PATCH 182/206] doc: stm32f0: comparator: move to "peripheral api" style The COMP peripheral was left by it's own. Signed-off-by: Karl Palsson --- lib/stm32/f0/comparator.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/stm32/f0/comparator.c b/lib/stm32/f0/comparator.c index 51bd0f2f..59e6023f 100644 --- a/lib/stm32/f0/comparator.c +++ b/lib/stm32/f0/comparator.c @@ -1,8 +1,7 @@ -/** @defgroup comp_file COMP +/** @addtogroup comp_file COMP peripheral API + * @ingroup peripheral_apis * - * @ingroup STM32F0xx - * - * @brief libopencm3 STM32F0xx COMP + * @brief STM32F0xx comparator peripheral * * @version 1.0.0 * From 66e2cc3ea83cb7c181284697de0c1a581413b05b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 Feb 2023 23:17:18 +0000 Subject: [PATCH 183/206] doc: stm32f0: flash: more variants than F05x these days. Don't be so restrictive with the names. Use the standard F0xx style. Signed-off-by: Karl Palsson --- lib/stm32/f0/flash.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/stm32/f0/flash.c b/lib/stm32/f0/flash.c index d594a5e6..ad12486c 100644 --- a/lib/stm32/f0/flash.c +++ b/lib/stm32/f0/flash.c @@ -2,7 +2,7 @@ * * @ingroup peripheral_apis * - * @brief libopencm3 STM32F05x FLASH + * @brief libopencm3 STM32F0xx FLASH * * @version 1.0.0 * @@ -11,8 +11,8 @@ * * @date 14 January 2014 * - * For the STM32F05x, accessing FLASH memory is described in - * section 3 of the STM32F05x Reference Manual. + * For the STM32F0xx, accessing FLASH memory is described in + * section 3 of the STM32F0xx Reference Manual. * * FLASH memory may be used for data storage as well as code, and may be * programmatically modified. Note that for firmware upload the STM32F1xx From f0575c3560f401ad5a91355b143ab63ecb6e2988 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 Feb 2023 23:35:51 +0000 Subject: [PATCH 184/206] stm32g4: rcc: use datasheet naming for CCIPR fields Follow HACKING specifications, be consistent with all other parts. Yes, the SEL suffix is kinda superfluous, but it's _consistent_ which is why we do it. Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g4/rcc.h | 105 +++++++++++++++--------------- lib/stm32/g4/rcc.c | 4 +- 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/include/libopencm3/stm32/g4/rcc.h b/include/libopencm3/stm32/g4/rcc.h index dbf1ef04..74cc10f2 100644 --- a/include/libopencm3/stm32/g4/rcc.h +++ b/include/libopencm3/stm32/g4/rcc.h @@ -572,69 +572,70 @@ /* all fields are 2 bits */ #define RCC_CCIPR_SEL_MASK 0x3 -#define RCC_CCIPR_ADC345_NONE 0 -#define RCC_CCIPR_ADC345_PLLP 1 -#define RCC_CCIPR_ADC345_SYS 2 -#define RCC_CCIPR_ADC345_SHIFT 30 +#define RCC_CCIPR_ADC345SEL_NONE 0 +#define RCC_CCIPR_ADC345SEL_PLLP 1 +#define RCC_CCIPR_ADC345SEL_SYS 2 +#define RCC_CCIPR_ADC345SEL_SHIFT 30 -#define RCC_CCIPR_ADC12_NONE 0 -#define RCC_CCIPR_ADC12_PLLP 1 -#define RCC_CCIPR_ADC12_SYS 2 -#define RCC_CCIPR_ADC12_SHIFT 28 +#define RCC_CCIPR_ADC12SEL_NONE 0 +#define RCC_CCIPR_ADC12SEL_PLLP 1 +#define RCC_CCIPR_ADC12SEL_SYS 2 +#define RCC_CCIPR_ADC12SEL_SHIFT 28 -#define RCC_CCIPR_CLK48_HSI48 0 -#define RCC_CCIPR_CLK48_PLLQ 2 -#define RCC_CCIPR_CLK48_SHIFT 26 +#define RCC_CCIPR_CLK48SEL_HSI48 0 +#define RCC_CCIPR_CLK48SEL_PLLQ 2 +#define RCC_CCIPR_CLK48SEL_SHIFT 26 -#define RCC_CCIPR_FDCAN_HSE 0 -#define RCC_CCIPR_FDCAN_PLLQ 1 -#define RCC_CCIPR_FDCAN_PCLK 2 -#define RCC_CCIPR_FDCAN_SHIFT 24 +#define RCC_CCIPR_FDCANSEL_HSE 0 +#define RCC_CCIPR_FDCANSEL_PLLQ 1 +#define RCC_CCIPR_FDCANSEL_PCLK 2 +#define RCC_CCIPR_FDCANSEL_SHIFT 24 -#define RCC_CCIPR_I2S23_SYS 0 -#define RCC_CCIPR_I2S23_PLLQ 1 -#define RCC_CCIPR_I2S23_EXT 2 -#define RCC_CCIPR_I2S23_SHI16 3 -#define RCC_CCIPR_I2S23_SHIFT 22 +#define RCC_CCIPR_I2S23SEL_SYS 0 +#define RCC_CCIPR_I2S23SEL_PLLQ 1 +#define RCC_CCIPR_I2S23SEL_EXT 2 +#define RCC_CCIPR_I2S23SEL_SHI16 3 +#define RCC_CCIPR_I2S23SEL_SHIFT 22 -#define RCC_CCIPR_SAI1_SYS 0 -#define RCC_CCIPR_SAI1_PLLQ 1 -#define RCC_CCIPR_SAI1_EXT 2 -#define RCC_CCIPR_SAI1_HSI16 3 -#define RCC_CCIPR_SAI1_SHIFT 20 +#define RCC_CCIPR_SAI1SEL_SYS 0 +#define RCC_CCIPR_SAI1SEL_PLLQ 1 +#define RCC_CCIPR_SAI1SEL_EXT 2 +#define RCC_CCIPR_SAI1SEL_HSI16 3 +#define RCC_CCIPR_SAI1SEL_SHIFT 20 -#define RCC_CCIPR_LPTIM1_PCLK 0 -#define RCC_CCIPR_LPTIM1_LSI 1 -#define RCC_CCIPR_LPTIM1_HSI16 2 -#define RCC_CCIPR_LPTIM1_LSE 3 +#define RCC_CCIPR_LPTIM1SEL_PCLK 0 +#define RCC_CCIPR_LPTIM1SEL_LSI 1 +#define RCC_CCIPR_LPTIM1SEL_HSI16 2 +#define RCC_CCIPR_LPTIM1SEL_LSE 3 #define RCC_CCIPR_LPTIM1SEL_SHIFT 18 -#define RCC_CCIPR_I2Cx_PCLK 0 -#define RCC_CCIPR_I2Cx_SYS 1 -#define RCC_CCIPR_I2Cx_HSI16 2 -#define RCC_CCIPR_I2C3_SHIFT 16 -#define RCC_CCIPR_I2C2_SHIFT 14 -#define RCC_CCIPR_I2C1_SHIFT 12 +#define RCC_CCIPR_I2CxSEL_PCLK 0 +#define RCC_CCIPR_I2CxSEL_SYS 1 +#define RCC_CCIPR_I2CxSEL_HSI16 2 +#define RCC_CCIPR_I2C3SEL_SHIFT 16 +#define RCC_CCIPR_I2C2SEL_SHIFT 14 +#define RCC_CCIPR_I2C1SEL_SHIFT 12 -#define RCC_CCIPR_LPUART1_PCLK 0 -#define RCC_CCIPR_LPUART1_SYS 1 -#define RCC_CCIPR_LPUART1_HSI16 2 -#define RCC_CCIPR_LPUART1_LSE 3 +#define RCC_CCIPR_USARTxSEL_PCLK 0 +#define RCC_CCIPR_USARTxSEL_SYSCLK 1 +#define RCC_CCIPR_USARTxSEL_HSI16 2 +#define RCC_CCIPR_USARTxSEL_LSE 3 + +#define RCC_CCIPR_LPUARTxSEL_PCLK RCC_CCIPR_USARTx_PCLK +#define RCC_CCIPR_LPUARTxSEL_SYSCLK RCC_CCIPR_USARTx_SYSCLK +#define RCC_CCIPR_LPUARTxSEL_HSI16 RCC_CCIPR_USARTx_HSI16 +#define RCC_CCIPR_LPUARTxSEL_LSE RCC_CCIPR_USARTx_LSE #define RCC_CCIPR_LPUART1SEL_SHIFT 10 -#define RCC_CCIPR_USARTx_PCLK 0 -#define RCC_CCIPR_USARTx_SYS 1 -#define RCC_CCIPR_USARTx_HSI16 2 -#define RCC_CCIPR_USARTx_LSE 3 -#define RCC_CCIPR_UARTx_PCLK RCC_CCIPR_USARTx_PCLK -#define RCC_CCIPR_UARTx_SYS RCC_CCIPR_USARTx_SYS -#define RCC_CCIPR_UARTx_HSI16 RCC_CCIPR_USARTx_HSI16 -#define RCC_CCIPR_UARTx_LSE RCC_CCIPR_USARTx_LSE -#define RCC_CCIPR_UART5_SHIFT 8 -#define RCC_CCIPR_UART4_SHIFT 6 -#define RCC_CCIPR_USART3_SHIFT 4 -#define RCC_CCIPR_USART2_SHIFT 2 -#define RCC_CCIPR_USART1_SHIFT 0 +#define RCC_CCIPR_UARTxSEL_PCLK RCC_CCIPR_USARTx_PCLK +#define RCC_CCIPR_UARTxSEL_SYSCLK RCC_CCIPR_USARTx_SYSCLK +#define RCC_CCIPR_UARTxSEL_HSI16 RCC_CCIPR_USARTx_HSI16 +#define RCC_CCIPR_UARTxSEL_LSE RCC_CCIPR_USARTx_LSE +#define RCC_CCIPR_UART5SEL_SHIFT 8 +#define RCC_CCIPR_UART4SEL_SHIFT 6 +#define RCC_CCIPR_USART3SEL_SHIFT 4 +#define RCC_CCIPR_USART2SEL_SHIFT 2 +#define RCC_CCIPR_USART1SEL_SHIFT 0 /**@}*/ /** defgroup rcc_ccipr2_values RCC_CCIPR2 - Peripherals independent clock config register 2 diff --git a/lib/stm32/g4/rcc.c b/lib/stm32/g4/rcc.c index f6bd2fff..5b8c14cd 100644 --- a/lib/stm32/g4/rcc.c +++ b/lib/stm32/g4/rcc.c @@ -759,8 +759,8 @@ void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock) */ void rcc_set_clock48_source(uint32_t clksel) { - RCC_CCIPR &= ~(RCC_CCIPR_SEL_MASK << RCC_CCIPR_CLK48_SHIFT); - RCC_CCIPR |= (clksel << RCC_CCIPR_CLK48_SHIFT); + RCC_CCIPR &= ~(RCC_CCIPR_SEL_MASK << RCC_CCIPR_CLK48SEL_SHIFT); + RCC_CCIPR |= (clksel << RCC_CCIPR_CLK48SEL_SHIFT); } /**@}*/ From 0878a046968eb0acf40134bfc6fc13828ed10a7b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 Feb 2023 23:53:42 +0000 Subject: [PATCH 185/206] stm32g4: rcc: use SYSCLK consistently with other families Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g4/rcc.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/libopencm3/stm32/g4/rcc.h b/include/libopencm3/stm32/g4/rcc.h index 74cc10f2..c1d38a90 100644 --- a/include/libopencm3/stm32/g4/rcc.h +++ b/include/libopencm3/stm32/g4/rcc.h @@ -574,12 +574,12 @@ #define RCC_CCIPR_ADC345SEL_NONE 0 #define RCC_CCIPR_ADC345SEL_PLLP 1 -#define RCC_CCIPR_ADC345SEL_SYS 2 +#define RCC_CCIPR_ADC345SEL_SYSCLK 2 #define RCC_CCIPR_ADC345SEL_SHIFT 30 #define RCC_CCIPR_ADC12SEL_NONE 0 #define RCC_CCIPR_ADC12SEL_PLLP 1 -#define RCC_CCIPR_ADC12SEL_SYS 2 +#define RCC_CCIPR_ADC12SEL_SYSCLK 2 #define RCC_CCIPR_ADC12SEL_SHIFT 28 #define RCC_CCIPR_CLK48SEL_HSI48 0 @@ -591,13 +591,13 @@ #define RCC_CCIPR_FDCANSEL_PCLK 2 #define RCC_CCIPR_FDCANSEL_SHIFT 24 -#define RCC_CCIPR_I2S23SEL_SYS 0 +#define RCC_CCIPR_I2S23SEL_SYSCLK 0 #define RCC_CCIPR_I2S23SEL_PLLQ 1 #define RCC_CCIPR_I2S23SEL_EXT 2 #define RCC_CCIPR_I2S23SEL_SHI16 3 #define RCC_CCIPR_I2S23SEL_SHIFT 22 -#define RCC_CCIPR_SAI1SEL_SYS 0 +#define RCC_CCIPR_SAI1SEL_SYSCLK 0 #define RCC_CCIPR_SAI1SEL_PLLQ 1 #define RCC_CCIPR_SAI1SEL_EXT 2 #define RCC_CCIPR_SAI1SEL_HSI16 3 @@ -610,14 +610,14 @@ #define RCC_CCIPR_LPTIM1SEL_SHIFT 18 #define RCC_CCIPR_I2CxSEL_PCLK 0 -#define RCC_CCIPR_I2CxSEL_SYS 1 +#define RCC_CCIPR_I2CxSEL_SYSCLK 1 #define RCC_CCIPR_I2CxSEL_HSI16 2 #define RCC_CCIPR_I2C3SEL_SHIFT 16 #define RCC_CCIPR_I2C2SEL_SHIFT 14 #define RCC_CCIPR_I2C1SEL_SHIFT 12 #define RCC_CCIPR_USARTxSEL_PCLK 0 -#define RCC_CCIPR_USARTxSEL_SYSCLK 1 +#define RCC_CCIPR_USARTxSEL_SYSCLK 1 #define RCC_CCIPR_USARTxSEL_HSI16 2 #define RCC_CCIPR_USARTxSEL_LSE 3 From e9426db2227dfbbf40bded5b694f8440ddad1bad Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 2 Feb 2023 23:54:50 +0000 Subject: [PATCH 186/206] stm32l4: rcc: use SYSCLK consistently with other families Signed-off-by: Karl Palsson --- include/libopencm3/stm32/l4/rcc.h | 8 ++++---- lib/stm32/l4/rcc.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/libopencm3/stm32/l4/rcc.h b/include/libopencm3/stm32/l4/rcc.h index f85791c3..1d0e804a 100644 --- a/include/libopencm3/stm32/l4/rcc.h +++ b/include/libopencm3/stm32/l4/rcc.h @@ -621,7 +621,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CCIPR_ADCSEL_NONE 0 #define RCC_CCIPR_ADCSEL_PLLSAI1R 1 #define RCC_CCIPR_ADCSEL_PLLSAI2R 2 -#define RCC_CCIPR_ADCSEL_SYS 3 +#define RCC_CCIPR_ADCSEL_SYSCLK 3 #define RCC_CCIPR_ADCSEL_MASK 0x3 #define RCC_CCIPR_ADCSEL_SHIFT 28 @@ -649,7 +649,7 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CCIPR_LPTIM1SEL_SHIFT 18 #define RCC_CCIPR_I2CxSEL_APB 0 -#define RCC_CCIPR_I2CxSEL_SYS 1 +#define RCC_CCIPR_I2CxSEL_SYSCLK 1 #define RCC_CCIPR_I2CxSEL_HSI16 2 #define RCC_CCIPR_I2CxSEL_MASK 0x3 #define RCC_CCIPR_I2C4SEL_SHIFT 0 @@ -665,12 +665,12 @@ Twelve frequency ranges are available: 100 kHz, 200 kHz, 400 kHz, 800 kHz, #define RCC_CCIPR_LPUART1SEL_SHIFT 10 #define RCC_CCIPR_USARTxSEL_APB 0 -#define RCC_CCIPR_USARTxSEL_SYS 1 +#define RCC_CCIPR_USARTxSEL_SYSCLK 1 #define RCC_CCIPR_USARTxSEL_HSI16 2 #define RCC_CCIPR_USARTxSEL_LSE 3 #define RCC_CCIPR_USARTxSEL_MASK 0x3 #define RCC_CCIPR_UARTxSEL_APB RCC_CCIPR_USARTxSEL_APB -#define RCC_CCIPR_UARTxSEL_SYS RCC_CCIPR_USARTxSEL_SYS +#define RCC_CCIPR_UARTxSEL_SYSCLK RCC_CCIPR_USARTxSEL_SYSCLK #define RCC_CCIPR_UARTxSEL_HSI16 RCC_CCIPR_USARTxSEL_HSI16 #define RCC_CCIPR_UARTxSEL_LSE RCC_CCIPR_USARTxSEL_LSE #define RCC_CCIPR_UARTxSEL_MASK RCC_CCIPR_USARTxSEL_MASK diff --git a/lib/stm32/l4/rcc.c b/lib/stm32/l4/rcc.c index c35a1896..99e9fd39 100644 --- a/lib/stm32/l4/rcc.c +++ b/lib/stm32/l4/rcc.c @@ -541,7 +541,7 @@ static uint32_t rcc_uart_i2c_clksel_freq_hz(uint32_t apb_clk, uint8_t shift, uin switch (clksel) { case RCC_CCIPR_USARTxSEL_APB: return apb_clk; - case RCC_CCIPR_USARTxSEL_SYS: + case RCC_CCIPR_USARTxSEL_SYSCLK: return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); case RCC_CCIPR_USARTxSEL_HSI16: return 16000000U; From e643f663423f6ffbd944ef88d2d675b7abc2ad03 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 3 Feb 2023 00:02:02 +0000 Subject: [PATCH 187/206] stm32g4:rcc: add uart peripheral clock source helpers Required so that the common uart infrastructure can be updated. This was the last family to receive this implementation. Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g4/rcc.h | 5 +++++ lib/stm32/g4/rcc.c | 35 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/libopencm3/stm32/g4/rcc.h b/include/libopencm3/stm32/g4/rcc.h index c1d38a90..bc50f413 100644 --- a/include/libopencm3/stm32/g4/rcc.h +++ b/include/libopencm3/stm32/g4/rcc.h @@ -1032,6 +1032,11 @@ uint32_t rcc_system_clock_source(void); void rcc_clock_setup_pll(const struct rcc_clock_scale *clock); void __attribute__((deprecated("Use rcc_clock_setup_pll as direct replacement"))) rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock); void rcc_set_clock48_source(uint32_t clksel); +/** + * Get the peripheral clock speed for the specified (LP)UxART + * @param usart Base address of USART to get clock frequency for. + */ +uint32_t rcc_get_usart_clk_freq(uint32_t usart); END_DECLS diff --git a/lib/stm32/g4/rcc.c b/lib/stm32/g4/rcc.c index 5b8c14cd..b54217c0 100644 --- a/lib/stm32/g4/rcc.c +++ b/lib/stm32/g4/rcc.c @@ -763,4 +763,39 @@ void rcc_set_clock48_source(uint32_t clksel) RCC_CCIPR |= (clksel << RCC_CCIPR_CLK48SEL_SHIFT); } +static uint32_t rcc_get_clksel_freq(uint8_t shift) { + uint8_t clksel = (RCC_CCIPR >> shift) & RCC_CCIPR_SEL_MASK; + uint8_t hpre = (RCC_CFGR >> RCC_CFGR_HPRE_SHIFT) & RCC_CFGR_HPRE_MASK; + switch (clksel) { + case RCC_CCIPR_USARTxSEL_PCLK: + return rcc_apb1_frequency; + case RCC_CCIPR_USARTxSEL_SYSCLK: + return rcc_ahb_frequency * rcc_get_div_from_hpre(hpre); + case RCC_CCIPR_USARTxSEL_LSE: + return 32768; + case RCC_CCIPR_USARTxSEL_HSI16: + return 16000000U; + } + cm3_assert_not_reached(); +} + + +uint32_t rcc_get_usart_clk_freq(uint32_t usart) +{ + if (usart == USART1_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_USART1SEL_SHIFT); + } else if (usart == USART2_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_USART2SEL_SHIFT); + } else if (usart == USART3_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_USART3SEL_SHIFT); + } else if (usart == UART4_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_UART4SEL_SHIFT); + } else if (usart == UART5_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_UART5SEL_SHIFT); + } else if (usart == LPUART1_BASE) { + return rcc_get_clksel_freq(RCC_CCIPR_LPUART1SEL_SHIFT); + } + cm3_assert_not_reached(); +} + /**@}*/ From 4d7a2ca271b846e7333e5da09ca1a6d0bf4b663f Mon Sep 17 00:00:00 2001 From: Harry Geyer Date: Thu, 12 Jan 2023 13:33:56 +0000 Subject: [PATCH 188/206] stm32: When setting baudrate of a USART, first get the clock frequency for that USART. Now that all families have support for calculating the clock of the uart, use that layer. Slightly slower for "old" families, but the only way to be correct for newer families. Reviewed-by: Karl Palsson --- lib/stm32/common/usart_common_all.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lib/stm32/common/usart_common_all.c b/lib/stm32/common/usart_common_all.c index e30e2feb..8e676c07 100644 --- a/lib/stm32/common/usart_common_all.c +++ b/lib/stm32/common/usart_common_all.c @@ -52,17 +52,7 @@ usart_reg_base void usart_set_baudrate(uint32_t usart, uint32_t baud) { - uint32_t clock = rcc_apb1_frequency; - -#if defined USART1 - if ((usart == USART1) -#if defined USART6 - || (usart == USART6) -#endif - ) { - clock = rcc_apb2_frequency; - } -#endif + uint32_t clock = rcc_get_usart_clk_freq(usart); /* * Yes it is as simple as that. The reference manual is From f3049c66992d9023e33f0e7fafe3ac5cf85ea045 Mon Sep 17 00:00:00 2001 From: Rohit Nimkar Date: Fri, 18 Nov 2022 08:03:40 +0530 Subject: [PATCH 189/206] doc: stm32: rcc: improve intellisense Removed newline between the comment block and function definition It enables vscode intellisense to display documentation about functions Reviewed-by: Karl Palsson --- lib/cm3/systick.c | 1 - lib/stm32/common/rcc_common_all.c | 16 ---------------- 2 files changed, 17 deletions(-) diff --git a/lib/cm3/systick.c b/lib/cm3/systick.c index d775dd06..4b0fdd4e 100644 --- a/lib/cm3/systick.c +++ b/lib/cm3/systick.c @@ -52,7 +52,6 @@ * * @param[in] value uint32_t. 24 bit reload value. */ - void systick_set_reload(uint32_t value) { STK_RVR = (value & STK_RVR_RELOAD); diff --git a/lib/stm32/common/rcc_common_all.c b/lib/stm32/common/rcc_common_all.c index 0b1f9370..7a9d32cf 100644 --- a/lib/stm32/common/rcc_common_all.c +++ b/lib/stm32/common/rcc_common_all.c @@ -24,7 +24,6 @@ #include -/*---------------------------------------------------------------------------*/ /** @brief RCC Enable Peripheral Clocks. * * Enable the clock on particular peripherals. There are three registers @@ -42,13 +41,11 @@ * @li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en * @li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en */ - void rcc_peripheral_enable_clock(volatile uint32_t *reg, uint32_t en) { *reg |= en; } -/*---------------------------------------------------------------------------*/ /** @brief RCC Disable Peripheral Clocks. * * Disable the clock on particular peripherals. There are three registers @@ -71,7 +68,6 @@ void rcc_peripheral_disable_clock(volatile uint32_t *reg, uint32_t en) *reg &= ~en; } -/*---------------------------------------------------------------------------*/ /** @brief RCC Reset Peripherals. * * Reset particular peripherals. There are three registers involved, each one @@ -94,7 +90,6 @@ void rcc_peripheral_reset(volatile uint32_t *reg, uint32_t reset) *reg |= reset; } -/*---------------------------------------------------------------------------*/ /** @brief RCC Remove Reset on Peripherals. * * Remove the reset on particular peripherals. There are three registers @@ -121,7 +116,6 @@ void rcc_peripheral_clear_reset(volatile uint32_t *reg, uint32_t clear_reset) #define _RCC_REG(i) MMIO32(RCC_BASE + ((i) >> 5)) #define _RCC_BIT(i) (1 << ((i) & 0x1f)) -/*---------------------------------------------------------------------------*/ /** @brief Enable Peripheral Clock in running mode. * * Enable the clock on particular peripheral. @@ -130,13 +124,11 @@ void rcc_peripheral_clear_reset(volatile uint32_t *reg, uint32_t clear_reset) * * For available constants, see #rcc_periph_clken (RCC_UART1 for example) */ - void rcc_periph_clock_enable(enum rcc_periph_clken clken) { _RCC_REG(clken) |= _RCC_BIT(clken); } -/*---------------------------------------------------------------------------*/ /** @brief Disable Peripheral Clock in running mode. * Disable the clock on particular peripheral. * @@ -144,13 +136,11 @@ void rcc_periph_clock_enable(enum rcc_periph_clken clken) * * For available constants, see #rcc_periph_clken (RCC_UART1 for example) */ - void rcc_periph_clock_disable(enum rcc_periph_clken clken) { _RCC_REG(clken) &= ~_RCC_BIT(clken); } -/*---------------------------------------------------------------------------*/ /** @brief Reset Peripheral, pulsed * * Reset particular peripheral, and restore to working state. @@ -159,14 +149,12 @@ void rcc_periph_clock_disable(enum rcc_periph_clken clken) * * For available constants, see #rcc_periph_rst (RST_UART1 for example) */ - void rcc_periph_reset_pulse(enum rcc_periph_rst rst) { _RCC_REG(rst) |= _RCC_BIT(rst); _RCC_REG(rst) &= ~_RCC_BIT(rst); } -/*---------------------------------------------------------------------------*/ /** @brief Reset Peripheral, hold * * Reset particular peripheral, and hold in reset state. @@ -175,13 +163,11 @@ void rcc_periph_reset_pulse(enum rcc_periph_rst rst) * * For available constants, see #rcc_periph_rst (RST_UART1 for example) */ - void rcc_periph_reset_hold(enum rcc_periph_rst rst) { _RCC_REG(rst) |= _RCC_BIT(rst); } -/*---------------------------------------------------------------------------*/ /** @brief Reset Peripheral, release * * Restore peripheral from reset state to working state. @@ -190,7 +176,6 @@ void rcc_periph_reset_hold(enum rcc_periph_rst rst) * * For available constants, see #rcc_periph_rst (RST_UART1 for example) */ - void rcc_periph_reset_release(enum rcc_periph_rst rst) { _RCC_REG(rst) &= ~_RCC_BIT(rst); @@ -203,7 +188,6 @@ void rcc_periph_reset_release(enum rcc_periph_rst rst) * * @param[in] mcosrc the unshifted source bits */ - void rcc_set_mco(uint32_t mcosrc) { RCC_CFGR = (RCC_CFGR & ~(RCC_CFGR_MCO_MASK << RCC_CFGR_MCO_SHIFT)) | From f58ffd4ba786793ac88ffeef9e9b870410f672af Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 3 Feb 2023 00:23:18 +0000 Subject: [PATCH 190/206] ld: add stm23l412xx parts Reported: https://github.com/libopencm3/libopencm3/pull/1449 Signed-off-by: Karl Palsson --- ld/devices.data | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ld/devices.data b/ld/devices.data index 57729c05..bc047443 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -214,6 +214,8 @@ stm32l162?c* stm32l1eep ROM=256K RAM=32K EEP=8K stm32l162?d*_x stm32l1eep ROM=384K RAM=80K EEP=16K stm32l162?d* stm32l1eep ROM=384K RAM=48K EEP=12K +stm32l41??8* stm32l4 ROM=64K RAM=32K RAM2=8K +stm32l41??b* stm32l4 ROM=128K RAM=32K RAM2=8K stm32l43??b* stm32l4 ROM=128K RAM=48K RAM2=16K stm32l4[34]??c* stm32l4 ROM=256K RAM=48K RAM2=16K stm32l451?c* stm32l4 ROM=256K RAM=128K RAM2=32K From 8bc483746bd78f2a398f2949420a4128eed5272c Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 3 Feb 2023 14:22:22 +0000 Subject: [PATCH 191/206] stm32h7:usart: add common file to build Without the common core, you couldn't actually link a project using the usart peripherals. Fixes: https://github.com/libopencm3/libopencm3/pull/1464 --- lib/stm32/h7/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stm32/h7/Makefile b/lib/stm32/h7/Makefile index 2c7cbb18..46d2d037 100644 --- a/lib/stm32/h7/Makefile +++ b/lib/stm32/h7/Makefile @@ -48,7 +48,7 @@ OBJS += rcc_common_all.o OBJS += rng_common_v1.o OBJS += spi_common_all.o spi_common_v2.o OBJS += timer_common_all.o -OBJS += usart_common_v2.o usart_common_fifos.o +OBJS += usart_common_all.o usart_common_v2.o usart_common_fifos.o OBJS += quadspi_common_v1.o VPATH += ../../usb:../:../../cm3:../common From 9914cd1d6ca7f968a4498a7b1bb779f701356b9e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 7 Mar 2023 14:23:49 +0000 Subject: [PATCH 192/206] usb: add missing stdint.h includes Some class headers were not including stdint.h themselves, despite relying on those types, and relying on them already being included earlier elsewhere. Consistently include stdint.h where it's used. Fixes: https://github.com/libopencm3/libopencm3/issues/1471 Signed-off-by: Karl Palsson --- include/libopencm3/usb/dfu.h | 2 ++ include/libopencm3/usb/msc.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/libopencm3/usb/dfu.h b/include/libopencm3/usb/dfu.h index 1d0fc3f1..bf9139e1 100644 --- a/include/libopencm3/usb/dfu.h +++ b/include/libopencm3/usb/dfu.h @@ -38,6 +38,8 @@ LGPL License Terms @ref lgpl_license #ifndef __DFU_H #define __DFU_H +#include + #define USB_CLASS_DFU 0xFE enum dfu_req { diff --git a/include/libopencm3/usb/msc.h b/include/libopencm3/usb/msc.h index cf9c54a6..2c52bb02 100644 --- a/include/libopencm3/usb/msc.h +++ b/include/libopencm3/usb/msc.h @@ -40,6 +40,8 @@ LGPL License Terms @ref lgpl_license #ifndef __MSC_H #define __MSC_H +#include + typedef struct _usbd_mass_storage usbd_mass_storage; /* Definitions of Mass Storage Class from: From 189017b25cebfc609a6c1a5a02047691ef845b1b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 7 Mar 2023 14:27:20 +0000 Subject: [PATCH 193/206] usb:msc: include referenced usbd_device headers In addition to stdint.h, MSC directly relies on the usbd_device type definition existing. Ensure it has included it's own dependencies. Fixes: https://github.com/libopencm3/libopencm3/issues/1471 Signed-off-by: Karl Palsson --- include/libopencm3/usb/msc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/libopencm3/usb/msc.h b/include/libopencm3/usb/msc.h index 2c52bb02..1317b2a7 100644 --- a/include/libopencm3/usb/msc.h +++ b/include/libopencm3/usb/msc.h @@ -41,6 +41,7 @@ LGPL License Terms @ref lgpl_license #define __MSC_H #include +#include typedef struct _usbd_mass_storage usbd_mass_storage; From 0241982fb4ad90d8f2a0146fc71eb01927663ea9 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Mon, 15 Aug 2022 17:57:51 +0100 Subject: [PATCH 194/206] stm32/usart: Implemented a function to get the current databits setting for a USART --- .../stm32/common/usart_common_all.h | 1 + lib/stm32/common/usart_common_all.c | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/libopencm3/stm32/common/usart_common_all.h b/include/libopencm3/stm32/common/usart_common_all.h index 8c310a9c..a86a91fb 100644 --- a/include/libopencm3/stm32/common/usart_common_all.h +++ b/include/libopencm3/stm32/common/usart_common_all.h @@ -100,6 +100,7 @@ BEGIN_DECLS void usart_set_baudrate(uint32_t usart, uint32_t baud); void usart_set_databits(uint32_t usart, uint32_t bits); +uint32_t usart_get_databits(uint32_t usart); void usart_set_stopbits(uint32_t usart, uint32_t stopbits); void usart_set_parity(uint32_t usart, uint32_t parity); void usart_set_mode(uint32_t usart, uint32_t mode); diff --git a/lib/stm32/common/usart_common_all.c b/lib/stm32/common/usart_common_all.c index 8e676c07..6fcbf191 100644 --- a/lib/stm32/common/usart_common_all.c +++ b/lib/stm32/common/usart_common_all.c @@ -95,6 +95,27 @@ void usart_set_databits(uint32_t usart, uint32_t bits) } } +/*---------------------------------------------------------------------------*/ +/** @brief USART Get Word Length. + +The word length is set to 8 or 9 bits. Note that the last bit will be a parity +bit if parity is enabled, in which case the data length will be 7 or 8 bits +respectively. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@returns unsigned 32 bit Word length in bits 8 or 9. +*/ + +uint32_t usart_get_databits(uint32_t usart) +{ + const uint32_t reg32 = USART_CR1(usart) & USART_CR1_M; + if (reg32) + return 9; + else + return 8; +} + /*---------------------------------------------------------------------------*/ /** @brief USART Set Stop Bit(s). From 48a83558747f950d055911c1ef92d224c63f2d3b Mon Sep 17 00:00:00 2001 From: dragonmux Date: Mon, 15 Aug 2022 17:58:18 +0100 Subject: [PATCH 195/206] stm32/usart: Implemented a function to get the current stop bits setting for a USART --- .../libopencm3/stm32/common/usart_common_all.h | 1 + lib/stm32/common/usart_common_all.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/libopencm3/stm32/common/usart_common_all.h b/include/libopencm3/stm32/common/usart_common_all.h index a86a91fb..c41a2267 100644 --- a/include/libopencm3/stm32/common/usart_common_all.h +++ b/include/libopencm3/stm32/common/usart_common_all.h @@ -102,6 +102,7 @@ void usart_set_baudrate(uint32_t usart, uint32_t baud); void usart_set_databits(uint32_t usart, uint32_t bits); uint32_t usart_get_databits(uint32_t usart); void usart_set_stopbits(uint32_t usart, uint32_t stopbits); +uint32_t usart_get_stopbits(uint32_t usart); void usart_set_parity(uint32_t usart, uint32_t parity); void usart_set_mode(uint32_t usart, uint32_t mode); void usart_set_flow_control(uint32_t usart, uint32_t flowcontrol); diff --git a/lib/stm32/common/usart_common_all.c b/lib/stm32/common/usart_common_all.c index 6fcbf191..49e1f20b 100644 --- a/lib/stm32/common/usart_common_all.c +++ b/lib/stm32/common/usart_common_all.c @@ -135,6 +135,22 @@ void usart_set_stopbits(uint32_t usart, uint32_t stopbits) USART_CR2(usart) = reg32; } +/*---------------------------------------------------------------------------*/ +/** @brief USART Get Stop Bit(s). + +The stop bits are specified as 0.5, 1, 1.5 or 2. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@returns unsigned 32 bit Stop bits @ref usart_cr2_stopbits. +*/ + +uint32_t usart_get_stopbits(uint32_t usart) +{ + const uint32_t reg32 = USART_CR2(usart); + return reg32 & USART_CR2_STOPBITS_MASK; +} + /*---------------------------------------------------------------------------*/ /** @brief USART Set Parity. From 188671389dabc857450e84ebcd11b9b396ace218 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Mon, 15 Aug 2022 17:58:34 +0100 Subject: [PATCH 196/206] stm32/usart: Implemented a function to get the current parity setting for a USART --- .../libopencm3/stm32/common/usart_common_all.h | 1 + lib/stm32/common/usart_common_all.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/libopencm3/stm32/common/usart_common_all.h b/include/libopencm3/stm32/common/usart_common_all.h index c41a2267..cb034cd9 100644 --- a/include/libopencm3/stm32/common/usart_common_all.h +++ b/include/libopencm3/stm32/common/usart_common_all.h @@ -104,6 +104,7 @@ uint32_t usart_get_databits(uint32_t usart); void usart_set_stopbits(uint32_t usart, uint32_t stopbits); uint32_t usart_get_stopbits(uint32_t usart); void usart_set_parity(uint32_t usart, uint32_t parity); +uint32_t usart_get_parity(uint32_t usart); void usart_set_mode(uint32_t usart, uint32_t mode); void usart_set_flow_control(uint32_t usart, uint32_t flowcontrol); void usart_enable(uint32_t usart); diff --git a/lib/stm32/common/usart_common_all.c b/lib/stm32/common/usart_common_all.c index 49e1f20b..93d44978 100644 --- a/lib/stm32/common/usart_common_all.c +++ b/lib/stm32/common/usart_common_all.c @@ -170,6 +170,22 @@ void usart_set_parity(uint32_t usart, uint32_t parity) USART_CR1(usart) = reg32; } +/*---------------------------------------------------------------------------*/ +/** @brief USART Get Parity. + +The stop bits are specified as 0.5, 1, 1.5 or 2. + +@param[in] usart unsigned 32 bit. USART block register address base @ref +usart_reg_base +@returns unsigned 32 bit Parity @ref usart_cr2_stopbits. +*/ + +uint32_t usart_get_parity(uint32_t usart) +{ + const uint32_t reg32 = USART_CR1(usart); + return reg32 & USART_PARITY_MASK; +} + /*---------------------------------------------------------------------------*/ /** @brief USART Set Rx/Tx Mode. From 56ec4c2b069355a40a277c125c377dea2d0c7511 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Mon, 15 Aug 2022 17:58:59 +0100 Subject: [PATCH 197/206] stm32/usart: Automatic whitespace cleanup --- include/libopencm3/stm32/common/usart_common_all.h | 1 - lib/stm32/common/usart_common_all.c | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/libopencm3/stm32/common/usart_common_all.h b/include/libopencm3/stm32/common/usart_common_all.h index cb034cd9..455746a0 100644 --- a/include/libopencm3/stm32/common/usart_common_all.h +++ b/include/libopencm3/stm32/common/usart_common_all.h @@ -140,4 +140,3 @@ END_DECLS #endif /** @endcond */ /**@}*/ - diff --git a/lib/stm32/common/usart_common_all.c b/lib/stm32/common/usart_common_all.c index 93d44978..7e0ef48c 100644 --- a/lib/stm32/common/usart_common_all.c +++ b/lib/stm32/common/usart_common_all.c @@ -396,7 +396,7 @@ void usart_disable_tx_interrupt(uint32_t usart) /*---------------------------------------------------------------------------*/ /** * @brief USART Transmission Complete Interrupt Enable - * + * * @param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base */ @@ -409,7 +409,7 @@ void usart_enable_tx_complete_interrupt(uint32_t usart) /*---------------------------------------------------------------------------*/ /** * @brief USART Transmission Complete Interrupt Disable - * + * * @param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base */ @@ -467,4 +467,3 @@ void usart_disable_error_interrupt(uint32_t usart) } /**@}*/ - From c212d19cd4228971e987f72577635a17ee2d1310 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Mon, 15 Aug 2022 18:06:48 +0100 Subject: [PATCH 198/206] usb/cdc: Added a definition for the GET_LINE_CODING class-specific request --- include/libopencm3/usb/cdc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/libopencm3/usb/cdc.h b/include/libopencm3/usb/cdc.h index 6e57a565..2a22ea40 100644 --- a/include/libopencm3/usb/cdc.h +++ b/include/libopencm3/usb/cdc.h @@ -118,7 +118,7 @@ struct usb_cdc_acm_descriptor { /* Table 13: Class-Specific Request Codes for PSTN subclasses */ /* ... */ #define USB_CDC_REQ_SET_LINE_CODING 0x20 -/* ... */ +#define USB_CDC_REQ_GET_LINE_CODING 0x21 #define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 /* ... */ @@ -161,4 +161,3 @@ struct usb_cdc_notification { #endif /**@}*/ - From 4d23ac87149cc1294ae08bcc1d78e4f5aa126626 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Tue, 23 Aug 2022 03:13:52 +0100 Subject: [PATCH 199/206] lm4f/uart: Fixed up the naming of one of the variables in uart_set_databits() --- lib/lm4f/uart.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/lm4f/uart.c b/lib/lm4f/uart.c index f37907b4..542ae3b7 100644 --- a/lib/lm4f/uart.c +++ b/lib/lm4f/uart.c @@ -138,16 +138,16 @@ void uart_set_baudrate(uint32_t uart, uint32_t baud) */ void uart_set_databits(uint32_t uart, uint8_t databits) { - uint32_t reg32, bitint32_t; + uint32_t reg32, bits32; /* This has the same effect as using UART_LCRH_WLEN_5/6/7/8 directly */ - bitint32_t = (databits - 5) << 5; + bits32 = (databits - 5) << 5; /* TODO: What about 9 data bits? */ reg32 = UART_LCRH(uart); reg32 &= ~UART_LCRH_WLEN_MASK; - reg32 |= bitint32_t; + reg32 |= bits32; UART_LCRH(uart) = reg32; } From 78ace3630844fa33516f2efdf1afc9c92431ac5b Mon Sep 17 00:00:00 2001 From: dragonmux Date: Tue, 23 Aug 2022 03:14:22 +0100 Subject: [PATCH 200/206] lm4f/uart: Implemented a function to get the current databits setting for a UART --- include/libopencm3/lm4f/uart.h | 1 + lib/lm4f/uart.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/libopencm3/lm4f/uart.h b/include/libopencm3/lm4f/uart.h index f36556ee..3f3aa661 100644 --- a/include/libopencm3/lm4f/uart.h +++ b/include/libopencm3/lm4f/uart.h @@ -444,6 +444,7 @@ BEGIN_DECLS void uart_set_baudrate(uint32_t uart, uint32_t baud); void uart_set_databits(uint32_t uart, uint8_t databits); +uint8_t uart_get_databits(uint32_t uart); void uart_set_stopbits(uint32_t uart, uint8_t stopbits); void uart_set_parity(uint32_t uart, enum uart_parity parity); void uart_set_mode(uint32_t uart, uint32_t mode); diff --git a/lib/lm4f/uart.c b/lib/lm4f/uart.c index 542ae3b7..725c52cb 100644 --- a/lib/lm4f/uart.c +++ b/lib/lm4f/uart.c @@ -151,6 +151,12 @@ void uart_set_databits(uint32_t uart, uint8_t databits) UART_LCRH(uart) = reg32; } +uint8_t uart_get_databits(uint32_t uart) +{ + const uint8_t bits = (UART_LCRH(uart) & UART_LCRH_WLEN_MASK) >> 5; + return bits + 5; +} + /** * \brief Set UART stopbits * From f0262cb4a949711811bc89450b877a15d8321c1f Mon Sep 17 00:00:00 2001 From: dragonmux Date: Tue, 23 Aug 2022 03:14:45 +0100 Subject: [PATCH 201/206] lm4f/uart: Implemented a function to get the current stop bits setting for a UART --- include/libopencm3/lm4f/uart.h | 1 + lib/lm4f/uart.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/libopencm3/lm4f/uart.h b/include/libopencm3/lm4f/uart.h index 3f3aa661..fbde2229 100644 --- a/include/libopencm3/lm4f/uart.h +++ b/include/libopencm3/lm4f/uart.h @@ -446,6 +446,7 @@ void uart_set_baudrate(uint32_t uart, uint32_t baud); void uart_set_databits(uint32_t uart, uint8_t databits); uint8_t uart_get_databits(uint32_t uart); void uart_set_stopbits(uint32_t uart, uint8_t stopbits); +uint8_t uart_get_stopbits(uint32_t uart); void uart_set_parity(uint32_t uart, enum uart_parity parity); void uart_set_mode(uint32_t uart, uint32_t mode); void uart_set_flow_control(uint32_t uart, enum uart_flowctl flow); diff --git a/lib/lm4f/uart.c b/lib/lm4f/uart.c index 725c52cb..62c19cb9 100644 --- a/lib/lm4f/uart.c +++ b/lib/lm4f/uart.c @@ -172,6 +172,13 @@ void uart_set_stopbits(uint32_t uart, uint8_t stopbits) } } +uint8_t uart_get_stopbits(uint32_t uart) +{ + if (UART_LCRH(uart) & UART_LCRH_STP2) + return 2; + return 1; +} + /** * \brief Set UART parity * From 10cfbd765269748697d14b983c94dcb57848b146 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Tue, 23 Aug 2022 03:19:59 +0100 Subject: [PATCH 202/206] lm4f/uart: Implemented a function to get the current parity setting for a UART --- include/libopencm3/lm4f/uart.h | 1 + lib/lm4f/uart.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/libopencm3/lm4f/uart.h b/include/libopencm3/lm4f/uart.h index fbde2229..920e26be 100644 --- a/include/libopencm3/lm4f/uart.h +++ b/include/libopencm3/lm4f/uart.h @@ -448,6 +448,7 @@ uint8_t uart_get_databits(uint32_t uart); void uart_set_stopbits(uint32_t uart, uint8_t stopbits); uint8_t uart_get_stopbits(uint32_t uart); void uart_set_parity(uint32_t uart, enum uart_parity parity); +enum uart_parity uart_get_parity(uint32_t uart); void uart_set_mode(uint32_t uart, uint32_t mode); void uart_set_flow_control(uint32_t uart, enum uart_flowctl flow); void uart_enable(uint32_t uart); diff --git a/lib/lm4f/uart.c b/lib/lm4f/uart.c index 62c19cb9..2835dc7a 100644 --- a/lib/lm4f/uart.c +++ b/lib/lm4f/uart.c @@ -214,6 +214,26 @@ void uart_set_parity(uint32_t uart, enum uart_parity parity) UART_LCRH(uart) = reg32; } +enum uart_parity uart_get_parity(uint32_t uart) +{ + const uint32_t reg32 = UART_LCRH(uart); + /* Check if parity is even enabled */ + if (!(reg32 & UART_LCRH_PEN)) + return UART_PARITY_NONE; + /* Check for sticky modes */ + if (reg32 & UART_LCRH_SPS) { + if (reg32 & UART_LCRH_EPS) { + return UART_PARITY_STICK_0; + } + return UART_PARITY_STICK_1; + } else { + if (reg32 & UART_LCRH_EPS) { + return UART_PARITY_EVEN; + } + return UART_PARITY_ODD; + } +} + /** * \brief Set the flow control scheme * From eaea8dc12ce9e862b0276eb3a29add4a65e13ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=B6pfl?= Date: Mon, 5 Jun 2023 14:19:31 +0200 Subject: [PATCH 203/206] usb:st usbfs-v2: fix disconnect polarity Fixes issue #1482: Incorrect interpretation of disconnected parameter in st_usbfs_v2_disconnect The `disconnected` parameter was interpreted incorrectly: When set to true it connected but should disconnect. Reviewed-by: Karl Palsson --- lib/stm32/st_usbfs_v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/stm32/st_usbfs_v2.c b/lib/stm32/st_usbfs_v2.c index f13134d4..a8ce1a83 100644 --- a/lib/stm32/st_usbfs_v2.c +++ b/lib/stm32/st_usbfs_v2.c @@ -90,9 +90,9 @@ static void st_usbfs_v2_disconnect(usbd_device *usbd_dev, bool disconnected) (void)usbd_dev; uint16_t reg = GET_REG(USB_BCDR_REG); if (disconnected) { - SET_REG(USB_BCDR_REG, reg | USB_BCDR_DPPU); - } else { SET_REG(USB_BCDR_REG, reg & ~USB_BCDR_DPPU); + } else { + SET_REG(USB_BCDR_REG, reg | USB_BCDR_DPPU); } } From 32a169207775d6c53c536d46b78ecf8eca3fdd18 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 16 Aug 2023 13:49:16 +0000 Subject: [PATCH 204/206] stm32/g4/dmamux: fix duplicated defines Fixes: https://github.com/libopencm3/libopencm3/issues/1491 Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g4/dmamux.h | 44 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/include/libopencm3/stm32/g4/dmamux.h b/include/libopencm3/stm32/g4/dmamux.h index 7876c753..44cc3cb1 100644 --- a/include/libopencm3/stm32/g4/dmamux.h +++ b/include/libopencm3/stm32/g4/dmamux.h @@ -188,29 +188,29 @@ LGPL License Terms @ref lgpl_license /* --- DMAMUX_RGxCR values ----------------------------------- */ -/** @defgroup dmamux_rgxcr_sig_id SIGID DMA request trigger input selected +/** @defgroup dmamux_rgxcr_sig_id SIG_ID DMA request trigger input selected @{*/ -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE0 0 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE1 1 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE2 2 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE3 3 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE4 4 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE5 5 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE6 6 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE7 7 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE8 8 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE9 9 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE10 10 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE11 11 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE12 12 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE13 13 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE14 14 -#define DMAMUX_CxCR_SYNC_ID_EXTI_LINE15 15 -#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH0_EVT 16 -#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH1_EVT 17 -#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH2_EVT 18 -#define DMAMUX_CxCR_SYNC_ID_DMAMUX_CH3_EVT 19 -#define DMAMUX_CxCR_SYNC_ID_LPTIM1_OUT 20 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE0 0 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE1 1 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE2 2 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE3 3 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE4 4 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE5 5 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE6 6 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE7 7 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE8 8 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE9 9 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE10 10 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE11 11 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE12 12 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE13 13 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE14 14 +#define DMAMUX_RGxCR_SIG_ID_EXTI_LINE15 15 +#define DMAMUX_RGxCR_SIG_ID_DMAMUX_CH0_EVT 16 +#define DMAMUX_RGxCR_SIG_ID_DMAMUX_CH1_EVT 17 +#define DMAMUX_RGxCR_SIG_ID_DMAMUX_CH2_EVT 18 +#define DMAMUX_RGxCR_SIG_ID_DMAMUX_CH3_EVT 19 +#define DMAMUX_RGxCR_SIG_ID_LPTIM1_OUT 20 /**@}*/ /**@}*/ From 1acf0c1f5650605bcd84f377bcd7a875fdafb9df Mon Sep 17 00:00:00 2001 From: TomasPech <44266722+TomasPech@users.noreply.github.com> Date: Tue, 3 Oct 2023 22:22:31 +0200 Subject: [PATCH 205/206] stm32g4: irc.json: fix FDCAN1_INT0/1 swap The swapped lines generated the wrong nvic.h, then jumping into the wrong ISR. See data sheet RM0440rev7 (page442, table 97). Reviewed-by: Karl Palsson --- include/libopencm3/stm32/g4/irq.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libopencm3/stm32/g4/irq.json b/include/libopencm3/stm32/g4/irq.json index fb4a91c1..6e90c5d0 100644 --- a/include/libopencm3/stm32/g4/irq.json +++ b/include/libopencm3/stm32/g4/irq.json @@ -21,8 +21,8 @@ "adc12", "usb_hp", "usb_lp", - "fdcan1_intr1", "fdcan1_intr0", + "fdcan1_intr1", "exti9_5", "tim1_brk_tim15", "tim1_up_tim16", From 1f3abd43763fa39d23e737602b6d0011a45c70b2 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 4 Oct 2023 21:44:27 +0000 Subject: [PATCH 206/206] stm32g4: irq.json: use fdcanX_itY consistently Other families used fdcanX_itY already, and that matches the terminology of the reference manual, so move to that style for consistency. Signed-off-by: Karl Palsson --- include/libopencm3/stm32/g4/irq.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/libopencm3/stm32/g4/irq.json b/include/libopencm3/stm32/g4/irq.json index 6e90c5d0..4231135d 100644 --- a/include/libopencm3/stm32/g4/irq.json +++ b/include/libopencm3/stm32/g4/irq.json @@ -21,8 +21,8 @@ "adc12", "usb_hp", "usb_lp", - "fdcan1_intr0", - "fdcan1_intr1", + "fdcan1_it0", + "fdcan1_it1", "exti9_5", "tim1_brk_tim15", "tim1_up_tim16", @@ -86,10 +86,10 @@ "i2c4_er", "spi4", "aes", - "fdcan2_intr0", - "fdcan2_intr1", - "fdcan3_intr0", - "fdcan3_intr1", + "fdcan2_it0", + "fdcan2_it1", + "fdcan3_it0", + "fdcan3_it1", "rng", "lpuart", "i2c3_ev",