From 9c36782b6d85e2ee52848041b35c0afd8c3c9779 Mon Sep 17 00:00:00 2001 From: Felix Held Date: Mon, 30 Apr 2012 00:22:56 +0200 Subject: Added support for the SDIO interface of the stm32 family. Register definition from the Datasheets; not tested in real hardware. --- include/libopencm3/stm32/sdio.h | 426 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 426 insertions(+) create mode 100644 include/libopencm3/stm32/sdio.h (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/sdio.h b/include/libopencm3/stm32/sdio.h new file mode 100644 index 0000000..cf9b056 --- /dev/null +++ b/include/libopencm3/stm32/sdio.h @@ -0,0 +1,426 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Felix Held + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_SDIO_H +#define LIBOPENCM3_SDIO_H + +#include +#include + + +/* --- SDIO registers ------------------------------------------------------ */ + +/* SDIO power control register (SDIO_POWER) */ +#define SDIO_POWER MMIO32(SDIO_BASE + 0x00) + +/* SDI clock control register (SDIO_CLKCR) */ +#define SDIO_CLKCR MMIO32(SDIO_BASE + 0x04) + +/* SDIO argument register (SDIO_ARG) */ +#define SDIO_ARG MMIO32(SDIO_BASE + 0x08) + +/* SDIO command register (SDIO_CMD) */ +#define SDIO_CMD MMIO32(SDIO_BASE + 0x0C) + +/* SDIO command response register (SDIO_RESPCMD) */ +#define SDIO_RESPCMD MMIO32(SDIO_BASE + 0x10) + +/* SDIO response 1..4 register (SDIO_RESPx) */ +#define SDIO_RESP1 MMIO32(SDIO_BASE + 0x14) +#define SDIO_RESP2 MMIO32(SDIO_BASE + 0x18) +#define SDIO_RESP3 MMIO32(SDIO_BASE + 0x1C) +#define SDIO_RESP4 MMIO32(SDIO_BASE + 0x20) + +/* SDIO data timer register (SDIO_DTIMER) */ +#define SDIO_DTIMER MMIO32(SDIO_BASE + 0x24) + +/* SDIO data length register (SDIO_DLEN) */ +#define SDIO_DLEN MMIO32(SDIO_BASE + 0x28) + +/* SDIO data control register (SDIO_DCTRL) */ +#define SDIO_DCTRL MMIO32(SDIO_BASE + 0x2C) + +/* SDIO data counter register (SDIO_DCOUNT) */ +/* read only, write has no effect */ +#define SDIO_DCOUNT MMIO32(SDIO_BASE + 0x30) + +/* SDIO status register (SDIO_STA) */ +#define SDIO_STA MMIO32(SDIO_BASE + 0x34) + +/* SDIO interrupt clear register (SDIO_ICR) */ +#define SDIO_ICR MMIO32(SDIO_BASE + 0x38) + +/* SDIO mask register (SDIO_MASK) */ +#define SDIO_MASK MMIO32(SDIO_BASE + 0x3C) + +/* SDIO FIFO counter register (SDIO_FIFOCNT) */ +#define SDIO_FIFOCNT MMIO32(SDIO_BASE + 0x48) + +/* SDIO data FIFO register (SDIO_FIFO) */ +/* the SDIO data FIFO is 32 32bit words long, beginning at this address */ +#define SDIO_FIFO MMIO32(SDIO_BASE + 0x80) + + +/* --- SDIO_POWER values --------------------------------------------------- */ + +#define SDIO_POWER_PWRCTRL_SHIFT 0 +#define SDIO_POWER_PWRCTRL_PWROFF (0x0 << SDIO_POWER_PWRCTRL_SHIFT) +/* what does "10: Reserved power-up" mean? */ +#define SDIO_POWER_PWRCTRL_RSVPWRUP (0x2 << SDIO_POWER_PWRCTRL_SHIFT) +#define SDIO_POWER_PWRCTRL_PWRON (0x3 << SDIO_POWER_PWRCTRL_SHIFT) + + +/* --- SDIO_POWER values --------------------------------------------------- */ + +/* HWFC_EN: HW Flow Control enable */ +#define SDIO_CLKCR_HWFC_EN (1 << 14) + +/* NEGEDGE: SDIO_CK dephasing selection bit */ +#define SDIO_CLKCR_NEGEDGE (1 << 13) + +/* WIDBUS: Wide bus mode enable bit */ +/* set the width of the data bus */ +#define SDIO_CLKCR_WIDBUS_SHIFT 11 +#define SDIO_CLKCR_WIDBUS_1 (0x0 << SDIO_CLKCR_WIDBUS_SHIFT) +#define SDIO_CLKCR_WIDBUS_4 (0x1 << SDIO_CLKCR_WIDBUS_SHIFT) +#define SDIO_CLKCR_WIDBUS_8 (0x2 << SDIO_CLKCR_WIDBUS_SHIFT) + +/* BYPASS: Clock divider bypass enable bit */ +#define SDIO_CLKCR_BYPASS (1 << 10) + +/* PWRSAV: Power saving configuration bit */ +#define SDIO_CLKCR_PWRSAV (1 << 9) + +/* CLKEN: Clock enable bit */ +#define SDIO_CLKCR_CLKEN (1 << 8) + +/* CLKDIV: Clock divide factor */ +#define SDIO_CLKCR_CLKDIV_SHIFT 0 +#define SDIO_CLKCR_CLKDIV_MSK (0xFF << SDIO_CLKCR_CLKDIV_SHIFT) + + +/* --- SDIO_CMD values ---------------------------------------------------- */ + +/* ATACMD: CE-ATA command */ +#define SDIO_CMD_ATACMD (1 << 14) + +/* nIEN: not Interrupt Enable */ +#define SDIO_CMD_NIEN (1 << 13) + +/* ENCMDcompl: Enable CMD completion */ +#define SDIO_CMD_ENCMDCOMPL (1 << 12) + +/* SDIOSuspend: SD I/O suspend command */ +#define SDIO_CMD_SDIOSUSPEND (1 << 11) + +/* CPSMEN: Command path state machine (CPSM) Enable bit */ +#define SDIO_CMD_CPSMEN (1 << 10) + +/* WAITPEND: CPSM Waits for ends of data transfer (CmdPend internal signal) */ +#define SDIO_CMD_WAITPEND (1 << 9) + +/* WAITINT: CPSM waits for interrupt request */ +#define SDIO_CMD_WAITINT (1 << 8) + +/* WAITRESP: Wait for response bits */ +#define SDIO_CMD_WAITRESP_SHIFT 6 +/* 00: No response, expect CMDSENT flag */ +#define SDIO_CMD_WAITRESP_NO_0 (0x0 << SDIO_CMD_WAITRESP_SHIFT) +/* 01: Short response, expect CMDREND or CCRCFAIL flag +#define SDIO_CMD_WAITRESP_SHORT (0x1 << SDIO_CMD_WAITRESP_SHIFT) +/* 10: No response, expect CMDSENT flag */ +#define SDIO_CMD_WAITRESP_NO_2 (0x2 << SDIO_CMD_WAITRESP_SHIFT) +/* 11: Long response, expect CMDREND or CCRCFAIL flag */ +#define SDIO_CMD_WAITRESP_LONG (0x3 << SDIO_CMD_WAITRESP_SHIFT) + +/* CMDINDEX: Command index */ +#define SDIO_CMD_CMDINDEX_SHIFT 0 +#define SDIO_CMD_CMDINDEX_MSK (0x3F << SDIO_CMD_CMDINDEX_SHIFT) + + +/* --- SDIO_RESPCMD values ------------------------------------------------ */ + +#define SDIO_RESPCMD_SHIFT 0 +#define SDIO_RESPCMD_MSK (0x3F << SDIO_RESPCMD_SHIFT) + + +/* --- SDIO_DCTRL values -------------------------------------------------- */ + +/* SDIOEN: SD I/O enable functions */ +#define SDIO_DCTRL_SDIOEN (1 << 11) + +/* RWMOD: Read wait mode */ +/* 0: Read Wait control stopping SDIO_D2 + * 1: Read Wait control using SDIO_CK + */ +#define SDIO_DCTRL_RWMOD (1 << 10) + +/* RWSTOP: Read wait stop */ +/* 0: Read wait in progress if RWSTART bit is set + * 1: Enable for read wait stop if RWSTART bit is set + */ +#define SDIO_DCTRL_RWSTOP (1 << 9) + +/* RWSTART: Read wait start */ +#define SDIO_DCTRL_RWSTART (1 << 8) + +/* DBLOCKSIZE: Data block size */ +/* SDIO_DCTRL_DBLOCKSIZE_n + * blocksize is 2**n bytes with 0<=n<=14 + */ +#define SDIO_DCTRL_DBLOCKSIZE_SHIFT 4 +#define SDIO_DCTRL_DBLOCKSIZE_0 (0x0 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_1 (0x1 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_2 (0x2 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_3 (0x3 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_4 (0x4 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_5 (0x5 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_6 (0x6 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_7 (0x7 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_8 (0x8 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_9 (0x9 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_10 (0xA << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_11 (0xB << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_12 (0xC << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_13 (0xD << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_DBLOCKSIZE_14 (0xE << SDIO_DCTRL_DBLOCKSIZE_SHIFT) + +/* DMAEN: DMA enable bit */ +#define SDIO_DCTRL_DMAEN (1 << 3) + +/* DTMODE: Data transfer mode selection 1: Stream or SDIO multibyte transfer */ +#define SDIO_DCTRL_DTMODE (1 << 2) + +/* DTDIR: Data transfer direction selection */ +/* 0: From controller to card. + * 1: From card to controller. + */ +#define SDIO_DCTRL_DTDIR (1 << 1) + +/* DTEN: Data transfer enabled bit */ +#define SDIO_DCTRL_DTEN (1 << 0) + + +/* --- SDIO_STA values ---------------------------------------------------- */ + +/* CEATAEND: CE-ATA command completion signal received for CMD61 */ +#define SDIO_STA_CEATAEND (1 << 23) + +/* SDIOIT: SDIO interrupt received */ +#define SDIO_STA_SDIOIT (1 << 22) + +/* RXDAVL: Data available in receive FIFO */ +#define SDIO_STA_RXDAVL (1 << 21) + +/* TXDAVL: Data available in transmit FIFO */ +#define SDIO_STA_TXDAVL (1 << 20) + +/* RXFIFOE: Receive FIFO empty */ +#define SDIO_STA_RXFIFOE (1 << 19) + +/* TXFIFOE: Transmit FIFO empty */ +/* HW Flow Control enabled -> TXFIFOE signals becomes activated when the FIFO + * contains 2 words. + */ +#define SDIO_STA_TXFIFOE (1 << 18) + +/* RXFIFOF: Receive FIFO full */ +/* HW Flow Control enabled => RXFIFOF signals becomes activated 2 words before + * the FIFO is full. + */ +#define SDIO_STA_RXFIFOF (1 << 17) + +/* TXFIFOF: Transmit FIFO full */ +#define SDIO_STA_TXFIFOF (1 << 16) + +/* RXFIFOHF: Receive FIFO half full: there are at least 8 words in the FIFO */ +#define SDIO_STA_RXFIFOHF (1 << 15) + +/* TXFIFOHE: Transmit FIFO half empty: at least 8 words can be written into + * the FIFO + */ +#define SDIO_STA_TXFIFOHE (1 << 14) + +/* RXACT: Data receive in progress */ +#define SDIO_STA_RXACT (1 << 13) + +/* TXACT: Data transmit in progress */ +#define SDIO_STA_TXACT (1 << 12) + +/* CMDACT: Command transfer in progress */ +#define SDIO_STA_CMDACT (1 << 11) + +/* DBCKEND: Data block sent/received (CRC check passed) */ +#define SDIO_STA_DBCKEND (1 << 10) + +/* STBITERR: Start bit not detected on all data signals in wide bus mode */ +#define SDIO_STA_STBITERR (1 << 9) + +/* DATAEND: Data end (data counter, SDIDCOUNT, is zero) */ +#define SDIO_STA_DATAEND (1 << 8) + +/* CMDSENT: Command sent (no response required) */ +#define SDIO_STA_CMDSENT (1 << 7) + +/* CMDREND: Command response received (CRC check passed) */ +#define SDIO_STA_CMDREND (1 << 6) + +/* RXOVERR: Received FIFO overrun error */ +#define SDIO_STA_RXOVERR (1 << 5) + +/* TXUNDERR: Transmit FIFO underrun error */ +#define SDIO_STA_TXUNDERR (1 << 4) + +/* DTIMEOUT: Data timeout */ +#define SDIO_STA_DTIMEOUT (1 << 3) + +/* CTIMEOUT: Command response timeout */ +#define SDIO_STA_CTIMEOUT (1 << 2) + +/* DCRCFAIL: Data block sent/received (CRC check failed) */ +#define SDIO_STA_DCRCFAIL (1 << 1) + +/* CCRCFAIL: Command response received (CRC check failed) */ +#define SDIO_STA_CCRCFAIL (1 << 0) + + +/* --- SDIO_ICR values ---------------------------------------------------- */ + +/* CEATAENDC: CEATAEND flag clear bit */ +#define SDIO_ICR_CEATAENDC (1 << 23) + +/* SDIOITC: SDIOIT flag clear bit */ +#define SDIO_ICR_SDIOITC (1 << 22) + +/* DBCKENDC: DBCKEND flag clear bit */ +#define SDIO_ICR_DBCKENDC (1 << 10) + +/* STBITERRC: STBITERR flag clear bit */ +#define SDIO_ICR_STBITERRC (1 << 9) + +/* DATAENDC: DATAEND flag clear bit */ +#define SDIO_ICR_DATAENDC (1 << 8) + +/* CMDSENTC: CMDSENT flag clear bit */ +#define SDIO_ICR_CMDSENTC (1 << 7) + +/* CMDRENDC: CMDREND flag clear bit */ +#define SDIO_ICR_CMDRENDC (1 << 6) + +/* RXOVERRC: RXOVERR flag clear bit */ +#define SDIO_ICR_RXOVERRC (1 << 5) + +/* TXUNDERRC: TXUNDERR flag clear bit */ +#define SDIO_ICR_TXUNDERRC (1 << 4) + +/* DTIMEOUTC: DTIMEOUT flag clear bit */ +#define SDIO_ICR_DTIMEOUTC (1 << 3) + +/* CTIMEOUTC: CTIMEOUT flag clear bit */ +#define SDIO_ICR_CTIMEOUTC (1 << 2) + +/* DCRCFAILC: DCRCFAIL flag clear bit */ +#define SDIO_ICR_DCRCFAILC (1 << 1) + +/* CCRCFAILC: CCRCFAIL flag clear bit */ +#define SDIO_ICR_CCRCFAILC (1 << 0) + + +/* --- SDIO_MASK values --------------------------------------------------- */ + +/* CEATAENDIE: CE-ATA command completion signal received interrupt enable */ +#define SDIO_MASK_CEATAENDIE (1 << 23) + +/* SDIOITIE: SDIO mode interrupt received interrupt enable */ +#define SDIO_MASK_SDIOITIE (1 << 22) + +/* RXDAVLIE: Data available in Rx FIFO interrupt enable */ +#define SDIO_MASK_RXDAVLIE (1 << 21) + +/* TXDAVLIE: Data available in Tx FIFO interrupt enable */ +#define SDIO_MASK_TXDAVLIE (1 << 20) + +/* RXFIFOEIE: Rx FIFO empty interrupt enable */ +#define SDIO_MASK_RXFIFOEIE (1 << 19) + +/* TXFIFOEIE: Tx FIFO empty interrupt enable */ +#define SDIO_MASK_TXFIFOEIE (1 << 18) + +/* RXFIFOFIE: Rx FIFO full interrupt enable */ +#define SDIO_MASK_RXFIFOFIE (1 << 17) + +/* TXFIFOFIE: Tx FIFO full interrupt enable */ +#define SDIO_MASK_TXFIFOFIE (1 << 16) + +/* RXFIFOHFIE: Rx FIFO half full interrupt enable */ +#define SDIO_MASK_RXFIFOHFIE (1 << 15) + +/* TXFIFOHEIE: Tx FIFO half empty interrupt enable */ +#define SDIO_MASK_TXFIFOHEIE (1 << 14) + +/* RXACTIE: Data receive acting interrupt enable */ +#define SDIO_MASK_RXACTIE (1 << 13) + +/* TXACTIE: Data transmit acting interrupt enable */ +#define SDIO_MASK_TXACTIE (1 << 12) + +/* CMDACTIE: Command acting interrupt enable */ +#define SDIO_MASK_CMDACTIE (1 << 11) + +/* DBCKENDIE: Data block end interrupt enable */ +#define SDIO_MASK_DBCKENDIE (1 << 10) + +/* STBITERRIE: Start bit error interrupt enable */ +#define SDIO_MASK_STBITERRIE (1 << 9) + +/* DATAENDIE: Data end interrupt enable */ +#define SDIO_MASK_DATAENDIE (1 << 8) + +/* CMDSENTIE: Command sent interrupt enable */ +#define SDIO_MASK_CMDSENTIE (1 << 7) + +/* CMDRENDIE: Command response received interrupt enable */ +#define SDIO_MASK_CMDRENDIE (1 << 6) + +/* RXOVERRIE: Rx FIFO overrun error interrupt enable */ +#define SDIO_MASK_RXOVERRIE (1 << 5) + +/* TXUNDERRIE: Tx FIFO underrun error interrupt enable */ +#define SDIO_MASK_TXUNDERRIE (1 << 4) + +/* DTIMEOUTIE: Data timeout interrupt enable */ +#define SDIO_MASK_DTIMEOUTIE (1 << 3) + +/* CTIMEOUTIE: Command timeout interrupt enable */ +#define SDIO_MASK_CTIMEOUTIE (1 << 2) + +/* DCRCFAILIE: Data CRC fail interrupt enable */ +#define SDIO_MASK_DCRCFAILIE (1 << 1) + +/* CCRCFAILIE: Command CRC fail interrupt enable */ +#define SDIO_MASK_CCRCFAILIE (1 << 0) + + +/* --- Function prototypes ------------------------------------------------- */ + + +/* TODO */ + + +#endif -- cgit v1.2.3 From 06620040aacdc0e88ee2fcc3cfa379ceea2032a9 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Mon, 28 May 2012 21:38:55 +0930 Subject: Header files for Doxygen group structure, layout changes to headings, example markup in stm32f1/ rcc --- Doxyfile | 8 +- DoxygenLayout.xml | 185 ++++++++++++++++++++++++++++++ include/libopencm3/cm3/common.h | 16 --- include/libopencm3/cm3/docmain.h | 64 +++++++++++ include/libopencm3/stm32/f1/doc-stm32f1.h | 13 +++ include/libopencm3/stm32/f1/rcc.h | 39 +++++++ lib/stm32/f1/rcc.c | 56 ++++++++- 7 files changed, 358 insertions(+), 23 deletions(-) create mode 100644 DoxygenLayout.xml create mode 100644 include/libopencm3/cm3/docmain.h create mode 100644 include/libopencm3/stm32/f1/doc-stm32f1.h (limited to 'include/libopencm3/stm32') diff --git a/Doxyfile b/Doxyfile index e5b6a38..a6f6985 100644 --- a/Doxyfile +++ b/Doxyfile @@ -640,7 +640,7 @@ RECURSIVE = YES # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -654,7 +654,7 @@ EXCLUDE_SYMLINKS = NO # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */*.d # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -1079,12 +1079,12 @@ ENUM_VALUES_PER_LINE = 4 # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. -GENERATE_TREEVIEW = NO +GENERATE_TREEVIEW = YES # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. -USE_INLINE_TREES = NO +USE_INLINE_TREES = YES # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree diff --git a/DoxygenLayout.xml b/DoxygenLayout.xml new file mode 100644 index 0000000..1a3be6f --- /dev/null +++ b/DoxygenLayout.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/libopencm3/cm3/common.h b/include/libopencm3/cm3/common.h index dc3e433..0610258 100644 --- a/include/libopencm3/cm3/common.h +++ b/include/libopencm3/cm3/common.h @@ -38,20 +38,4 @@ typedef uint64_t u64; #define MMIO32(addr) (*(volatile u32 *)(addr)) #define MMIO64(addr) (*(volatile u64 *)(addr)) -/* Main page for the doxygen-generated documentation: */ - -/** - * @mainpage libopencm3 Developer Documentation - * - * The libopencm3 project (previously known as libopenstm32) aims to create - * a free/libre/open-source (GPL v3, or later) firmware library for various - * ARM Cortex-M3 microcontrollers, including ST STM32, Toshiba TX03, - * Atmel SAM3U, NXP LPC1000 and others. - * - * @par "" - * - * See the libopencm3 wiki for - * more information. - */ - #endif diff --git a/include/libopencm3/cm3/docmain.h b/include/libopencm3/cm3/docmain.h new file mode 100644 index 0000000..865b6ea --- /dev/null +++ b/include/libopencm3/cm3/docmain.h @@ -0,0 +1,64 @@ +/** + * @mainpage libopencm3 Developer Documentation + * + * The libopencm3 project (previously known as libopenstm32) aims to create + * a free/libre/open-source (GPL v3, or later) firmware library for various + * ARM Cortex-M3 microcontrollers, including ST STM32, Toshiba TX03, + * Atmel SAM3U, NXP LPC1000 and others. + * + * @par "" + * + * See the libopencm3 wiki for + * more information. + +LGPL License Terms @ref lgpl_license + +*/ + +/** @page lgpl_license libopencm3 License + +libopencm3 is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +libopencm3 is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with this +program. If not, see . + +*/ + +/** @defgroup LM3S +Libraries for Texas instruments LM3S series. +*/ + +/** @defgroup LPC13xx +Libraries for NXP Semiconductor LPC13xx series. +*/ + +/** @defgroup LPC17xx +Libraries for NXP Semiconductor LPC17xx series. +*/ + +/** @defgroup STM32F +Libraries for ST Microelectronics STM32F series. +*/ + +/** @defgroup STM32F1xx +@ingroup STM32F +Libraries for ST Microelectronics STM32F1xx series. +*/ + +/** @defgroup STM32F2xx +@ingroup STM32F +Libraries for ST Microelectronics STM32F2xx series. +*/ + +/** @defgroup STM32F4xx +@ingroup STM32F +Libraries for ST Microelectronics STM32F4xx series. +*/ + diff --git a/include/libopencm3/stm32/f1/doc-stm32f1.h b/include/libopencm3/stm32/f1/doc-stm32f1.h new file mode 100644 index 0000000..33bae3a --- /dev/null +++ b/include/libopencm3/stm32/f1/doc-stm32f1.h @@ -0,0 +1,13 @@ +/** @defgroup STM32F1xx_defines + +@brief Defined Constants and Types for the STM32F1xx series + +@ingroup STM32F1xx + +@version 1.0.0 + +@date 24 May 2012 + +LGPL License Terms @ref lgpl_license + */ + diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index 9cbe1e7..3d199a3 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -1,3 +1,27 @@ +/** @file + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Reset and Clock Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Federico Ruiz-Ugalde \ +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann + +@date 18 May 2012 + +LGPL License Terms @ref lgpl_license + */ +/** @defgroup STM32F1xx_rcc_defines + +@brief Defined Constants and Types for the STM32F1xx Reset and Clock Control + +@ingroup STM32F1xx_defines + +LGPL License Terms @ref lgpl_license + + */ /* * This file is part of the libopencm3 project. * @@ -230,6 +254,10 @@ /* --- RCC_AHBENR values --------------------------------------------------- */ +/** @defgroup rcc_ahbenr_en RCC_AHBENR enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_AHBENR_ETHMACENRX (1 << 16) #define RCC_AHBENR_ETHMACENTX (1 << 15) #define RCC_AHBENR_ETHMACEN (1 << 14) @@ -241,9 +269,14 @@ #define RCC_AHBENR_SRAMEN (1 << 2) #define RCC_AHBENR_DMA2EN (1 << 1) #define RCC_AHBENR_DMA1EN (1 << 0) +/*@}*/ /* --- RCC_APB2ENR values -------------------------------------------------- */ +/** @defgroup rcc_apb2enr_en RCC_APB2ENR enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_APB2ENR_ADC3EN (1 << 15) /* (XX) */ #define RCC_APB2ENR_USART1EN (1 << 14) #define RCC_APB2ENR_TIM8EN (1 << 13) /* (XX) */ @@ -259,9 +292,14 @@ #define RCC_APB2ENR_IOPBEN (1 << 3) #define RCC_APB2ENR_IOPAEN (1 << 2) #define RCC_APB2ENR_AFIOEN (1 << 0) +/*@}*/ /* --- RCC_APB1ENR values -------------------------------------------------- */ +/** @defgroup rcc_apb1enr_en RCC_APB1ENR enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_APB1ENR_DACEN (1 << 29) #define RCC_APB1ENR_PWREN (1 << 28) #define RCC_APB1ENR_BKPEN (1 << 27) @@ -284,6 +322,7 @@ #define RCC_APB1ENR_TIM4EN (1 << 2) #define RCC_APB1ENR_TIM3EN (1 << 1) #define RCC_APB1ENR_TIM2EN (1 << 0) +/*@}*/ /* --- RCC_BDCR values ----------------------------------------------------- */ diff --git a/lib/stm32/f1/rcc.c b/lib/stm32/f1/rcc.c index 8945e80..e700074 100644 --- a/lib/stm32/f1/rcc.c +++ b/lib/stm32/f1/rcc.c @@ -1,8 +1,34 @@ +/** @file + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Reset and Clock Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Federico Ruiz-Ugalde \ +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 May 2012 + +This library supports the Reset and Clock +Control System in the STM32F1xx series of ARM Cortex Microcontrollers +by ST Microelectronics. + +Clock settings and resets for many peripherals are given here rather than in the +peripheral library. + +The library also provides a number of common configurations for the processor +system clock. Not all possible configurations are given here. + +@bugs None known + +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 * * This library is free software: you can redistribute it and/or modify @@ -19,13 +45,23 @@ * along with this library. If not, see . */ + #include #include -/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset. */ +/** Default ppre1 peripheral clock frequency after reset. */ u32 rcc_ppre1_frequency = 8000000; +/** Default ppre2 peripheral clock frequency after reset. */ u32 rcc_ppre2_frequency = 8000000; +//----------------------------------------------------------------------------- +/** @brief RCC Clear the Oscillator Ready Interrupt + +Clear the interrupt flag that was set when a clock oscillator became ready to use. + +@param[in] enum ::osc_t. Oscillator ID +*/ + void rcc_osc_ready_int_clear(osc_t osc) { switch (osc) { @@ -230,6 +266,20 @@ void rcc_osc_bypass_disable(osc_t osc) } } +//----------------------------------------------------------------------------- +/** @brief RCC Enable a peripheral clock. + +Enable the clock on a particular peripheral. Several peripherals could be +enabled simultaneously if they are controlled by the same register. + +@param[in] Unsigned int32 *reg. Pointer to a Clock Enable Register + (either RCC_AHBENR, RCC_APB1RENR or RCC_APB2RENR) +@param[in] Unsigned int32 en. OR of all enables to be set +@li If register is RCC_AHBER, from @ref rcc_ahbenr_en +@li If register is RCC_APB1RENR, from @ref rcc_apb1enr_en +@li If register is RCC_APB2RENR, from @ref rcc_apb2enr_en +*/ + void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en) { *reg |= en; -- cgit v1.2.3 From 9531d653fb83bd9864a882a190f286a92499ca72 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 11 Jun 2012 12:45:58 +0000 Subject: Even/Odd parity bit configs used the wrong bit Checked F10x, F100, F4 and L1 reference manuals. Confirmed with my user application code. --- include/libopencm3/stm32/usart.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/usart.h b/include/libopencm3/stm32/usart.h index d9f2c8d..5c7f285 100644 --- a/include/libopencm3/stm32/usart.h +++ b/include/libopencm3/stm32/usart.h @@ -270,8 +270,8 @@ /* CR1_PCE / CR1_PS combined values */ #define USART_PARITY_NONE 0x00 -#define USART_PARITY_ODD USART_CR1_PS -#define USART_PARITY_EVEN (USART_CR1_PS | USART_CR1_PCE) +#define USART_PARITY_EVEN USART_CR1_PCE +#define USART_PARITY_ODD (USART_CR1_PS | USART_CR1_PCE) #define USART_PARITY_MASK (USART_CR1_PS | USART_CR1_PCE) /* CR1_TE/CR1_RE combined values */ -- cgit v1.2.3 From 71a3a7f2b134115c9851ff38314a74c4a2f9c5d3 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 7 Jun 2012 15:41:42 +0000 Subject: Add Device Electronic Signature support. Working unique id support, but not 100% convinced that this is the "least surprise" path. ST's docs provide the bits from low to high, in 2xu16 and 2xu32. But to get it back as a "u96" the highest bits should be first? --- include/libopencm3/stm32/f1/desig.h | 52 +++++++++++++++++++++++++++++++++ include/libopencm3/stm32/f1/memorymap.h | 5 ++++ lib/stm32/f1/Makefile | 2 +- lib/stm32/f1/desig.c | 37 +++++++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 include/libopencm3/stm32/f1/desig.h create mode 100644 lib/stm32/f1/desig.c (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/f1/desig.h b/include/libopencm3/stm32/f1/desig.h new file mode 100644 index 0000000..743e946 --- /dev/null +++ b/include/libopencm3/stm32/f1/desig.h @@ -0,0 +1,52 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_DESIG_H +#define LIBOPENCM3_DESIG_H + +#include +#include + +/* --- Device Electronic Signature -------------------------------- */ + +/* Flash size register */ +#define DESIG_FLASH_SIZE MMIO16(DESIG_FLASH_SIZE_BASE + 0x00) + +/* Unique ID register (96 bits) */ +/* Note: ST says these may be accessed in any width if you choose */ +#define DESIG_UID_15_0 MMIO16(DESIG_UNIQUE_ID_BASE + 0x00) +/* Listed as "This field value is also reserved for a future feature" WTH?! */ +#define DESIG_UID_31_16 MMIO16(DESIG_UNIQUE_ID_BASE + 0x02) +#define DESIG_UID_63_32 MMIO32(DESIG_UNIQUE_ID_BASE + 0x04) +#define DESIG_UID_95_64 MMIO32(DESIG_UNIQUE_ID_BASE + 0x08) + +/** + * Read the onboard flash size + * @return flash size in KB + */ +u16 desig_get_flash_size(void); + +/** + * Read the full 96 bit unique identifier + * Note: ST specifies that bits 31..16 are _also_ reserved for future use + * @param result pointer to at least 3xu32s (96 bits) + */ +void desig_get_unique_id(u32 result[]); + +#endif diff --git a/include/libopencm3/stm32/f1/memorymap.h b/include/libopencm3/stm32/f1/memorymap.h index f8528d4..5cc432e 100644 --- a/include/libopencm3/stm32/f1/memorymap.h +++ b/include/libopencm3/stm32/f1/memorymap.h @@ -26,6 +26,7 @@ /* Memory map for all busses */ #define PERIPH_BASE ((u32)0x40000000) +#define INFO_BASE ((u32)0x1ffff000) #define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) #define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) #define PERIPH_BASE_AHB (PERIPH_BASE + 0x18000) @@ -110,4 +111,8 @@ /* FSMC */ #define FSMC_BASE (PERIPH_BASE + 0x60000000) +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x7e0) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x7e8) + #endif diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index d598f84..40c109a 100644 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -31,7 +31,7 @@ ARFLAGS = rcs OBJS = vector.o rcc.o gpio.o usart.o adc.o spi.o flash.o nvic.o \ rtc.o i2c.o dma.o systick.o exti.o scb.o ethernet.o \ usb_f103.o usb.o usb_control.o usb_standard.o can.o \ - timer.o usb_f107.o + timer.o usb_f107.o desig.o VPATH += ../../usb:../ diff --git a/lib/stm32/f1/desig.c b/lib/stm32/f1/desig.c new file mode 100644 index 0000000..7ae968e --- /dev/null +++ b/lib/stm32/f1/desig.c @@ -0,0 +1,37 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +u16 desig_get_flash_size(void) +{ + return DESIG_FLASH_SIZE; +} + +void desig_get_unique_id(u32 result[]) +{ + // Could also just return a pointer to the start? read it as they wish? + u16 bits15_0 = DESIG_UID_15_0; + u32 bits31_16 = DESIG_UID_31_16; + u32 bits63_32 = DESIG_UID_63_32; + u32 bits95_64 = DESIG_UID_95_64; + result[0] = bits95_64; + result[1] = bits63_32; + result[2] = bits31_16 << 16 | bits15_0; +} -- cgit v1.2.3 From 62849f043c9e1d9bf06f964d0be516301dfe82a4 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 12 Jun 2012 15:23:16 +0000 Subject: Add helper function for max clock on HSI for f100 Based on existing HSI code. Tested with f100c8, on custom board with no external crystals or resonators. --- include/libopencm3/stm32/f1/rcc.h | 5 +++++ lib/stm32/f1/rcc.c | 47 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index 9cbe1e7..6ce2340 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -408,6 +408,11 @@ void rcc_set_usbpre(u32 usbpre); u32 rcc_get_system_clock_source(int i); void rcc_clock_setup_in_hsi_out_64mhz(void); void rcc_clock_setup_in_hsi_out_48mhz(void); + +/** + * Maximum speed possible for F100 (Value Line) on HSI + */ +void rcc_clock_setup_in_hsi_out_24mhz(void); void rcc_clock_setup_in_hse_8mhz_out_24mhz(void); void rcc_clock_setup_in_hse_8mhz_out_72mhz(void); void rcc_clock_setup_in_hse_12mhz_out_72mhz(void); diff --git a/lib/stm32/f1/rcc.c b/lib/stm32/f1/rcc.c index 8945e80..d127074 100644 --- a/lib/stm32/f1/rcc.c +++ b/lib/stm32/f1/rcc.c @@ -436,6 +436,53 @@ void rcc_clock_setup_in_hsi_out_48mhz(void) rcc_ppre2_frequency = 48000000; } +void rcc_clock_setup_in_hsi_out_24mhz(void) { + /* Enable internal high-speed oscillator. */ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 12MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 24MHz */ + + /* + * Sysclk is (will be) running with 24MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_0WS); + + /* + * Set the PLL multiplication factor to 6. + * 8MHz (internal) * 6 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 24MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL6); + + /* Select HSI/2 as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ppre1_frequency = 24000000; + rcc_ppre2_frequency = 24000000; +} + + void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) { /* Enable internal high-speed oscillator. */ -- cgit v1.2.3 From 2f4cd293248b012c87be34d4f45786b7f8c06770 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Wed, 13 Jun 2012 22:14:53 +0930 Subject: Code for iwdg module STM32F series --- include/libopencm3/stm32/iwdg.h | 8 ++- lib/stm32/iwdg.c | 146 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 lib/stm32/iwdg.c (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/iwdg.h b/include/libopencm3/stm32/iwdg.h index 2d24482..2a8ee9d 100644 --- a/include/libopencm3/stm32/iwdg.h +++ b/include/libopencm3/stm32/iwdg.h @@ -78,8 +78,12 @@ /* PVU: Watchdog prescaler value update */ #define IWDG_SR_PVU (1 << 0) -/* --- IWDG funtion prototypes---------------------------------------------- */ +/* --- IWDG function prototypes---------------------------------------------- */ -/* TODO */ +void iwdg_start(void); +void iwdg_set_period_ms(u32 period); +bool iwdg_reload_busy(void); +bool iwdg_prescaler_busy(void); +void iwdg_reset(void); #endif diff --git a/lib/stm32/iwdg.c b/lib/stm32/iwdg.c new file mode 100644 index 0000000..a4a15ec --- /dev/null +++ b/lib/stm32/iwdg.c @@ -0,0 +1,146 @@ +/** @file + +@ingroup STM32F + +@brief libopencm3 STM32F1xx Independent Watchdog Timer + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +@date 11 June 2012 + +This library supports the Independent Watchdog Timer System in the STM32F1xx +series of ARM Cortex Microcontrollers by ST Microelectronics. + +The watchdog timer uses the LSI (low speed internal) clock which is low power +and continues to operate during stop and standby modes. Its frequency is +nominally 32kHz (40kHz for the STM32F1xx series) but can vary from as low +as 17kHz up to 60kHz (refer to datasheet electrical characteristics). + +Note that the User Configuration option byte provides a means of automatically +enabling the IWDG timer at power on (with counter value 0xFFF). If the +relevant bit is not set, the IWDG timer must be enabled by software. + +@bugs None known + +@note: Tested: CPU STM32F103RET6, Board ET-ARM Stamp STM32 + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#define LSI_FREQUENCY 32000 + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Enable Watchdog Timer + +The watchdog timer is started. The timeout period defaults to 512 milliseconds +unless it has been previously defined. + +*/ + +void iwdg_start(void) +{ + IWDG_KR = IWDG_KR_START; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Set Period in Milliseconds + +The countdown period is converted into count and prescale values. The maximum +period is 32.76 seconds; values above this are truncated. Periods less than 1ms +are not supported by this library. + +A delay of up to 5 clock cycles of the LSI clock (about 156 microseconds) +can occasionally occur if the prescale or preload registers are currently busy +loading a previous value. + +@param[in] u32 Period in milliseconds (< 32760) from a watchdog reset until +a system reset is issued. +*/ + +#define COUNT_LENGTH 12 +#define COUNT_MASK ((1 << COUNT_LENGTH)-1) + +void iwdg_set_period_ms(u32 period) +{ +u32 count, prescale, reload, exponent; +/* Set the count to represent ticks of the 32kHz LSI clock */ + count = (period << 5); +/* Strip off the first 12 bits to get the prescale value required */ + prescale = (count >> 12); + if (prescale > 256) {exponent = IWDG_PR_DIV256; reload = COUNT_MASK;} + else if (prescale > 128) {exponent = IWDG_PR_DIV256; reload = (count >> 8);} + else if (prescale > 64) {exponent = IWDG_PR_DIV128; reload = (count >> 7);} + else if (prescale > 32) {exponent = IWDG_PR_DIV64; reload = (count >> 6);} + else if (prescale > 16) {exponent = IWDG_PR_DIV32; reload = (count >> 5);} + else if (prescale > 8) {exponent = IWDG_PR_DIV16; reload = (count >> 4);} + else if (prescale > 4) {exponent = IWDG_PR_DIV8; reload = (count >> 3);} + else {exponent = IWDG_PR_DIV4; reload = (count >> 2);} +/* Avoid the undefined situation of a zero count */ + if (count == 0) count = 1; + + while (iwdg_prescaler_busy()); + IWDG_KR = IWDG_KR_UNLOCK; + IWDG_PR = exponent; + while (iwdg_reload_busy()); + IWDG_KR = IWDG_KR_UNLOCK; + IWDG_RLR = (reload & COUNT_MASK); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Get Reload Register Status + +@returns boolean: TRUE if the reload register is busy and unavailable for loading +a new count value. +*/ + +bool iwdg_reload_busy(void) +{ + return (IWDG_SR & IWDG_SR_RVU); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG Get Prescaler Register Status + +@returns boolean: TRUE if the prescaler register is busy and unavailable for loading +a new period value. +*/ + +bool iwdg_prescaler_busy(void) +{ + return (IWDG_SR & IWDG_SR_PVU); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief IWDG reset Watchdog Timer + +The watchdog timer is reset. The counter restarts from the value in the reload +register. +*/ + +void iwdg_reset(void) +{ + IWDG_KR = IWDG_KR_RESET; +} + -- cgit v1.2.3 From 450c3e00a16c3d8bf1a9282d2ca4b45e8b4d9045 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 18 Jun 2012 18:57:45 +0000 Subject: Basic helper routines for CRC Note, the CRC block is pretty useless for interoperability. It only operates on 32bit chunks, and in a different bit order. No attempt to make full helpers for compatibility with other implementations has been done. https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FCRC%20computation&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=2006 --- include/libopencm3/stm32/crc.h | 20 +++++++++++++++++++ lib/stm32/crc.c | 44 ++++++++++++++++++++++++++++++++++++++++++ lib/stm32/f1/Makefile | 2 +- 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 lib/stm32/crc.c (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/crc.h b/include/libopencm3/stm32/crc.h index 6ae4085..7d80259 100644 --- a/include/libopencm3/stm32/crc.h +++ b/include/libopencm3/stm32/crc.h @@ -55,4 +55,24 @@ /* TODO */ +/** + * Reset the CRC calculator to initial values. + */ +void crc_reset(void); + +/** + * Add a word to the crc calculator and return the result. + * @param data new word to add to the crc calculator + * @return final crc calculator value + */ +u32 crc_calculate(u32 data); + +/** + * Add a block of data to the CRC calculator and return the final result + * @param datap pointer to the start of a block of 32bit data words + * @param size length of data, in 32bit increments + * @return final CRC calculator value + */ +u32 crc_calculate_block(u32 *datap, int size); + #endif diff --git a/lib/stm32/crc.c b/lib/stm32/crc.c new file mode 100644 index 0000000..bbbe1fd --- /dev/null +++ b/lib/stm32/crc.c @@ -0,0 +1,44 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +void crc_reset(void) +{ + CRC_CR |= CRC_CR_RESET; +} + +u32 crc_calculate(u32 data) +{ + CRC_DR = data; + // Data sheet says this blocks until it's ready.... + return CRC_DR; +} + +u32 crc_calculate_block(u32 *datap, int size) +{ + int i; + for (i = 0; i < size; i++) { + CRC_DR = datap[i]; + } + return CRC_DR; +} + + + diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index 40c109a..0059ba1 100644 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -31,7 +31,7 @@ ARFLAGS = rcs OBJS = vector.o rcc.o gpio.o usart.o adc.o spi.o flash.o nvic.o \ rtc.o i2c.o dma.o systick.o exti.o scb.o ethernet.o \ usb_f103.o usb.o usb_control.o usb_standard.o can.o \ - timer.o usb_f107.o desig.o + timer.o usb_f107.o desig.o crc.o VPATH += ../../usb:../ -- cgit v1.2.3 From 0e02438a80030c60619a170d00c9edca3773fffc Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Sat, 30 Jun 2012 16:56:14 +0930 Subject: Code for DAC module STM32Fxxx series Add prototypes to dac.h and small change to simplify alignment enum --- .gitignore | 4 + include/libopencm3/stm32/dac.h | 130 ++++++++++- lib/stm32/dac.c | 517 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 644 insertions(+), 7 deletions(-) create mode 100644 lib/stm32/dac.c (limited to 'include/libopencm3/stm32') diff --git a/.gitignore b/.gitignore index f0c86ce..63b7b48 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ *.swp \#* .\#* +*~ +*.map +*.log +doxygen/ diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h index 0402eb0..6a778b5 100644 --- a/include/libopencm3/stm32/dac.h +++ b/include/libopencm3/stm32/dac.h @@ -1,3 +1,27 @@ +/** @file + +@ingroup STM32F + +@brief libopencm3 STM32F1xx Digital to Analog Converter + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Felix Held +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 30 June 2012 + +LGPL License Terms @ref lgpl_license + */ +/** @defgroup STM32F1xx_dac_defines + +@brief Defined Constants and Types for the STM32F1xx Digital to Analog Converter + +@ingroup STM32F1xx_defines + +LGPL License Terms @ref lgpl_license + + */ /* * This file is part of the libopencm3 project. * @@ -69,7 +93,7 @@ /* --- DAC_CR values ------------------------------------------------------- */ /* DMAUDRIE2: DAC channel2 DMA underrun interrupt enable */ -/* doesn't exist in most members of the stm32f1 family */ +/* doesn't exist in most members of the STM32F1 family */ #define DAC_CR_DMAUDRIE2 (1 << 29) /* DMAEN2: DAC channel2 DMA enable */ @@ -80,6 +104,11 @@ * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 */ #define DAC_CR_MAMP2_SHIFT 24 +/** @defgroup dac_mamp2 DAC Channel 2 LFSR Mask and Triangle Wave Amplitude values +@ingroup STM32F1xx_dac_defines + +Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 +@{*/ #define DAC_CR_MAMP2_1 (0x0 << DAC_CR_MAMP2_SHIFT) #define DAC_CR_MAMP2_2 (0x1 << DAC_CR_MAMP2_SHIFT) #define DAC_CR_MAMP2_3 (0x2 << DAC_CR_MAMP2_SHIFT) @@ -92,6 +121,7 @@ #define DAC_CR_MAMP2_10 (0x9 << DAC_CR_MAMP2_SHIFT) #define DAC_CR_MAMP2_11 (0xA << DAC_CR_MAMP2_SHIFT) #define DAC_CR_MAMP2_12 (0xB << DAC_CR_MAMP2_SHIFT) +/*@}*/ /* WAVE2[1:0]: DAC channel2 noise/triangle wave generation enable */ /* Legend: @@ -102,9 +132,18 @@ * Note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) */ #define DAC_CR_WAVE2_SHIFT 22 -#define DAC_CR_WAVE2_DIS (0x0 << DAC_CR_WAVE2_SHIFT) +#define DAC_CR_WAVE2_DIS (0x3 << DAC_CR_WAVE2_SHIFT) +/** @defgroup dac_wave2_en DAC Channel 2 Waveform Generation Enable +@ingroup STM32F1xx_dac_defines + +@li NOISE: Noise wave generation enabled +@li TRI: Triangle wave generation enabled + +@note: only used if bit TEN2 is set (DAC channel2 trigger enabled) +@{*/ #define DAC_CR_WAVE2_NOISE (0x1 << DAC_CR_WAVE2_SHIFT) #define DAC_CR_WAVE2_TRI (0x2 << DAC_CR_WAVE2_SHIFT) +/*@}*/ /* TSEL2[2:0]: DAC channel2 trigger selection */ /* Legend: @@ -125,6 +164,25 @@ * Note: this is *not* valid for the STM32L1 family */ #define DAC_CR_TSEL2_SHIFT 19 +/** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection +@ingroup STM32F1xx_dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN2 is set (DAC channel 2 trigger enabled) +@{*/ #define DAC_CR_TSEL2_T6 (0x0 << DAC_CR_TSEL2_SHIFT) #define DAC_CR_TSEL2_T3 (0x1 << DAC_CR_TSEL2_SHIFT) #define DAC_CR_TSEL2_T8 (0x1 << DAC_CR_TSEL2_SHIFT) @@ -135,6 +193,7 @@ #define DAC_CR_TSEL2_T4 (0x5 << DAC_CR_TSEL2_SHIFT) #define DAC_CR_TSEL2_E9 (0x6 << DAC_CR_TSEL2_SHIFT) #define DAC_CR_TSEL2_SW (0x7 << DAC_CR_TSEL2_SHIFT) +/*@}*/ /* TEN2: DAC channel2 trigger enable */ #define DAC_CR_TEN2 (1 << 18) @@ -146,7 +205,7 @@ #define DAC_CR_EN2 (1 << 16) /* DMAUDRIE1: DAC channel1 DMA underrun interrupt enable */ -/* doesn't exist in most members of the stm32f1 family */ +/* doesn't exist in most members of the STM32F1 family */ #define DAC_CR_DMAUDRIE1 (1 << 13) /* DMAEN1: DAC channel1 DMA enable */ @@ -157,6 +216,11 @@ * Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**n)-1 */ #define DAC_CR_MAMP1_SHIFT 8 +/** @defgroup dac_mamp1 DAC Channel 1 LFSR Mask and Triangle Wave Amplitude values +@ingroup STM32F1xx_dac_defines + +Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 +@{*/ #define DAC_CR_MAMP1_1 (0x0 << DAC_CR_MAMP1_SHIFT) #define DAC_CR_MAMP1_2 (0x1 << DAC_CR_MAMP1_SHIFT) #define DAC_CR_MAMP1_3 (0x2 << DAC_CR_MAMP1_SHIFT) @@ -169,6 +233,7 @@ #define DAC_CR_MAMP1_10 (0x9 << DAC_CR_MAMP1_SHIFT) #define DAC_CR_MAMP1_11 (0xA << DAC_CR_MAMP1_SHIFT) #define DAC_CR_MAMP1_12 (0xB << DAC_CR_MAMP1_SHIFT) +/*@}*/ /* WAVE1[1:0]: DAC channel1 noise/triangle wave generation enable */ /* Legend: @@ -179,9 +244,19 @@ * Note: only used if bit TEN1 = 1 (DAC channel1 trigger enabled) */ #define DAC_CR_WAVE1_SHIFT 6 -#define DAC_CR_WAVE1_DIS (0x0 << DAC_CR_WAVE1_SHIFT) +#define DAC_CR_WAVE1_DIS (0x3 << DAC_CR_WAVE1_SHIFT) +/** @defgroup dac_wave1_en DAC Channel 1 Waveform Generation Enable +@ingroup STM32F1xx_dac_defines + +@li DIS: wave generation disabled +@li NOISE: Noise wave generation enabled +@li TRI: Triangle wave generation enabled + +@note: only used if bit TEN2 = 1 (DAC channel2 trigger enabled) +@{*/ #define DAC_CR_WAVE1_NOISE (0x1 << DAC_CR_WAVE1_SHIFT) #define DAC_CR_WAVE1_TRI (0x2 << DAC_CR_WAVE1_SHIFT) +/*@}*/ /* TSEL1[2:0]: DAC channel1 trigger selection */ /* Legend: @@ -202,6 +277,25 @@ * Note: this is *not* valid for the STM32L1 family */ #define DAC_CR_TSEL1_SHIFT 3 +/** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection +@ingroup STM32F1xx_dac_defines + +@li T6: Timer 6 TRGO event +@li T3: Timer 3 TRGO event +@li T8: Timer 8 TRGO event +@li T7: Timer 7 TRGO event +@li T5: Timer 5 TRGO event +@li T15: Timer 15 TRGO event +@li T2: Timer 2 TRGO event +@li T4: Timer 4 TRGO event +@li E9: External line 9 +@li SW: Software trigger + +@note: Refer to the timer documentation for details of the TRGO event. +@note: T3 replaced by T8 and T5 replaced by T15 in some devices. +@note: this is not valid for the STM32L1 family. +@note: only used if bit TEN2 is set (DAC channel 1 trigger enabled). +@{*/ #define DAC_CR_TSEL1_T6 (0x0 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_T3 (0x1 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_T8 (0x1 << DAC_CR_TSEL1_SHIFT) @@ -212,6 +306,7 @@ #define DAC_CR_TSEL1_T4 (0x5 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_E9 (0x6 << DAC_CR_TSEL1_SHIFT) #define DAC_CR_TSEL1_SW (0x7 << DAC_CR_TSEL1_SHIFT) +/*@}*/ /* TEN1: DAC channel1 trigger enable */ #define DAC_CR_TEN1 (1 << 2) @@ -292,11 +387,32 @@ #define DAC_DOR2_DACC2DOR_LSB (1 << 0) #define DAC_DOR2_DACC2DOR_MSK (0x0FFF << 0) +/** DAC channel identifier */ +typedef enum { + CHANNEL_1, CHANNEL_2, CHANNEL_D +} data_channel; -/* --- Function prototypes ------------------------------------------------- */ +/** DAC data size (8/12 bits), alignment (right/left) */ +typedef enum { + RIGHT8, RIGHT12, LEFT12 +} data_align; +/* --- Function prototypes ------------------------------------------------- */ -/* TODO */ - +void dac_enable(data_channel dac_channel); +void dac_disable(data_channel dac_channel); +void dac_buffer_enable(data_channel dac_channel); +void dac_buffer_disable(data_channel dac_channel); +void dac_dma_enable(data_channel dac_channel); +void dac_dma_disable(data_channel dac_channel); +void dac_trigger_enable(data_channel dac_channel); +void dac_trigger_disable(data_channel dac_channel); +void dac_set_trigger_source(u32 dac_trig_src); +void dac_set_waveform_generation(u32 dac_wave_ens); +void dac_disable_waveform_generation(data_channel dac_channel); +void dac_set_waveform_characteristics(u32 dac_mamp); +void dac_load_data_buffer_single(u32 dac_data, data_align dac_data_format, data_channel dac_channel); +void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data_format); +void dac_software_trigger(data_channel dac_channel); #endif diff --git a/lib/stm32/dac.c b/lib/stm32/dac.c new file mode 100644 index 0000000..deec130 --- /dev/null +++ b/lib/stm32/dac.c @@ -0,0 +1,517 @@ +/** @file + +@ingroup STM32F + +@brief libopencm3 STM32Fxx Digital to Analog Converter + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 30 June 2012 + +This library supports the Digital to Analog Conversion System in the +STM32F series of ARM Cortex Microcontrollers by ST Microelectronics. + +The DAC is present only in a limited set of devices, notably some +of the connection line, high density and XL devices. + +Two DAC channels are available, however unlike the ADC channels these +are separate DAC devices controlled by the same register block. + +The DAC is on APB1. Its clock must be enabled in RCC and the GPIO +ports set to alternate function output before it can be used. +The digital output driver is disabled so the output driver mode +(push-pull/open drain) is arbitrary. + +The DAC has a holding (buffer) register and an output register from +which the analog output is derived. The holding register must be +loaded first. If triggering is enabled the output register is loaded +from the holding register after a trigger occurs. If triggering is +not enabled the holding register contents are transferred directly +to the output register. + +@note To avoid nonlinearities, do not allow outputs to range close +to zero or V_analog. + +@section dac_api_dual Dual Channel Conversion + +There are dual modes in which both DACs are used to output data +simultaneously or independently on both channels. The data must be +presented according to the formats described in the datasheets. A +convenience function @ref dac_load_data_buffer_dual is provided +for software controlled use. + +A variety of modes are available depending on whether independent +or simultaneous output is desired, and whether waveforms are to be +superimposed. Refer to the datasheets. + +If DMA is used, only enable it for one of the channels. The DMA +requests will then serve data in dual format to the data register +dedicated to dual mode. The data will then be split and loaded to the +appropriate DAC following the next trigger. There are three registers +available, one for each of the formats: 12 bit right-aligned, 12 bit +left-aligned and 8 bit right-aligned. The desired format is determined +by specifying the appropriate register to the DMA controller. + +@section dac_api_basic_ex Basic DAC handling API. + +Set the DAC's GPIO port to any alternate function output mode. Enable the +DAC clock. Enable the DAC, set a trigger source and load the buffer +with the first value. After the DAC is triggered, load the buffer with +the next value. This example uses software triggering and added noise. +The trigger and further buffer load calls are made when data is to be +sent out. + +@code + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_DACEN); + dac_disable(CHANNEL_1); + dac_set_waveform_characteristics(DAC_CR_MAMP1_8); + dac_set_waveform_generation(DAC_CR_WAVE1_NOISE); + dac_enable(CHANNEL_1); + dac_set_trigger_source(DAC_CR_TSEL1_SW); + dac_load_data_buffer_single(0, RIGHT12, CHANNEL_1); + .... + dac_software_trigger(CHANNEL_1); + dac_load_data_buffer_single(value, RIGHT12, CHANNEL_1); +@endcode + +@section dac_api_dma_ex Simultaneous Dual DAC with DMA. + +This example in part sets up the DAC channel 1 DMA (DMA2 channel 3) to read +16 bit data from memory into the right-aligned 8 bit dual register DAC_DHR8RD. +Both DAC channels are enabled, and both triggers are set to the same timer +2 input as required for simultaneous operation. DMA is enabled for DAC channel +1 only to ensure that only one DMA request is generated. + +@code + dma_set_memory_size(DMA2,DMA_CHANNEL3,DMA_CCR_MSIZE_16BIT); + dma_set_peripheral_size(DMA2,DMA_CHANNEL3,DMA_CCR_PSIZE_16BIT); + dma_set_read_from_memory(DMA2,DMA_CHANNEL3); + dma_set_peripheral_address(DMA2,DMA_CHANNEL3,(u32) &DAC_DHR8RD); + dma_enable_channel(DMA2,DMA_CHANNEL3); + ... + dac_trigger_enable(CHANNEL_D); + dac_set_trigger_source(DAC_CR_TSEL1_T2 | DAC_CR_TSEL2_T2); + dac_dma_enable(CHANNEL_1); + dac_enable(CHANNEL_D); +@endcode + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +#define MASK8 0xFF +#define MASK12 0xFFF + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Enable. + +Enable a digital to analog converter channel. After setting this enable, the DAC +requires a twakeup time typically around 10 microseconds before it +actually wakes up. + +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_EN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_EN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_EN1 | DAC_CR_EN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Disable. + +Disable a digital to analog converter channel. + +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_EN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_EN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_EN1 | DAC_CR_EN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Output Buffer Enable. + +Enable a digital to analog converter channel output drive buffer. This is an optional +amplifying buffer that provides additional drive for the output signal. The +buffer is enabled by default after a reset and needs to be explicitly disabled +if required. + +@param[in] enum ::data_channel, dac_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] enum ::data_channel, dac_channel. +*/ + +void dac_buffer_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_BOFF1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_BOFF2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_BOFF1 | DAC_CR_BOFF2); + break; + } +} +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel DMA Enable. + +Enable a digital to analog converter channel DMA mode (connected to DMA2 channel +3 for DAC channel 1 and DMA2 channel 4 for DAC channel 2). A DMA request is +generated following an external trigger. + +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_dma_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_DMAEN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_DMAEN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel DMA Disable. + +Disable a digital to analog converter channel DMA mode. + +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_dma_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_DMAEN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_DMAEN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Trigger Enable. + +Enable a digital to analog converter channel external trigger mode. This allows an +external trigger to initiate register transfers from the buffer register to the DAC +output register, followed by a DMA transfer to the buffer register if DMA is enabled. +The trigger source must also be selected. + +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_trigger_enable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR |= DAC_CR_TEN1; + break; + case CHANNEL_2: + DAC_CR |= DAC_CR_TEN2; + break; + case CHANNEL_D: + DAC_CR |= (DAC_CR_TEN1 | DAC_CR_TEN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief DAC Channel Trigger Disable. + +Disable a digital to analog converter channel external trigger. + +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_trigger_disable(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_TEN1; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_TEN2; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_TEN1 | DAC_CR_TEN2); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Set DAC Channel Trigger Source. + +Sets the digital to analog converter trigger source, which can be taken from various +timers, an external trigger or a software trigger. + +@param[in] u32 dac_trig_src. Taken from @ref dac_trig2_sel or @ref dac_trig1_sel or +a logical OR of one of each of these to set both channels simultaneously. +*/ + +void dac_set_trigger_source(u32 dac_trig_src) +{ + DAC_CR |= dac_trig_src; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Enable and Set DAC Channel Waveform Generation. + +Enable the digital to analog converter waveform generation as either pseudo-random +noise or triangular wave. These signals are superimposed on existing output values +in the DAC output registers. + +@note The DAC trigger must be enabled for this to work. + +@param[in] u32 dac_trig_src. Taken from @ref dac_wave1_en or @ref dac_wave2_en or +a logical OR of one of each of these to set both channels simultaneously. +*/ + +void dac_set_waveform_generation(u32 dac_wave_ens) +{ + DAC_CR |= dac_wave_ens; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Disable DAC Channel Waveform Generation. + +Disable a digital to analog converter channel superimposed waveform generation. + +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_disable_waveform_generation(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_CR &= ~DAC_CR_WAVE1_DIS; + break; + case CHANNEL_2: + DAC_CR &= ~DAC_CR_WAVE2_DIS; + break; + case CHANNEL_D: + DAC_CR &= ~(DAC_CR_WAVE1_DIS | DAC_CR_WAVE2_DIS); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Set DAC Channel LFSR Mask or Triangle Wave Amplitude. + +Sets the digital to analog converter superimposed waveform generation characteristics. +@li If the noise generation mode is set, this sets the length of the PRBS sequence and +hence the amplitude of the output noise signal. Default setting is length 1. +@li If the triangle wave generation mode is set, this sets the amplitude of the +output signal as 2^(n)-1 where n is the parameter value. Default setting is 1. + +@note High amplitude levels of these waveforms can overload the DAC and distort the +signal output. +@note This must be called before enabling the DAC as the settings will then become read-only. +@note The DAC trigger must be enabled for this to work. + +@param[in] u32 dac_mamp. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a logical OR +of one of each of these to set both channels simultaneously. +*/ + +void dac_set_waveform_characteristics(u32 dac_mamp) +{ + DAC_CR |= dac_mamp; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Load DAC Data Register. + +Loads the appropriate digital to analog converter data register with 12 or 8 bit +data to be converted on a channel. The data can be aligned as follows: +@li right-aligned 8 bit data in bits 0-7 +@li right-aligned 12 bit data in bits 0-11 +@li left aligned 12 bit data in bits 4-15 + +This function can also be used to load the dual channel registers if the data is +formatted according to the datasheets: +@li right-aligned 8 bit data in bits 0-7 for channel 1 and 8-15 for channel 2 +@li right-aligned 12 bit data in bits 0-11 for channel 1 and 16-27 for channel 2 +@li left aligned 12 bit data in bits 4-15 for channel 1 and 20-31 for channel 2 + +@param[in] u32 dac_data with appropriate alignment. +@param[in] enum ::data_align, dac_data_format. Alignment and size. +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_load_data_buffer_single(u32 dac_data, data_align dac_data_format, data_channel dac_channel) +{ + if (dac_channel == CHANNEL_1) + { + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8R1 = dac_data; + break; + case RIGHT12: + DAC_DHR12R1 = dac_data; + break; + case LEFT12: + DAC_DHR12L1 = dac_data; + break; + } + } + else if (dac_channel == CHANNEL_2) + { + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8R2 = dac_data; + break; + case RIGHT12: + DAC_DHR12R2 = dac_data; + break; + case LEFT12: + DAC_DHR12L2 = dac_data; + break; + } + } + else + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8RD = dac_data; + break; + case RIGHT12: + DAC_DHR12RD = dac_data; + break; + case LEFT12: + DAC_DHR12LD = dac_data; + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Load DAC Dual Data Register. + +Loads the appropriate digital to analog converter dual data register with 12 or +8 bit data to be converted for both channels. This allows high bandwidth +simultaneous or independent analog output. The data in both channels are aligned +identically. + +@param[in] u32 dac_data for channel 1 with appropriate alignment. +@param[in] u32 dac_data for channel 2 with appropriate alignment. +@param[in] enum ::data_align, dac_data_format. Right or left aligned, and 8 or 12 bit. +*/ + +void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data_format) +{ + switch (dac_data_format) { + case RIGHT8: + DAC_DHR8RD = ((dac_data1 & MASK8) | ((dac_data2 & MASK8) << 8)); + break; + case RIGHT12: + DAC_DHR12RD = ((dac_data1 & MASK12) | ((dac_data2 & MASK12) << 12)); + break; + case LEFT12: + DAC_DHR12LD = ((dac_data1 & MASK12) | ((dac_data2 & MASK12) << 16)); + break; + } +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Trigger the DAC by a Software Trigger. + +If the trigger source is set to be a software trigger, cause a trigger to occur. +The trigger is cleared by hardware after conversion. + +@param[in] enum ::data_channel, dac_channel. +*/ + +void dac_software_trigger(data_channel dac_channel) +{ + switch (dac_channel) { + case CHANNEL_1: + DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG1; + break; + case CHANNEL_2: + DAC_SWTRIGR |= DAC_SWTRIGR_SWTRIG2; + break; + case CHANNEL_D: + DAC_SWTRIGR |= (DAC_SWTRIGR_SWTRIG1 | DAC_SWTRIGR_SWTRIG2); + break; + } +} + -- cgit v1.2.3 From 5848c8624b42f1783a76f5ad8dd5bb6464b58cfe Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Mon, 9 Jul 2012 16:29:17 +0930 Subject: Minor changes to doxygen content, no changes to code. --- include/libopencm3/stm32/dac.h | 20 ++++++++++---------- include/libopencm3/stm32/doc-stm32f.h | 13 +++++++++++++ 2 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 include/libopencm3/stm32/doc-stm32f.h (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h index 6a778b5..96ac8d0 100644 --- a/include/libopencm3/stm32/dac.h +++ b/include/libopencm3/stm32/dac.h @@ -2,7 +2,7 @@ @ingroup STM32F -@brief libopencm3 STM32F1xx Digital to Analog Converter +@brief libopencm3 STM32F Digital to Analog Converter @version 1.0.0 @@ -13,11 +13,11 @@ LGPL License Terms @ref lgpl_license */ -/** @defgroup STM32F1xx_dac_defines +/** @defgroup STM32F_dac_defines -@brief Defined Constants and Types for the STM32F1xx Digital to Analog Converter +@brief Defined Constants and Types for the STM32F Digital to Analog Converter -@ingroup STM32F1xx_defines +@ingroup STM32F_defines LGPL License Terms @ref lgpl_license @@ -105,7 +105,7 @@ LGPL License Terms @ref lgpl_license */ #define DAC_CR_MAMP2_SHIFT 24 /** @defgroup dac_mamp2 DAC Channel 2 LFSR Mask and Triangle Wave Amplitude values -@ingroup STM32F1xx_dac_defines +@ingroup STM32F_dac_defines Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 @{*/ @@ -134,7 +134,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 #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 STM32F1xx_dac_defines +@ingroup STM32F_dac_defines @li NOISE: Noise wave generation enabled @li TRI: Triangle wave generation enabled @@ -165,7 +165,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 */ #define DAC_CR_TSEL2_SHIFT 19 /** @defgroup dac_trig2_sel DAC Channel 2 Trigger Source Selection -@ingroup STM32F1xx_dac_defines +@ingroup STM32F_dac_defines @li T6: Timer 6 TRGO event @li T3: Timer 3 TRGO event @@ -217,7 +217,7 @@ 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 STM32F1xx_dac_defines +@ingroup STM32F_dac_defines Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 @{*/ @@ -246,7 +246,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 #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 STM32F1xx_dac_defines +@ingroup STM32F_dac_defines @li DIS: wave generation disabled @li NOISE: Noise wave generation enabled @@ -278,7 +278,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 */ #define DAC_CR_TSEL1_SHIFT 3 /** @defgroup dac_trig1_sel DAC Channel 1 Trigger Source Selection -@ingroup STM32F1xx_dac_defines +@ingroup STM32F_dac_defines @li T6: Timer 6 TRGO event @li T3: Timer 3 TRGO event diff --git a/include/libopencm3/stm32/doc-stm32f.h b/include/libopencm3/stm32/doc-stm32f.h new file mode 100644 index 0000000..e592c12 --- /dev/null +++ b/include/libopencm3/stm32/doc-stm32f.h @@ -0,0 +1,13 @@ +/** @defgroup STM32F_defines + +@brief Defined Constants and Types for the STM32F series + +@ingroup STM32F + +@version 1.0.0 + +@date 8 July 2012 + +LGPL License Terms @ref lgpl_license + */ + -- cgit v1.2.3 From cba9561e89c833b8151bf0439400ed5a9fd14ff8 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Mon, 9 Jul 2012 16:54:01 +0930 Subject: NVIC_Set_Interrupt_Priority: change to use 4-bit fields. (viz STM32F10xxx Cortex-M3 programming manual PM0056 and Cortex-M3-Generic-User-Guide.pdf) Doxygen commentary added --- include/libopencm3/stm32/f1/nvic_f1.h | 5 ++ include/libopencm3/stm32/nvic.h | 33 ++++++++++- lib/stm32/nvic.c | 101 +++++++++++++++++++++++++++++++++- 3 files changed, 135 insertions(+), 4 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/f1/nvic_f1.h b/include/libopencm3/stm32/f1/nvic_f1.h index 884f728..ce9a99e 100644 --- a/include/libopencm3/stm32/f1/nvic_f1.h +++ b/include/libopencm3/stm32/f1/nvic_f1.h @@ -27,6 +27,10 @@ */ /* User Interrupts */ +/** @defgroup nvic_stn32f1_userint STM32F1xx User Interrupts +@ingroup STM32F_nvic_defines + +@{*/ #define NVIC_WWDG_IRQ 0 #define NVIC_PVD_IRQ 1 #define NVIC_TAMPER_IRQ 2 @@ -95,5 +99,6 @@ #define NVIC_CAN2_RX1_IRQ 65 #define NVIC_CAN2_SCE_IRQ 66 #define NVIC_OTG_FS_IRQ 67 +/*@}*/ #endif diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h index 36a8fe5..f974483 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/stm32/nvic.h @@ -1,3 +1,26 @@ +/** @file + +@ingroup STM32F + +@brief libopencm3 STM32F Nested Vectored Interrupt Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski + +@date 8 July 2012 + +LGPL License Terms @ref lgpl_license + */ +/** @defgroup STM32F_nvic_defines + +@brief Defined Constants and Types for the STM32F Nested Vectored Interrupt Controller + +@ingroup STM32F_defines + +LGPL License Terms @ref lgpl_license + + */ /* * This file is part of the libopencm3 project. * @@ -65,6 +88,11 @@ /* --- IRQ channel numbers-------------------------------------------------- */ /* Cortex M3 System Interrupts */ +/** @defgroup nvic_sysint Cortex M3 System Interrupts +@ingroup STM32F_nvic_defines + +IRQ numbers -3 and -6 to -9 are reserved +@{*/ #define NVIC_NMI_IRQ -14 #define NVIC_HARD_FAULT_IRQ -13 #define NVIC_MEM_MANAGE_IRQ -12 @@ -76,9 +104,10 @@ /* irq number -3 reserved */ #define NVIC_PENDSV_IRQ -2 #define NVIC_SYSTICK_IRQ -1 +/*@}*/ -/* Note: User interrupts are family specific and are defined in a familiy +/* Note: User interrupts are family specific and are defined in a family * specific header file in the corresponding subfolder. */ @@ -103,6 +132,6 @@ void nvic_clear_pending_irq(u8 irqn); u8 nvic_get_active_irq(u8 irqn); u8 nvic_get_irq_enabled(u8 irqn); void nvic_set_priority(u8 irqn, u8 priority); -void nvic_generate_software_interrupt(u8 irqn); +void nvic_generate_software_interrupt(u16 irqn); #endif diff --git a/lib/stm32/nvic.c b/lib/stm32/nvic.c index c9cf48b..ae91bff 100644 --- a/lib/stm32/nvic.c +++ b/lib/stm32/nvic.c @@ -1,3 +1,25 @@ +/** @file + +@ingroup STM32F + +@brief libopencm3 STM32F Nested Vectored Interrupt Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto +@author @htmlonly © @endhtmlonly 2012 Fergus Noble + +@date 7 July 2012 + +The STM32F series provides up to 68 maskable user interrupts for the STM32F10x +series, and 87 for the STM32F2xx and STM32F4xx series. + +The NVIC registers are defined by the ARM standards +@see Cortex-M3 Devices Generic User Guide + + +LGPL License Terms @ref lgpl_license +*/ /* * This file is part of the libopencm3 project. * @@ -20,47 +42,122 @@ #include +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Enable Interrupt + +Enables a user interrupt. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +*/ + void nvic_enable_irq(u8 irqn) { NVIC_ISER(irqn / 32) = (1 << (irqn % 32)); } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Disable Interrupt + +Disables a user interrupt. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +*/ + void nvic_disable_irq(u8 irqn) { NVIC_ICER(irqn / 32) = (1 << (irqn % 32)); } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Return Pending Interrupt + +True if the interrupt has occurred and is waiting for service. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@return Boolean. Interrupt pending. +*/ + u8 nvic_get_pending_irq(u8 irqn) { return NVIC_ISPR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Set Pending Interrupt + +Force a user interrupt to a pending state. No effect if the interrupt is already +pending. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +*/ + void nvic_set_pending_irq(u8 irqn) { NVIC_ISPR(irqn / 32) = (1 << (irqn % 32)); } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Clear Pending Interrupt + +Force remove a user interrupt from a pending state. No effect if the interrupt is +actively being serviced. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +*/ + void nvic_clear_pending_irq(u8 irqn) { NVIC_ICPR(irqn / 32) = (1 << (irqn % 32)); } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Return Active Interrupt + +Interrupt has occurred and is currently being serviced. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@return Boolean. Interrupt active. +*/ + u8 nvic_get_active_irq(u8 irqn) { return NVIC_IABR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Return Enabled Interrupt + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@return Boolean. Interrupt enabled. +*/ + u8 nvic_get_irq_enabled(u8 irqn) { return NVIC_ISER(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; } +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Set Interrupt Priority + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@param[in] priority Unsigned int8. Interrupt priority (0 ... 255) +*/ + void nvic_set_priority(u8 irqn, u8 priority) { - NVIC_IPR(irqn) = priority; + NVIC_IPR(irqn / 4) = ((priority << ((irqn % 4) * 8)); } -void nvic_generate_software_interrupt(u8 irqn) +/*-----------------------------------------------------------------------------*/ +/** @brief NVIC Software Trigger Interrupt + +Generate an interrupt from software. This has no effect for unprivileged access +unless the privilege level has been elevated through the System Control Registers. + +@param[in] sgin Unsigned int16. Interrupt number (0 ... 239) +*/ + +void nvic_generate_software_interrupt(u16 irqn) { if (irqn <= 239) NVIC_STIR |= irqn; -- cgit v1.2.3 From 52fd7c79768490158241260273d29e9fa86f45e8 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Tue, 10 Jul 2012 09:32:47 +0930 Subject: STM32F timers. Doxygen markup added, and some code changes: 1. Remove the extra mask (TIM_DIER(timer_peripheral) & flag) in timer_get_flag. Not all flags in SR relate to IRQs and the flags that do might be useful even if interrupts not enabled. 2. In a number of functions (e.g. timer_set_output_idle_state) that only apply to advanced timers, add test for TIM1 and TIM8, as done in some others. 3. Added timer_force_event to manipulate the EG register TBD DMA burst - can't get my head around why this would be useful. Someone must have thought so! --- include/libopencm3/stm32/timer.h | 226 +++++++--- lib/stm32/f1/timer.c | 900 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 1066 insertions(+), 60 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/timer.h b/include/libopencm3/stm32/timer.h index 3c8c8c2..3066fd3 100644 --- a/include/libopencm3/stm32/timer.h +++ b/include/libopencm3/stm32/timer.h @@ -1,3 +1,26 @@ +/** @file + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Timers + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Piotr Esden-Tempski + +@date 18 May 2012 + +LGPL License Terms @ref lgpl_license + */ +/** @defgroup STM32F1xx_tim_defines + +@brief Defined Constants and Types for the STM32F1xx Timers + +@ingroup STM32F1xx_defines + +LGPL License Terms @ref lgpl_license + + */ /* * This file is part of the libopencm3 project. * @@ -26,6 +49,11 @@ /* --- Convenience macros -------------------------------------------------- */ /* Timer register base adresses (for convenience) */ +/****************************************************************************/ +/** @defgroup tim_reg_base Timer register base addresses +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM1 TIM1_BASE #define TIM2 TIM2_BASE #define TIM3 TIM3_BASE @@ -34,6 +62,7 @@ #define TIM6 TIM6_BASE #define TIM7 TIM7_BASE #define TIM8 TIM8_BASE +/*@}*/ /* --- Timer registers ----------------------------------------------------- */ @@ -227,25 +256,43 @@ /* --- TIMx_CR1 values ----------------------------------------------------- */ +/****************************************************************************/ +/** @defgroup tim_x_cr1_cdr TIMx_CR1 CKD[1:0] Clock Division Ratio +@ingroup STM32F1xx_tim_defines + +@{*/ /* CKD[1:0]: Clock division */ #define TIM_CR1_CKD_CK_INT (0x0 << 8) #define TIM_CR1_CKD_CK_INT_MUL_2 (0x1 << 8) #define TIM_CR1_CKD_CK_INT_MUL_4 (0x2 << 8) #define TIM_CR1_CKD_CK_INT_MASK (0x3 << 8) +/*@}*/ /* ARPE: Auto-reload preload enable */ #define TIM_CR1_ARPE (1 << 7) /* CMS[1:0]: Center-aligned mode selection */ +/****************************************************************************/ +/** @defgroup tim_x_cr1_cms TIMx_CR1 CMS[1:0]: Center-aligned Mode Selection +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM_CR1_CMS_EDGE (0x0 << 5) #define TIM_CR1_CMS_CENTER_1 (0x1 << 5) #define TIM_CR1_CMS_CENTER_2 (0x2 << 5) #define TIM_CR1_CMS_CENTER_3 (0x3 << 5) #define TIM_CR1_CMS_MASK (0x3 << 5) +/*@}*/ /* DIR: Direction */ +/****************************************************************************/ +/** @defgroup tim_x_cr1_dir TIMx_CR1 DIR: Direction +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM_CR1_DIR_UP (0 << 4) #define TIM_CR1_DIR_DOWN (1 << 4) +/*@}*/ /* OPM: One pulse mode */ #define TIM_CR1_OPM (1 << 3) @@ -261,32 +308,43 @@ /* --- TIMx_CR2 values ----------------------------------------------------- */ -/* OIS4: Output idle state 4 (OC4 output) */ +/****************************************************************************/ +/** @defgroup tim_x_cr2_ois TIMx_CR2_OIS: Force Output Idle State Control Values +@ingroup STM32F1xx_tim_defines + +@{*/ +/* OIS4:*//** Output idle state 4 (OC4 output) */ #define TIM_CR2_OIS4 (1 << 14) -/* OIS3N: Output idle state 3 (OC3N output) */ +/* OIS3N:*//** Output idle state 3 (OC3N output) */ #define TIM_CR2_OIS3N (1 << 13) -/* OIS3: Output idle state 3 (OC3 output) */ +/* OIS3:*//** Output idle state 3 (OC3 output) */ #define TIM_CR2_OIS3 (1 << 12) -/* OIS2N: Output idle state 2 (OC2N output) */ +/* OIS2N:*//** Output idle state 2 (OC2N output) */ #define TIM_CR2_OIS2N (1 << 11) -/* OIS2: Output idle state 2 (OC2 output) */ +/* OIS2:*//** Output idle state 2 (OC2 output) */ #define TIM_CR2_OIS2 (1 << 10) -/* OIS1N: Output idle state 1 (OC1N output) */ +/* OIS1N:*//** Output idle state 1 (OC1N output) */ #define TIM_CR2_OIS1N (1 << 9) -/* OIS1: Output idle state 1 (OC1 output) */ +/* OIS1:*//** Output idle state 1 (OC1 output) */ #define TIM_CR2_OIS1 (1 << 8) #define TIM_CR2_OIS_MASK (0x7f << 8) +/*@}*/ /* TI1S: TI1 selection */ #define TIM_CR2_TI1S (1 << 7) /* MMS[2:0]: Master mode selection */ +/****************************************************************************/ +/** @defgroup tim_mastermode TIMx_CR2 MMS[6:4]: Master Mode Selection +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM_CR2_MMS_RESET (0x0 << 4) #define TIM_CR2_MMS_ENABLE (0x1 << 4) #define TIM_CR2_MMS_UPDATE (0x2 << 4) @@ -296,6 +354,7 @@ #define TIM_CR2_MMS_COMPARE_OC3REF (0x6 << 4) #define TIM_CR2_MMS_COMPARE_OC4REF (0x7 << 4) #define TIM_CR2_MMS_MASK (0x7 << 4) +/*@}*/ /* CCDS: Capture/compare DMA selection */ #define TIM_CR2_CCDS (1 << 3) @@ -344,137 +403,186 @@ #define TIM_SMCR_MSM (1 << 7) /* TS[2:0]: Trigger selection */ +/** @defgroup tim_ts TS Trigger selection +@ingroup STM32F1xx_tim_defines + +@{*/ +/** Internal Trigger 0 (ITR0) */ #define TIM_SMCR_TS_ITR0 (0x0 << 4) +/** Internal Trigger 1 (ITR1) */ #define TIM_SMCR_TS_ITR1 (0x1 << 4) +/** Internal Trigger 2 (ITR2) */ #define TIM_SMCR_TS_ITR2 (0x2 << 4) +/** Internal Trigger 3 (ITR3) */ #define TIM_SMCR_TS_ITR3 (0x3 << 4) +/** TI1 Edge Detector (TI1F_ED) */ #define TIM_SMCR_TS_IT1F_ED (0x4 << 4) +/** Filtered Timer Input 1 (TI1FP1) */ #define TIM_SMCR_TS_IT1FP1 (0x5 << 4) +/** Filtered Timer Input 2 (TI1FP2) */ #define TIM_SMCR_TS_IT1FP2 (0x6 << 4) +/** External Trigger input (ETRF) */ #define TIM_SMCR_TS_ETRF (0x7 << 4) #define TIM_SMCR_TS_MASK (0x7 << 4) +/*@}*/ /* SMS[2:0]: Slave mode selection */ +/** @defgroup tim_sms SMS Slave mode selection +@ingroup STM32F1xx_tim_defines + +@{*/ +/** Slave mode disabled */ #define TIM_SMCR_SMS_OFF (0x0 << 0) +/** Encoder mode 1 - Counter counts up/down on TI2FP2 edge depending on TI1FP1 +level. */ #define TIM_SMCR_SMS_EM1 (0x1 << 0) +/** Encoder mode 2 - Counter counts up/down on TI1FP1 edge depending on TI2FP2 +level. */ #define TIM_SMCR_SMS_EM2 (0x2 << 0) +/** Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges +depending on the level of the complementary input. */ #define TIM_SMCR_SMS_EM3 (0x3 << 0) +/** Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter +and generates an update of the registers. */ #define TIM_SMCR_SMS_RM (0x4 << 0) +/** Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. */ #define TIM_SMCR_SMS_GM (0x5 << 0) +/** Trigger Mode - The counter starts at a rising edge of the trigger TRGI. */ #define TIM_SMCR_SMS_TM (0x6 << 0) +/** External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. */ #define TIM_SMCR_SMS_ECM1 (0x7 << 0) #define TIM_SMCR_SMS_MASK (0x7 << 0) +/*@}*/ /* --- TIMx_DIER values ---------------------------------------------------- */ -/* TDE: Trigger DMA request enable */ +/****************************************************************************/ +/** @defgroup tim_irq_enable TIMx_DIER Timer DMA and Interrupt Enable Values +@ingroup STM32F1xx_tim_defines + +@{*/ +/* TDE:*//** Trigger DMA request enable */ #define TIM_DIER_TDE (1 << 14) -/* COMDE: COM DMA request enable */ +/* COMDE:*//** COM DMA request enable */ #define TIM_DIER_COMDE (1 << 13) -/* CC4DE: Capture/Compare 4 DMA request enable */ +/* CC4DE:*//** Capture/Compare 4 DMA request enable */ #define TIM_DIER_CC4DE (1 << 12) -/* CC3DE: Capture/Compare 3 DMA request enable */ +/* CC3DE:*//** Capture/Compare 3 DMA request enable */ #define TIM_DIER_CC3DE (1 << 11) -/* CC2DE: Capture/Compare 2 DMA request enable */ +/* CC2DE:*//** Capture/Compare 2 DMA request enable */ #define TIM_DIER_CC2DE (1 << 10) -/* CC1DE: Capture/Compare 1 DMA request enable */ +/* CC1DE:*//** Capture/Compare 1 DMA request enable */ #define TIM_DIER_CC1DE (1 << 9) -/* UDE: Update DMA request enable */ +/* UDE*//**: Update DMA request enable */ #define TIM_DIER_UDE (1 << 8) -/* BIE: Break interrupt enable */ +/* BIE:*//** Break interrupt enable */ #define TIM_DIER_BIE (1 << 7) -/* TIE: Trigger interrupt enable */ +/* TIE:*//** Trigger interrupt enable */ #define TIM_DIER_TIE (1 << 6) -/* COMIE: COM interrupt enable */ +/* COMIE:*//** COM interrupt enable */ #define TIM_DIER_COMIE (1 << 5) -/* CC4IE: Capture/compare 4 interrupt enable */ +/* CC4IE:*//** Capture/compare 4 interrupt enable */ #define TIM_DIER_CC4IE (1 << 4) -/* CC3IE: Capture/compare 3 interrupt enable */ +/* CC3IE:*//** Capture/compare 3 interrupt enable */ #define TIM_DIER_CC3IE (1 << 3) -/* CC2IE: Capture/compare 2 interrupt enable */ +/* CC2IE:*//** Capture/compare 2 interrupt enable */ #define TIM_DIER_CC2IE (1 << 2) -/* CC1IE: Capture/compare 1 interrupt enable */ +/* CC1IE:*//** Capture/compare 1 interrupt enable */ #define TIM_DIER_CC1IE (1 << 1) -/* UIE: Update interrupt enable */ +/* UIE:*//** Update interrupt enable */ #define TIM_DIER_UIE (1 << 0) +/*@}*/ /* --- TIMx_SR values ------------------------------------------------------ */ +/****************************************************************************/ +/** @defgroup tim_sr_values TIMx_SR Timer Status Register Flags +@ingroup STM32F1xx_tim_defines -/* CC4OF: Capture/compare 4 overcapture flag */ +@{*/ + +/* CC4OF:*//** Capture/compare 4 overcapture flag */ #define TIM_SR_CC4OF (1 << 12) -/* CC3OF: Capture/compare 3 overcapture flag */ +/* CC3OF:*//** Capture/compare 3 overcapture flag */ #define TIM_SR_CC3OF (1 << 11) -/* CC2OF: Capture/compare 2 overcapture flag */ +/* CC2OF:*//** Capture/compare 2 overcapture flag */ #define TIM_SR_CC2OF (1 << 10) -/* CC1OF: Capture/compare 1 overcapture flag */ +/* CC1OF:*//** Capture/compare 1 overcapture flag */ #define TIM_SR_CC1OF (1 << 9) -/* BIF: Break interrupt flag */ +/* BIF:*//** Break interrupt flag */ #define TIM_SR_BIF (1 << 7) -/* TIF: Trigger interrupt flag */ +/* TIF:*//** Trigger interrupt flag */ #define TIM_SR_TIF (1 << 6) -/* COMIF: COM interrupt flag */ +/* COMIF:*//** COM interrupt flag */ #define TIM_SR_COMIF (1 << 5) -/* CC4IF: Capture/compare 4 interrupt flag */ +/* CC4IF:*//** Capture/compare 4 interrupt flag */ #define TIM_SR_CC4IF (1 << 4) -/* CC3IF: Capture/compare 3 interrupt flag */ +/* CC3IF:*//** Capture/compare 3 interrupt flag */ #define TIM_SR_CC3IF (1 << 3) -/* CC2IF: Capture/compare 2 interrupt flag */ +/* CC2IF:*//** Capture/compare 2 interrupt flag */ #define TIM_SR_CC2IF (1 << 2) -/* CC1IF: Capture/compare 1 interrupt flag */ +/* CC1IF:*//** Capture/compare 1 interrupt flag */ #define TIM_SR_CC1IF (1 << 1) -/* UIF: Update interrupt flag */ +/* UIF:*//** Update interrupt flag */ #define TIM_SR_UIF (1 << 0) +/*@}*/ /* --- TIMx_EGR values ----------------------------------------------------- */ -/* BG: Break generation */ +/****************************************************************************/ +/** @defgroup tim_event_gen TIMx_EGR Timer Event Generator Values +@ingroup STM32F1xx_tim_defines + +@{*/ + +/* BG:*//** Break generation */ #define TIM_EGR_BG (1 << 7) -/* TG: Trigger generation */ +/* TG:*//** Trigger generation */ #define TIM_EGR_TG (1 << 6) -/* COMG: Capture/compare control update generation */ +/* COMG:*//** Capture/compare control update generation */ #define TIM_EGR_COMG (1 << 5) -/* CC4G: Capture/compare 4 generation */ +/* CC4G:*//** Capture/compare 4 generation */ #define TIM_EGR_CC4G (1 << 4) -/* CC3G: Capture/compare 3 generation */ +/* CC3G:*//** Capture/compare 3 generation */ #define TIM_EGR_CC3G (1 << 3) -/* CC2G: Capture/compare 2 generation */ +/* CC2G:*//** Capture/compare 2 generation */ #define TIM_EGR_CC2G (1 << 2) -/* CC1G: Capture/compare 1 generation */ +/* CC1G:*//** Capture/compare 1 generation */ #define TIM_EGR_CC1G (1 << 1) -/* UG: Update generation */ +/* UG:*//** Update generation */ #define TIM_EGR_UG (1 << 0) +/*@}*/ /* --- TIMx_CCMR1 values --------------------------------------------------- */ @@ -805,11 +913,17 @@ #define TIM_BDTR_OSSI (1 << 10) /* LOCK[1:0]: Lock configuration */ +/****************************************************************************/ +/** @defgroup tim_lock TIM_BDTR_LOCK Timer Lock Values +@ingroup STM32F1xx_tim_defines + +@{*/ #define TIM_BDTR_LOCK_OFF (0x0 << 8) #define TIM_BDTR_LOCK_LEVEL_1 (0x1 << 8) #define TIM_BDTR_LOCK_LEVEL_2 (0x2 << 8) #define TIM_BDTR_LOCK_LEVEL_3 (0x3 << 8) #define TIM_BDTR_LOCK_MASK (0x3 << 8) +/*@}*/ /* DTG[7:0]: Dead-time generator set-up */ #define TIM_BDTR_DTG_MASK 0x00FF @@ -828,7 +942,7 @@ /* --- TIMx convenience defines -------------------------------------------- */ -/* Output Compare channel designators */ +/** Output Compare channel designators */ enum tim_oc_id { TIM_OC1=0, TIM_OC1N, @@ -839,7 +953,7 @@ enum tim_oc_id { TIM_OC4, }; -/* Output Compare mode designators */ +/** Output Compare mode designators */ enum tim_oc_mode { TIM_OCM_FROZEN, TIM_OCM_ACTIVE, @@ -851,7 +965,7 @@ enum tim_oc_mode { TIM_OCM_PWM2, }; -/* Input Capture channel designators */ +/** Input Capture channel designators */ enum tim_ic_id { TIM_IC1, TIM_IC2, @@ -859,7 +973,13 @@ enum tim_ic_id { TIM_IC4, }; -/* Input Capture input filter */ +/** Input Capture input filter. The frequency used to sample the +input and the number of events needed to validate an output transition. + +TIM_IC_CK_INT_N_x No division from the Deadtime and Sampling Clock frequency (DTF), +filter length x +TIM_IC_DTF_DIV_y_N_x Division by y from the DTF, filter length x + */ enum tim_ic_filter { TIM_IC_OFF, TIM_IC_CK_INT_N_2, @@ -879,7 +999,9 @@ enum tim_ic_filter { TIM_IC_DTF_DIV_32_N_8, }; -/* Input Capture input prescaler */ +/** Input Capture input prescaler. + +TIM_IC_PSC_x Input capture is done every x events*/ enum tim_ic_psc { TIM_IC_PSC_OFF, TIM_IC_PSC_2, @@ -887,7 +1009,10 @@ enum tim_ic_psc { TIM_IC_PSC_8, }; -/* Input Capture input prescaler */ +/** Input Capture input source. + +The direction of the channel (input/output) as well as the input used. + */ enum tim_ic_input { TIM_IC_OUT = 0, TIM_IC_IN_TI1 = 1, @@ -897,13 +1022,13 @@ enum tim_ic_input { TIM_IC_IN_TI4 = 6, }; -/* Input Capture input prescaler */ +/** Input Capture input polarity */ enum tim_ic_pol { TIM_IC_RISING, TIM_IC_FALLING, }; -/* --- TIM functions ------------------------------------------------------- */ +/* --- TIM function prototypes ------------------------------------------------------- */ void timer_reset(u32 timer_peripheral); void timer_enable_irq(u32 timer_peripheral, u32 irq); void timer_disable_irq(u32 timer_peripheral, u32 irq); @@ -982,5 +1107,6 @@ void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc); void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol); void timer_slave_set_mode(u32 timer, u8 mode); void timer_slave_set_trigger(u32 timer, u8 trigger); +void timer_force_event(u32 timer, u8 event); #endif diff --git a/lib/stm32/f1/timer.c b/lib/stm32/f1/timer.c index cf5b411..11cb954 100644 --- a/lib/stm32/f1/timer.c +++ b/lib/stm32/f1/timer.c @@ -1,3 +1,71 @@ +/** @file + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Timers + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Edward Cheeseman + +@date 8 July 2012 + +This library supports the General Purpose and Advanced Control Timers for +the STM32F1xx series of ARM Cortex Microcontrollers by ST Microelectronics. + +The STM32F1xx series have four general purpose timers (2-5), while some have +an additional two advanced timers (1,8), and some have two basic timers (6,7). +Some of the larger devices have additional general purpose timers (9-14). + +@todo Add timer DMA burst settings + +@section tim_api_ex Basic TIMER handling API. + +Enable the timer clock first. The timer mode sets the clock division ratio, +the count alignment (edge or centred) and count direction. Finally enable the timer. + +The timer output compare block produces a signal that can be configured for +output to a pin or passed to other peripherals for use as a trigger. In all cases +the output compare mode must be set to define how the output responds to a compare +match, and the output must be enabled. If output to a pin is required, enable the +appropriate GPIO clock and set the pin to alternate output mode. + +Example: Timer 2 with 2x clock divide, edge aligned and up counting. +@code + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM2EN); + timer_reset(TIM2); + timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT_MUL_2, + TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + ... + timer_set_period(TIM2, 1000); + timer_enable_counter(TIM2); +@endcode +Example: Timer 1 with PWM output, no clock divide and centre alignment. Set the +Output Compare mode to PWM and enable the output of channel 1. Note that for the +advanced timers the break functionality must be enabled before the signal will +appear at the output, even though break is not being used. This is in addition to +the normal output enable. Enable the alternate function clock (APB2 only) and port A +clock. Set ports A8 and A9 (timer 1 channel 1 compare outputs) to alternate function +push-pull outputs where the PWM output will appear. + +@code + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8 | GPIO9); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN); + timer_reset(TIM1); + timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_CENTER_1, TIM_CR1_DIR_UP); + timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM2); + timer_enable_oc_output(TIM1, TIM_OC1); + timer_enable_break_main_output(TIM1); + timer_set_oc_value(TIM1, TIM_OC1, 200); + timer_set_period(TIM1, 1000); + timer_enable_counter(TIM1); +@endcode + +@todo input capture example + +*/ /* * This file is part of the libopencm3 project. * @@ -28,6 +96,17 @@ #include #include +/*---------------------------------------------------------------------------*/ +/** @brief Reset a Timer. + +The counter and all its associated configuration registers +are placed in the reset condition. The reset is effected via the RCC peripheral reset +system. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base + (TIM9 .. TIM14 not yet supported here). +*/ + void timer_reset(u32 timer_peripheral) { switch (timer_peripheral) { @@ -93,31 +172,84 @@ void timer_reset(u32 timer_peripheral) } } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Interrupts for a Timer + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt enable bits to be set +*/ + void timer_enable_irq(u32 timer_peripheral, u32 irq) { TIM_DIER(timer_peripheral) |= irq; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Interrupts for a Timer. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt enable bits to be cleared +*/ + void timer_disable_irq(u32 timer_peripheral, u32 irq) { TIM_DIER(timer_peripheral) &= ~irq; } +/*---------------------------------------------------------------------------*/ +/** @brief Read a Status Flag. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] flag Unsigned int32. Status register flag @ref tim_sr_values. +@returns boolean: flag set. +*/ + bool timer_get_flag(u32 timer_peripheral, u32 flag) { - if (((TIM_SR(timer_peripheral) & flag) != 0) && - ((TIM_DIER(timer_peripheral) & flag) != 0)) { + if ((TIM_SR(timer_peripheral) & flag) != 0) { return true; } return false; } +/*---------------------------------------------------------------------------*/ +/** @brief Clear a Status Flag. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] flag Unsigned int32. @ref tim_sr_values. Status register flag. +*/ + void timer_clear_flag(u32 timer_peripheral, u32 flag) { TIM_SR(timer_peripheral) &= ~flag; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer Mode. + +The modes are: + +@li Clock divider ratio (to form the sampling clock for the input filters, +and the dead-time clock in the advanced timers 1 and 8) +@li Edge/centre alignment +@li Count direction + +The alignment and count direction are effective only for timers 1 to 5 and 8 +while the clock divider ratio is effective for all timers except 6,7 +The remaining timers are limited hardware timers which do not support these mode +settings. + +@note: When center alignment mode is selected, count direction is controlled by +hardware and cannot be written. The count direction setting has no effect +in this case. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base (TIM1, TIM2 ... TIM5, TIM8) +@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref tim_x_cr1_cdr +@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms +@param[in] direction Unsigned int32. Count direction in bit 4,: @ref tim_x_cr1_dir +*/ + void timer_set_mode(u32 timer_peripheral, u32 clock_div, u32 alignment, u32 direction) { @@ -132,6 +264,16 @@ void timer_set_mode(u32 timer_peripheral, u32 clock_div, TIM_CR1(timer_peripheral) = cr1; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Filter and Dead-time Clock Divider Ratio. + +This forms the sampling clock for the input filters and the dead-time clock +in the advanced timers 1 and 8, by division from the timer clock. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref tim_x_cr1_cdr +*/ + void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) { clock_div &= TIM_CR1_CKD_CK_INT_MASK; @@ -139,16 +281,44 @@ void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) TIM_CR1(timer_peripheral) |= clock_div; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Auto-Reload Buffering. + +During counter operation this causes the counter to be loaded from its +auto-reload register only at the next update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_preload(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Auto-Reload Buffering. + +This causes the counter to be loaded immediately with a new count value when the +auto-reload register is written, so that the new value becomes effective for the +current count cycle rather than for the cycle following an update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_preload(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE; } +/*---------------------------------------------------------------------------*/ +/** @brief Specify the counter alignment mode. + +The mode can be edge aligned or centered. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms +*/ + void timer_set_alignment(u32 timer_peripheral, u32 alignment) { alignment &= TIM_CR1_CMS_MASK; @@ -156,128 +326,368 @@ void timer_set_alignment(u32 timer_peripheral, u32 alignment) TIM_CR1(timer_peripheral) |= alignment; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Count Up. + +This has no effect if the timer is set to center aligned. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_direction_up(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Count Down. + +This has no effect if the timer is set to center aligned. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_direction_down(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Timer for One Cycle and Stop. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_one_shot_mode(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_OPM; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Timer to Run Continuously. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_continuous_mode(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Generate Update IRQ or DMA on any Event. + +The events which will generate an interrupt or DMA request can be +@li a counter underflow/overflow, +@li a forced update, +@li an event from the slave mode controller. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_update_on_any(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Timer to Generate Update IRQ or DMA only from Under/Overflow Events. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_update_on_overflow(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_URS; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Update Events. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_update_event(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Update Events. + +Update events are not generated and the shadow registers keep their values. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_update_event(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable the timer to start counting. + +This should be called after the timer initial configuration has been completed. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_counter(u32 timer_peripheral) { TIM_CR1(timer_peripheral) |= TIM_CR1_CEN; } +/*---------------------------------------------------------------------------*/ +/** @brief Stop the timer from counting. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_counter(u32 timer_peripheral) { TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer Output Idle States High. + +This determines the value of the timer output compare when it enters idle state. + +@sa @ref timer_set_oc_idle_state_set + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref tim_x_cr2_ois. +If several settings are to be made, use the logical OR of the output control values. +*/ + void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs) { - TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer Output Idle States Low. + +This determines the value of the timer output compare when it enters idle state. + +@sa @ref timer_set_oc_idle_state_unset + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref tim_x_cr2_ois +*/ + void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs) { - TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer 1 Input to XOR of Three Channels. + +The first timer capture input is formed from the XOR of the first three timer input +channels 1, 2, 3. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_set_ti1_ch123_xor(u32 timer_peripheral) { TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer 1 Input to Channel 1. + +The first timer capture input is taken from the timer input channel 1 only. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_set_ti1_ch1(u32 timer_peripheral) { TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Master Mode + +This sets the Trigger Output TRGO for synchronizing with slave timers or passing as +an internal trigger to the ADC or DAC. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] mode Unsigned int32. Master Mode @ref tim_mastermode +*/ + void timer_set_master_mode(u32 timer_peripheral, u32 mode) { TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK; TIM_CR2(timer_peripheral) |= mode; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer DMA Requests on Capture/Compare Events. + +Capture/compare events will cause DMA requests to be generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_set_dma_on_compare_event(u32 timer_peripheral) { TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Timer DMA Requests on Update Events. + +Update events will cause DMA requests to be generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_set_dma_on_update_event(u32 timer_peripheral) { TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Capture/Compare Control Update with Trigger. + +If the capture/compare control bits CCxE, CCxNE and OCxM are set to be +preloaded, they are updated by software setting the COM bit (@ref ) or when a +rising edge occurs on the trigger input TRGI. + +@note This setting is only valid for the advanced timer channels with complementary +outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral) { - TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Capture/Compare Control Update with Trigger. + +If the capture/compare control bits CCxE, CCxNE and OCxM are set to be +preloaded, they are updated by software setting the COM bit (@ref ). + +@note This setting is only valid for the advanced timer channels with complementary +outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral) { - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Capture/Compare Control Preload. + +The capture/compare control bits CCxE, CCxNE and OCxM are set to be preloaded +when a COM event occurs. + +@note This setting is only valid for the advanced timer channels with complementary +outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral) { - TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Capture/Compare Control Preload. + +The capture/compare control bits CCxE, CCxNE and OCxM preload is disabled. + +@note This setting is only valid for the advanced timer channels with complementary +outputs. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +*/ + void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral) { - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Value for the Timer Prescaler. + +The timer clock is prescaled by the 16 bit scale value plus 1. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] value Unsigned int32. Prescaler values 0...0xFFFF. +*/ + void timer_set_prescaler(u32 timer_peripheral, u32 value) { TIM_PSC(timer_peripheral) = value; } +/*---------------------------------------------------------------------------*/ +/** @brief Set the Value for the Timer Repetition Counter. + +A timer update event is generated only after the specified number of repeat +count cycles have been completed. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] value Unsigned int32. Repetition values 0...0xFF. +*/ + void timer_set_repetition_counter(u32 timer_peripheral, u32 value) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_RCR(timer_peripheral) = value; } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Period + +Specify the timer period in the auto-reload register. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] period Unsigned int32. Period in counter clock ticks. +*/ + void timer_set_period(u32 timer_peripheral, u32 period) { TIM_ARR(timer_peripheral) = period; } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Clear Function + +When this is enabled, the output compare signal is cleared when a high is detected +on the external trigger input. This works in the output compare and PWM modes only +(not forced mode). +The output compare signal remains off until the next update event. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -296,11 +706,19 @@ void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) case TIM_OC1N: case TIM_OC2N: case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ + /* Ignoring as oc clear enable only applies to the whole channel. */ break; } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare Clear Function + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -319,11 +737,24 @@ void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) case TIM_OC1N: case TIM_OC2N: case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ + /* Ignoring as oc clear enable only applies to the whole channel. */ break; } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Fast Mode + +When this is enabled, the output compare signal is forced to the compare state +by a trigger input, independently of the compare match. This speeds up the +setting of the output compare to 3 clock cycles as opposed to at least 5 in the +slow mode. This works in the PWM1 and PWM2 modes only. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -347,6 +778,17 @@ void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Slow Mode + +This disables the fast compare mode and the output compare depends on the +counter and compare register values. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -370,6 +812,29 @@ void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Mode + +Specifies how the comparator output will respond to a compare match. The mode can be: +@li Frozen - the output does not respond to a match. +@li Active - the output assumes the active state on the first match. +@li Inactive - the output assumes the inactive state on the first match. +@li Toggle - The output switches between active and inactive states on each match. +@li Force inactive. The output is forced low regardless of the compare state. +@li Force active. The output is forced high regardless of the compare state. +@li PWM1 - The output is active when the counter is less than the compare register contents +and inactive otherwise. +@li PWM2 - The output is inactive when the counter is less than the compare register contents +and active otherwise. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +@param[in] oc_mode enum ::tim_oc_mode. OC mode designators. + TIM_OCM_FROZEN, TIM_OCM_ACTIVE, TIM_OCM_INACTIVE, TIM_OCM_TOGGLE, + TIM_OCM_FORCE_LOW, TIM_OCM_FORCE_HIGH, TIM_OCM_PWM1, TIM_OCM_PWM2 +*/ + void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, enum tim_oc_mode oc_mode) { @@ -510,6 +975,14 @@ void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare Preload Register + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +*/ + void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -533,6 +1006,14 @@ void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare Preload Register + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action) +*/ + void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -556,6 +1037,16 @@ void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set the Output Polarity High + +The polarity of the channel output is set active high. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -601,6 +1092,16 @@ void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set the Output Polarity Low + +The polarity of the channel output is set active low. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -646,6 +1147,16 @@ void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Enable the Output Compare + +The channel output compare functionality is enabled. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -691,6 +1202,16 @@ void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Disable the Output Compare + +The channel output compare functionality is disabled. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) { switch (oc_id) { @@ -736,6 +1257,19 @@ void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer set Output Compare Idle State High + +@sa Similar function suitable for multiple OC idle state settings +@ref timer_set_output_idle_state + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) { /* Acting for TIM1 and TIM8 only. */ @@ -767,6 +1301,19 @@ void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Idle State Low + +@sa Similar function suitable for multiple OC idle state settings +@ref timer_reset_output_idle_state + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8) +*/ + void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) { /* Acting for TIM1 and TIM8 only. */ @@ -798,6 +1345,19 @@ void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) } } +/*---------------------------------------------------------------------------*/ +/** @brief Timer Set Output Compare Value + +This is a convenience function to set the OC preload register value for loading +to the compare register. + +@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base + (TIM9 .. TIM14 not yet supported here). +@param[in] oc_id enum ::tim_oc_id OC channel designators + TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken) +@param[in] value Unsigned int32. Compare value. +*/ + void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) { switch (oc_id) { @@ -821,100 +1381,306 @@ void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) } } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Output in Break + +Enables the output in the Break feature of an advanced timer. This does not +enable the break functionality itself but only sets the Master Output Enable in +the Break and Deadtime Register. + +@note This setting is only valid for the advanced timers. + +@note It is necessary to call this function to enable the output on an advanced +timer even if break or deadtime features are not being used<\b>. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_enable_break_main_output(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Output in Break + +Disables the output in the Break feature of an advanced timer. This clears +the Master Output Enable in the Break and Deadtime Register. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_disable_break_main_output(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Automatic Output in Break + +Enables the automatic output feature of the Break function of an advanced +timer so that the output is re-enabled at the next update event following a +break event. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_enable_break_automatic_output(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Automatic Output in Break + +Disables the automatic output feature of the Break function of an advanced +timer so that the output is re-enabled at the next update event following a +break event. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_disable_break_automatic_output(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE; } +/*---------------------------------------------------------------------------*/ +/** @brief Activate Break when Input High + +Sets the break function to activate when the break input becomes high. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_set_break_polarity_high(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP; } +/*---------------------------------------------------------------------------*/ +/** @brief Activate Break when Input Low + +Sets the break function to activate when the break input becomes low. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_set_break_polarity_low(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Break + +Enables the break function of an advanced timer. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_enable_break(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Break + +Disables the break function of an advanced timer. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_disable_break(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Off-State in Run Mode + +Enables the off-state in run mode for the break function of an advanced +timer in which the complementary outputs have been configured. It has no effect +if no complementary output is present. When the capture-compare output is +disabled while the complementary output is enabled, the output is set to its +inactive level as defined by the output polarity. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Off-State in Run Mode + +Disables the off-state in run mode for the break function of an advanced +timer in which the complementary outputs have been configured. It has no effect +if no complementary output is present. When the capture-compare output is +disabled, the output is also disabled. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR; } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Off-State in Idle Mode + +Enables the off-state in idle mode for the break function of an advanced +timer. When the master output is disabled the output is set to its +inactive level as defined by the output polarity. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI; } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Off-State in Idle Mode + +Disables the off-state in idle mode for the break function of an advanced +timer. When the master output is disabled the output is also disabled. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +*/ + void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Lock Bits + +Set the lock bits for an advanced timer. Three levels of lock providing +protection against software errors. Once written they cannot be changed until a +timer reset has occurred. + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +@param[in] lock Unsigned int32. Lock specification @ref tim_lock +*/ + void timer_set_break_lock(u32 timer_peripheral, u32 lock) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= lock; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Deadtime + +The deadtime and sampling clock (DTSC) is set in the clock division ratio part of the +timer mode settings. The deadtime count is an 8 bit value defined in terms of the +number of DTSC cycles: + +@li Bit 7 = 0, deadtime = bits(6:0) +@li Bits 7:6 = 10, deadtime = 2x(64+bits(5:0)) +@li Bits 7:5 = 110, deadtime = 8x(32+bits(5:0)) +@li Bits 7:5 = 111, deadtime = 16x(32+bits(5:0)) + +@note This setting is only valid for the advanced timers. + +@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 +@param[in] deadtime Unsigned int32. Deadtime count specification as defined above. +*/ + void timer_set_deadtime(u32 timer_peripheral, u32 deadtime) { if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) TIM_BDTR(timer_peripheral) |= deadtime; } +/*---------------------------------------------------------------------------*/ +/** @brief Force generate a timer event. + +The event specification consists of 8 possible events that can be forced on the +timer. The forced events are automatically cleared by hardware. The UG event is +useful to cause shadow registers to be preloaded before the timer is started to +avoid uncertainties in the first cycle in case an update event may never be +generated. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] event Unsigned int32. Event specification @ref tim_event_gen +*/ + void timer_generate_event(u32 timer_peripheral, u32 event) { TIM_EGR(timer_peripheral) |= event; } +/*---------------------------------------------------------------------------*/ +/** @brief Read Counter + +Read back the value of a timer's counter register contents + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@returns Unsigned int32. Counter value. +*/ + u32 timer_get_counter(u32 timer_peripheral) { return TIM_CNT(timer_peripheral); } +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Capture Filter Parameters + +Set the input filter parameters for an input channel, specifying: +@li the frequency of sampling from the Deadtime and Sampling clock +(@see @ref timer_set_clock_division) +@li the number of events that must occur before a transition is considered valid. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] flt ::tim_ic_filter. Input Capture Filter identifier. +*/ + void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt) { switch (ic) { @@ -937,6 +1703,16 @@ void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt) } } +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Capture Prescaler + +Set the number of events between each capture. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler. +*/ + void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc) { switch (ic) { @@ -959,6 +1735,27 @@ void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc) } } +/*---------------------------------------------------------------------------*/ +/** @brief Set Capture/Compare Channel Direction/Input + +The Capture/Compare channel is defined as output (compare) or input with the input +mapping specified: + +@li channel is configured as output +@li channel is configured as input and mapped on corresponding input +@li channel is configured as input and mapped on alternate input +(TI2 for channel 1, TI1 for channel 2, TI4 for channel 3, TI3 for channel 4) +@li channel is configured as input and is mapped on TRC (requires an +internal trigger input selected through TS bit + +@note not all combinations of the input and channel are valid, see datasheets. +@note these parameters are writable only when the channel is off. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] in ::tim_ic_input. Input Capture channel direction and source input. +*/ + void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in) { in &= 3; @@ -989,6 +1786,14 @@ void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in) } } +/*---------------------------------------------------------------------------*/ +/** @brief Set Input Polarity + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +@param[in] pol ::tim_ic_pol. Input Capture polarity. +*/ + void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol) { if (pol) @@ -997,28 +1802,70 @@ void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol) TIM_CCER(timer) &= ~(0x2 << (ic * 4)); } +/*---------------------------------------------------------------------------*/ +/** @brief Enable Timer Input Capture + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +*/ + void timer_ic_enable(u32 timer, enum tim_ic_id ic) { TIM_CCER(timer) |= (0x1 << (ic * 4)); } +/*---------------------------------------------------------------------------*/ +/** @brief Disable Timer Input Capture + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] ic ::tim_ic_id. Input Capture channel designator. +*/ + void timer_ic_disable(u32 timer, enum tim_ic_id ic) { TIM_CCER(timer) &= ~(0x1 << (ic * 4)); } +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Filter Parameters for Slave + +Set the input filter parameters for the external trigger, specifying: +@li the frequency of sampling from the Deadtime and Sampling clock +(@see @ref timer_set_clock_division) +@li the number of events that must occur before a transition is considered valid. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] flt ::tim_ic_filter. Input Capture Filter identifier. +*/ + void timer_slave_set_filter(u32 timer, enum tim_ic_filter flt) { TIM_SMCR(timer) &= ~TIM_SMCR_ETF_MASK; TIM_SMCR(timer) |= flt << 8; } +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Prescaler for Slave + +Set the external trigger frequency division ratio. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler. +*/ + void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc) { TIM_SMCR(timer) &= ~TIM_SMCR_ETPS_MASK; TIM_SMCR(timer) |= psc << 12; } +/*---------------------------------------------------------------------------*/ +/** @brief Set External Trigger Polarity for Slave + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] pol ::tim_ic_pol. Input Capture polarity. +*/ + void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol) { if (pol) @@ -1027,15 +1874,48 @@ void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol) TIM_SMCR(timer) &= ~TIM_SMCR_ETP; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Slave Mode + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] mode Unsigned int8. Slave mode @ref tim_sms +*/ + void timer_slave_set_mode(u32 timer, u8 mode) { TIM_SMCR(timer) &= ~TIM_SMCR_SMS_MASK; TIM_SMCR(timer) |= mode; } +/*---------------------------------------------------------------------------*/ +/** @brief Set Slave Trigger Source + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] trigger Unsigned int8. Slave trigger source @ref tim_ts +*/ + void timer_slave_set_trigger(u32 timer, u8 trigger) { TIM_SMCR(timer) &= ~TIM_SMCR_TS_MASK; TIM_SMCR(timer) |= trigger; } +/*---------------------------------------------------------------------------*/ +/** @brief Force Timer Event + +A number of events can be forced by software action. All events are cleared by +hardware on completion. + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@param[in] event Unsigned int8. Event identifier @ref tim_event_gen. +More than one event can be forced at the same time by logical OR of the event +identifiers. +*/ + +void timer_force_event(u32 timer, u8 event) +{ + TIM_EGR(timer) = event; +} + +/* TODO Timer DMA burst */ + -- cgit v1.2.3 From 0e5e451e2287c61e4ca046561b8daedd412a6bc8 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Tue, 14 Aug 2012 18:25:19 +0930 Subject: Revert nvic_set_priority to original form. Minor doxygen markup changes. --- include/libopencm3/stm32/f1/nvic_f1.h | 2 +- lib/stm32/nvic.c | 41 ++++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 18 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/f1/nvic_f1.h b/include/libopencm3/stm32/f1/nvic_f1.h index ce9a99e..99594ee 100644 --- a/include/libopencm3/stm32/f1/nvic_f1.h +++ b/include/libopencm3/stm32/f1/nvic_f1.h @@ -27,7 +27,7 @@ */ /* User Interrupts */ -/** @defgroup nvic_stn32f1_userint STM32F1xx User Interrupts +/** @defgroup nvic_stm32f1_userint STM32F1xx User Interrupts @ingroup STM32F_nvic_defines @{*/ diff --git a/lib/stm32/nvic.c b/lib/stm32/nvic.c index ea502b3..9fda91c 100644 --- a/lib/stm32/nvic.c +++ b/lib/stm32/nvic.c @@ -9,13 +9,15 @@ @author @htmlonly © @endhtmlonly 2010 Thomas Otto @author @htmlonly © @endhtmlonly 2012 Fergus Noble -@date 7 July 2012 +@date 14 August 2012 The STM32F series provides up to 68 maskable user interrupts for the STM32F10x series, and 87 for the STM32F2xx and STM32F4xx series. -The NVIC registers are defined by the ARM standards +The NVIC registers are defined by the ARM standards but the STM32F series have some +additional limitations @see Cortex-M3 Devices Generic User Guide +@see STM32F10xxx Cortex-M3 programming manual LGPL License Terms @ref lgpl_license @@ -47,7 +49,7 @@ LGPL License Terms @ref lgpl_license Enables a user interrupt. -@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint */ void nvic_enable_irq(u8 irqn) @@ -60,7 +62,7 @@ void nvic_enable_irq(u8 irqn) Disables a user interrupt. -@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint */ void nvic_disable_irq(u8 irqn) @@ -73,7 +75,7 @@ void nvic_disable_irq(u8 irqn) True if the interrupt has occurred and is waiting for service. -@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint @return Boolean. Interrupt pending. */ @@ -85,10 +87,10 @@ u8 nvic_get_pending_irq(u8 irqn) /*-----------------------------------------------------------------------------*/ /** @brief NVIC Set Pending Interrupt -Force a user interrupt to a pending state. No effect if the interrupt is already -pending. +Force a user interrupt to a pending state. This has no effect if the interrupt +is already pending. -@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint */ void nvic_set_pending_irq(u8 irqn) @@ -99,10 +101,10 @@ void nvic_set_pending_irq(u8 irqn) /*-----------------------------------------------------------------------------*/ /** @brief NVIC Clear Pending Interrupt -Force remove a user interrupt from a pending state. No effect if the interrupt is -actively being serviced. +Force remove a user interrupt from a pending state. This has no effect if the +interrupt is actively being serviced. -@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint */ void nvic_clear_pending_irq(u8 irqn) @@ -115,7 +117,7 @@ void nvic_clear_pending_irq(u8 irqn) Interrupt has occurred and is currently being serviced. -@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint @return Boolean. Interrupt active. */ @@ -127,7 +129,7 @@ u8 nvic_get_active_irq(u8 irqn) /*-----------------------------------------------------------------------------*/ /** @brief NVIC Return Enabled Interrupt -@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint @return Boolean. Interrupt enabled. */ @@ -139,13 +141,18 @@ u8 nvic_get_irq_enabled(u8 irqn) /*-----------------------------------------------------------------------------*/ /** @brief NVIC Set Interrupt Priority -@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stn32f1_userint -@param[in] priority Unsigned int8. Interrupt priority (0 ... 255) +There are 16 priority levels only, given by the upper four bits of the priority +byte, as required by ARM standards. The priority levels are interpreted according +to the pre-emptive priority grouping set in the SCB Application Interrupt and Reset +Control Register (SCB_AIRCR), as done in @ref scb_set_priority_grouping. + +@param[in] irqn Unsigned int8. Interrupt number @ref nvic_stm32f1_userint +@param[in] priority Unsigned int8. Interrupt priority (0 ... 255 in steps of 16) */ void nvic_set_priority(u8 irqn, u8 priority) { - NVIC_IPR(irqn / 4) = (priority << ((irqn % 4) * 8)); + NVIC_IPR(irqn) = priority; } /*-----------------------------------------------------------------------------*/ @@ -154,7 +161,7 @@ void nvic_set_priority(u8 irqn, u8 priority) Generate an interrupt from software. This has no effect for unprivileged access unless the privilege level has been elevated through the System Control Registers. -@param[in] sgin Unsigned int16. Interrupt number (0 ... 239) +@param[in] irqn Unsigned int16. Interrupt number (0 ... 239) */ void nvic_generate_software_interrupt(u16 irqn) -- cgit v1.2.3 From 70b2376c9f8e008f7e5e8967206b73a2fe7926f9 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Sat, 18 Aug 2012 13:32:48 +0930 Subject: Update to doxygen comments to fix promiscuity problem (see later) --- include/libopencm3/stm32/f1/nvic_f1.h | 14 ++++++++++++++ include/libopencm3/stm32/nvic.h | 6 +++--- lib/stm32/nvic.c | 11 +++++++---- 3 files changed, 24 insertions(+), 7 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/f1/nvic_f1.h b/include/libopencm3/stm32/f1/nvic_f1.h index 99594ee..bb0e03d 100644 --- a/include/libopencm3/stm32/f1/nvic_f1.h +++ b/include/libopencm3/stm32/f1/nvic_f1.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F_nvic_f1_defines STM32F NVIC Defines + +@brief Defined Constants and Types for the STM32F1xx Nested Vectored Interrupt Controller + +@ingroup STM32F_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h index f974483..f6a6075 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/stm32/nvic.h @@ -1,9 +1,9 @@ -/** @file - -@ingroup STM32F +/** @defgroup STM32F_nvic_defines STM32F NVIC Defines @brief libopencm3 STM32F Nested Vectored Interrupt Controller +@ingroup STM32F_defines + @version 1.0.0 @author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski diff --git a/lib/stm32/nvic.c b/lib/stm32/nvic.c index 9fda91c..e17e78c 100644 --- a/lib/stm32/nvic.c +++ b/lib/stm32/nvic.c @@ -1,6 +1,6 @@ -/** @file +/** @defgroup STM32F-nvic-file NVIC -@ingroup STM32F +@ingroup STM32F-files @brief libopencm3 STM32F Nested Vectored Interrupt Controller @@ -9,7 +9,7 @@ @author @htmlonly © @endhtmlonly 2010 Thomas Otto @author @htmlonly © @endhtmlonly 2012 Fergus Noble -@date 14 August 2012 +@date 18 August 2012 The STM32F series provides up to 68 maskable user interrupts for the STM32F10x series, and 87 for the STM32F2xx and STM32F4xx series. @@ -19,7 +19,6 @@ additional limitations @see Cortex-M3 Devices Generic User Guide @see STM32F10xxx Cortex-M3 programming manual - LGPL License Terms @ref lgpl_license */ /* @@ -42,6 +41,8 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ +/**@{*/ + #include /*-----------------------------------------------------------------------------*/ @@ -169,3 +170,5 @@ void nvic_generate_software_interrupt(u16 irqn) if (irqn <= 239) NVIC_STIR |= irqn; } +/**@}*/ + -- cgit v1.2.3 From 95126e8cd3740794c61ed9a832d7a77eca94f1c9 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Sat, 18 Aug 2012 16:05:17 +0930 Subject: Tiny doxygen mod to get all constants to show in doc output --- include/libopencm3/stm32/nvic.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h index f6a6075..cc8dcd6 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/stm32/nvic.h @@ -39,6 +39,7 @@ LGPL License Terms @ref lgpl_license * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ +/**@{*/ #ifndef LIBOPENCM3_NVIC_H #define LIBOPENCM3_NVIC_H @@ -135,3 +136,5 @@ void nvic_set_priority(u8 irqn, u8 priority); void nvic_generate_software_interrupt(u16 irqn); #endif +/**@}*/ + -- cgit v1.2.3 From e4bcceaa8fcaddda448c2e1495d82d5895fe6f43 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Sat, 18 Aug 2012 16:19:47 +0930 Subject: And a bit more doc mods --- include/libopencm3/stm32/nvic.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h index cc8dcd6..6a98737 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/stm32/nvic.h @@ -8,18 +8,9 @@ @author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski -@date 8 July 2012 +@date 18 August 2012 LGPL License Terms @ref lgpl_license - */ -/** @defgroup STM32F_nvic_defines - -@brief Defined Constants and Types for the STM32F Nested Vectored Interrupt Controller - -@ingroup STM32F_defines - -LGPL License Terms @ref lgpl_license - */ /* * This file is part of the libopencm3 project. -- cgit v1.2.3 From 52533a6e3d2e3a1936ce76692774557a354d3569 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Mon, 20 Aug 2012 17:19:20 +0930 Subject: STM32F1xx: Changed markup to get more control over documentation, each file having its own group module rather than using @file. No code changes except for the following: gpio: Added function to map the eventout signal plus two Remap functions dma: Prevent changing base addresses while channel enabled (see datasheet) pwr: Added pwr.c (new file) timer: Removed the last function that I introduced recently; there is already an equivalent function present. Changed some parameter names for consistency. --- include/libopencm3/cm3/docmain.h | 22 ++- include/libopencm3/stm32/dac.h | 32 ++- include/libopencm3/stm32/doc-stm32f.h | 15 +- include/libopencm3/stm32/f1/dma.h | 38 ++++ include/libopencm3/stm32/f1/doc-stm32f1.h | 6 +- include/libopencm3/stm32/f1/gpio.h | 246 +++++++++++++++++++---- include/libopencm3/stm32/f1/rcc.h | 96 +++++++-- include/libopencm3/stm32/iwdg.h | 28 +++ include/libopencm3/stm32/pwr.h | 56 +++++- include/libopencm3/stm32/systick.h | 25 +++ include/libopencm3/stm32/timer.h | 44 ++--- lib/stm32/dac.c | 47 ++--- lib/stm32/f1/dma.c | 229 +++++++++++++++++++++- lib/stm32/f1/gpio.c | 229 ++++++++++++++++++---- lib/stm32/f1/pwr.c | 217 ++++++++++++++++++++ lib/stm32/f1/rcc.c | 315 ++++++++++++++++++++++++++++-- lib/stm32/f1/timer.c | 132 ++++++------- lib/stm32/iwdg.c | 18 +- lib/stm32/systick.c | 75 +++++++ 19 files changed, 1584 insertions(+), 286 deletions(-) create mode 100644 lib/stm32/f1/pwr.c (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/cm3/docmain.h b/include/libopencm3/cm3/docmain.h index 865b6ea..9407ceb 100644 --- a/include/libopencm3/cm3/docmain.h +++ b/include/libopencm3/cm3/docmain.h @@ -1,6 +1,12 @@ /** * @mainpage libopencm3 Developer Documentation - * + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + +@date 18 August 2012 + * The libopencm3 project (previously known as libopenstm32) aims to create * a free/libre/open-source (GPL v3, or later) firmware library for various * ARM Cortex-M3 microcontrollers, including ST STM32, Toshiba TX03, @@ -31,33 +37,33 @@ program. If not, see . */ -/** @defgroup LM3S +/** @defgroup LM3S LM3S Libraries for Texas instruments LM3S series. */ -/** @defgroup LPC13xx +/** @defgroup LPC13xx LPC13xx Libraries for NXP Semiconductor LPC13xx series. */ -/** @defgroup LPC17xx +/** @defgroup LPC17xx LPC17xx Libraries for NXP Semiconductor LPC17xx series. */ -/** @defgroup STM32F +/** @defgroup STM32F STM32F Libraries for ST Microelectronics STM32F series. */ -/** @defgroup STM32F1xx +/** @defgroup STM32F1xx STM32F1xx @ingroup STM32F Libraries for ST Microelectronics STM32F1xx series. */ -/** @defgroup STM32F2xx +/** @defgroup STM32F2xx STM32F2xx @ingroup STM32F Libraries for ST Microelectronics STM32F2xx series. */ -/** @defgroup STM32F4xx +/** @defgroup STM32F4xx STM32F4xx @ingroup STM32F Libraries for ST Microelectronics STM32F4xx series. */ diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h index 96ac8d0..3a57132 100644 --- a/include/libopencm3/stm32/dac.h +++ b/include/libopencm3/stm32/dac.h @@ -1,27 +1,19 @@ -/** @file +/** @defgroup STM32F_dac_defines DAC Defines -@ingroup STM32F +@brief libopencm3 Defined Constants and Types for the STM32F Digital to Analog Converter -@brief libopencm3 STM32F Digital to Analog Converter +@ingroup STM32F_defines @version 1.0.0 @author @htmlonly © @endhtmlonly 2012 Felix Held @author @htmlonly © @endhtmlonly 2012 Ken Sarkies -@date 30 June 2012 +@date 18 August 2012 LGPL License Terms @ref lgpl_license */ -/** @defgroup STM32F_dac_defines - -@brief Defined Constants and Types for the STM32F Digital to Analog Converter -@ingroup STM32F_defines - -LGPL License Terms @ref lgpl_license - - */ /* * This file is part of the libopencm3 project. * @@ -41,6 +33,8 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_DAC_H #define LIBOPENCM3_DAC_H @@ -121,7 +115,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 #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: @@ -143,7 +137,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 @{*/ #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: @@ -193,7 +187,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n)-1 #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) @@ -233,7 +227,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 #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: @@ -256,7 +250,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 @{*/ #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: @@ -306,7 +300,7 @@ Unmask bits [(n-1)..0] of LFSR/Triangle Amplitude equal to (2**(n+1)-1 #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) @@ -416,3 +410,5 @@ void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data void dac_software_trigger(data_channel dac_channel); #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/doc-stm32f.h b/include/libopencm3/stm32/doc-stm32f.h index e592c12..0f3f850 100644 --- a/include/libopencm3/stm32/doc-stm32f.h +++ b/include/libopencm3/stm32/doc-stm32f.h @@ -1,13 +1,24 @@ -/** @defgroup STM32F_defines +/** @defgroup STM32F_defines STM32F Top Level Defines @brief Defined Constants and Types for the STM32F series @ingroup STM32F +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + @version 1.0.0 -@date 8 July 2012 +@date 18 August 2012 LGPL License Terms @ref lgpl_license */ +/** @defgroup STM32F-files STM32F Top Level Files + +@brief Common Files for ST Microelectronics STM32F series. + +@ingroup STM32F + +*/ + + diff --git a/include/libopencm3/stm32/f1/dma.h b/include/libopencm3/stm32/f1/dma.h index 5aa0183..64eafe0 100644 --- a/include/libopencm3/stm32/f1/dma.h +++ b/include/libopencm3/stm32/f1/dma.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F1xx_dma_defines DMA Defines + +@ingroup STM32F1xx_defines + +@brief Defined Constants and Types for the STM32F1xx DMA Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -18,6 +32,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_DMA_H #define LIBOPENCM3_DMA_H @@ -241,24 +257,39 @@ #define DMA_CCR_MEM2MEM (1 << 14) /* PL[13:12]: Channel priority level */ +/** @defgroup dma_ch_pri DMA Channel Priority Levels +@ingroup STM32F1xx_dma_defines + +@{*/ #define DMA_CCR_PL_LOW (0x0 << 12) #define DMA_CCR_PL_MEDIUM (0x1 << 12) #define DMA_CCR_PL_HIGH (0x2 << 12) #define DMA_CCR_PL_VERY_HIGH (0x3 << 12) +/**@}*/ #define DMA_CCR_PL_MASK (0x3 << 12) #define DMA_CCR_PL_SHIFT 12 /* MSIZE[11:10]: Memory size */ +/** @defgroup dma_ch_memwidth DMA Channel Memory Word Width +@ingroup STM32F1xx_dma_defines + +@{*/ #define DMA_CCR_MSIZE_8BIT (0x0 << 10) #define DMA_CCR_MSIZE_16BIT (0x1 << 10) #define DMA_CCR_MSIZE_32BIT (0x2 << 10) +/**@}*/ #define DMA_CCR_MSIZE_MASK (0x3 << 10) #define DMA_CCR_MSIZE_SHIFT 10 /* PSIZE[9:8]: Peripheral size */ +/** @defgroup dma_ch_perwidth DMA Channel Peripheral Word Width +@ingroup STM32F1xx_dma_defines + +@{*/ #define DMA_CCR_PSIZE_8BIT (0x0 << 8) #define DMA_CCR_PSIZE_16BIT (0x1 << 8) #define DMA_CCR_PSIZE_32BIT (0x2 << 8) +/**@}*/ #define DMA_CCR_PSIZE_MASK (0x3 << 8) #define DMA_CCR_PSIZE_SHIFT 8 @@ -300,6 +331,10 @@ /* --- Generic values ------------------------------------------------------ */ +/** @defgroup dma_ch DMA Channel Number +@ingroup STM32F1xx_dma_defines + +@{*/ #define DMA_CHANNEL1 1 #define DMA_CHANNEL2 2 #define DMA_CHANNEL3 3 @@ -307,6 +342,7 @@ #define DMA_CHANNEL5 5 #define DMA_CHANNEL6 6 #define DMA_CHANNEL7 7 +/**@}*/ /* --- function prototypes ------------------------------------------------- */ @@ -333,3 +369,5 @@ void dma_set_memory_address(u32 dma, u8 channel, u32 address); void dma_set_number_of_data(u32 dma, u8 channel, u16 number); #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/f1/doc-stm32f1.h b/include/libopencm3/stm32/f1/doc-stm32f1.h index 33bae3a..04293a6 100644 --- a/include/libopencm3/stm32/f1/doc-stm32f1.h +++ b/include/libopencm3/stm32/f1/doc-stm32f1.h @@ -1,12 +1,14 @@ -/** @defgroup STM32F1xx_defines +/** @defgroup STM32F1xx_defines STM32F1xx Defines @brief Defined Constants and Types for the STM32F1xx series @ingroup STM32F1xx +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net + @version 1.0.0 -@date 24 May 2012 +@date 18 August 2012 LGPL License Terms @ref lgpl_license */ diff --git a/include/libopencm3/stm32/f1/gpio.h b/include/libopencm3/stm32/f1/gpio.h index e4e11be..2f4292a 100644 --- a/include/libopencm3/stm32/f1/gpio.h +++ b/include/libopencm3/stm32/f1/gpio.h @@ -1,3 +1,18 @@ +/** @defgroup STM32F1xx_gpio_defines GPIO Defines + +@brief Defined Constants and Types for the STM32F1xx General Purpose I/O + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 Piotr Esden-Tempski + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +32,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ +/**@{*/ #ifndef LIBOPENCM3_GPIO_H #define LIBOPENCM3_GPIO_H @@ -27,6 +43,10 @@ /* --- Convenience macros -------------------------------------------------- */ /* GPIO port base addresses (for convenience) */ +/** @defgroup gpio_port_id GPIO Port IDs +@ingroup STM32F1xx_gpio_defines + +@{*/ #define GPIOA GPIO_PORT_A_BASE #define GPIOB GPIO_PORT_B_BASE #define GPIOC GPIO_PORT_C_BASE @@ -34,8 +54,13 @@ #define GPIOE GPIO_PORT_E_BASE #define GPIOF GPIO_PORT_F_BASE #define GPIOG GPIO_PORT_G_BASE +/**@}*/ /* GPIO number definitions (for convenience) */ +/** @defgroup gpio_pin_id GPIO Pin Identifiers +@ingroup STM32F1xx_gpio_defines + +@{*/ #define GPIO0 (1 << 0) #define GPIO1 (1 << 1) #define GPIO2 (1 << 2) @@ -53,6 +78,7 @@ #define GPIO14 (1 << 14) #define GPIO15 (1 << 15) #define GPIO_ALL 0xffff +/**@}*/ /* --- Alternate function GPIOs -------------------------------------------- */ @@ -593,22 +619,50 @@ /* --- GPIO_CRL/GPIO_CRH values -------------------------------------------- */ +/** @defgroup gpio_cnf GPIO Pin Configuration +@ingroup STM32F1xx_gpio_defines +If mode specifies input, configuration can be +@li Analog input +@li Floating input +@li Pull up/down input + +If mode specifies output, configuration can be +@li Digital push-pull +@li Digital open drain +@li Alternate function push-pull or analog output +@li Alternate function open drain or analog output +@{*/ /* CNF[1:0] values when MODE[1:0] is 00 (input mode) */ +/** Analog Input */ #define GPIO_CNF_INPUT_ANALOG 0x00 +/** Digital Input Floating */ #define GPIO_CNF_INPUT_FLOAT 0x01 /* Default */ +/** Digital Input Pull Up and Down */ #define GPIO_CNF_INPUT_PULL_UPDOWN 0x02 - -/* Output mode (MODE[1:0]) values */ -#define GPIO_MODE_INPUT 0x00 /* Default */ -#define GPIO_MODE_OUTPUT_10_MHZ 0x01 -#define GPIO_MODE_OUTPUT_2_MHZ 0x02 -#define GPIO_MODE_OUTPUT_50_MHZ 0x03 - /* CNF[1:0] values when MODE[1:0] is != 00 (one of the output modes) */ +/** Digital Output Pushpull */ #define GPIO_CNF_OUTPUT_PUSHPULL 0x00 +/** Digital Output Open Drain */ #define GPIO_CNF_OUTPUT_OPENDRAIN 0x01 +/** Alternate Function Output Pushpull */ #define GPIO_CNF_OUTPUT_ALTFN_PUSHPULL 0x02 +/** Alternate Function Output Open Drain */ #define GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN 0x03 +/**@}*/ + +/* Pin mode (MODE[1:0]) values */ +/** @defgroup gpio_mode GPIO Pin Mode +@ingroup STM32F1xx_gpio_defines +@li Input (default after reset) +@li Output mode at 10 MHz maximum speed +@li Output mode at 2 MHz maximum speed +@li Output mode at 50 MHz maximum speed +@{*/ +#define GPIO_MODE_INPUT 0x00 /* Default */ +#define GPIO_MODE_OUTPUT_10_MHZ 0x01 +#define GPIO_MODE_OUTPUT_2_MHZ 0x02 +#define GPIO_MODE_OUTPUT_50_MHZ 0x03 +/**@}*/ /* --- GPIO_IDR values ----------------------------------------------------- */ @@ -652,19 +706,31 @@ /* External interrupt configuration register 4 (AFIO_EXTICR4) */ #define AFIO_EXTICR4 MMIO32(AFIO_BASE + 0x14) +/* AF remap and debug I/O configuration register (AFIO_MAPR) */ +#define AFIO_MAPR2 MMIO32(AFIO_BASE + 0x1C) + /* --- AFIO_EVCR values ---------------------------------------------------- */ /* EVOE: Event output enable */ #define AFIO_EVCR_EVOE (1 << 7) /* PORT[2:0]: Port selection */ +/** @defgroup afio_evcr_port EVENTOUT Port selection +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_EVCR_PORT_PA (0x0 << 4) #define AFIO_EVCR_PORT_PB (0x1 << 4) #define AFIO_EVCR_PORT_PC (0x2 << 4) #define AFIO_EVCR_PORT_PD (0x3 << 4) #define AFIO_EVCR_PORT_PE (0x4 << 4) +/**@}*/ /* PIN[3:0]: Pin selection */ +/** @defgroup afio_evcr_pin EVENTOUT Pin selection +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_EVCR_PIN_Px0 (0x0 << 0) #define AFIO_EVCR_PIN_Px1 (0x1 << 0) #define AFIO_EVCR_PIN_Px2 (0x2 << 0) @@ -681,117 +747,206 @@ #define AFIO_EVCR_PIN_Px13 (0xD << 0) #define AFIO_EVCR_PIN_Px14 (0xE << 0) #define AFIO_EVCR_PIN_Px15 (0xF << 0) +/**@}*/ /* --- AFIO_MAPR values ---------------------------------------------------- */ /* 31 reserved */ -/* PTP_PPS_REMAP: Ethernet PTP PPS remapping +/** @defgroup afio_remap_cld Alternate Function Remap Controls for Connectivity +Line Devices only +@ingroup STM32F1xx_gpio_defines + +@{*/ +/* PTP_PPS_REMAP: *//** Ethernet PTP PPS remapping * (only connectivity line devices) */ #define AFIO_MAPR_PTP_PPS_REMAP (1 << 30) -/* TIM2ITR1_IREMAP: TIM2 internal trigger 1 remapping +/* TIM2ITR1_IREMAP: *//** TIM2 internal trigger 1 remapping * (only connectivity line devices) */ #define AFIO_MAPR_TIM2ITR1_IREMAP (1 << 29) -/* SPI3_REMAP: SPI3/I2S3 remapping +/* SPI3_REMAP: *//** SPI3/I2S3 remapping * (only connectivity line devices) */ #define AFIO_MAPR_SPI3_REMAP (1 << 28) +/* MII_REMAP: */ /** MII or RMII selection + * (only connectivity line devices) */ +#define AFIO_MAPR_MII_RMII_SEL (1 << 23) + +/* CAN2_REMAP: */ /** CAN2 I/O remapping + * (only connectivity line devices) */ +#define AFIO_MAPR_CAN2_REMAP (1 << 22) + +/* ETH_REMAP: */ /** Ethernet MAC I/O remapping + * (only connectivity line devices) */ +#define AFIO_MAPR_ETH_REMAP (1 << 21) + +/**@}*/ + /* 27 reserved */ /* SWJ_CFG[2:0]: Serial wire JTAG configuration */ +/** @defgroup afio_swj_disable Serial Wire JTAG disables +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_SWJ_MASK (0x7 << 24) +/** Full Serial Wire JTAG capability */ #define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) +/** Full Serial Wire JTAG capability without JNTRST */ #define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST (0x1 << 24) +/** JTAG-DP disabled with SW-DP enabled */ #define AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON (0x2 << 24) +/** JTAG-DP disabled and SW-DP disabled */ #define AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF (0x4 << 24) +/**@}*/ -/* MII_REMAP: MII or RMII selection - * (only connectivity line devices) */ -#define AFIO_MAPR_MII_RMII_SEL (1 << 23) +/** @defgroup afio_remap Alternate Function Remap Controls +@ingroup STM32F1xx_gpio_defines -/* CAN2_REMAP: CAN2 I/O remapping - * (only connectivity line devices) */ -#define AFIO_MAPR_CAN2_REMAP (1 << 22) - -/* ETH_REMAP: Ethernet MAC I/O remapping - * (only connectivity line devices) */ -#define AFIO_MAPR_ETH_REMAP (1 << 21) - -/* ADC2_ETRGREG_REMAP: ADC2 external trigger regulator conversion remapping +@{*/ +/* ADC2_ETRGREG_REMAP: */ /** ADC2 external trigger regulator conversion remapping * (only low-, medium-, high- and XL-densitiy devices) */ #define AFIO_MAPR_ADC2_ETRGREG_REMAP (1 << 20) -/* ADC2_ETRGINJ_REMAP: ADC2 external trigger injected conversion remapping +/* ADC2_ETRGINJ_REMAP: */ /** ADC2 external trigger injected conversion remapping * (only low-, medium-, high- and XL-densitiy devices) */ #define AFIO_MAPR_ADC2_ETRGINJ_REMAP (1 << 19) -/* ADC1_ETRGREG_REMAP: ADC1 external trigger regulator conversion remapping +/* ADC1_ETRGREG_REMAP: */ /** ADC1 external trigger regulator conversion remapping * (only low-, medium-, high- and XL-densitiy devices) */ #define AFIO_MAPR_ADC1_ETRGREG_REMAP (1 << 18) -/* ADC1_ETRGINJ_REMAP: ADC1 external trigger injected conversion remapping +/* ADC1_ETRGINJ_REMAP: */ /** ADC1 external trigger injected conversion remapping * (only low-, medium-, high- and XL-densitiy devices) */ #define AFIO_MAPR_ADC1_ETRGINJ_REMAP (1 << 17) -/* TIM5CH4_IREMAP: TIM5 channel4 internal remap */ +/* TIM5CH4_IREMAP: */ /** TIM5 channel4 internal remap */ #define AFIO_MAPR_TIM5CH4_IREMAP (1 << 16) -/* PD01_REMAP: Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ +/* PD01_REMAP: */ /** Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ #define AFIO_MAPR_PD01_REMAP (1 << 15) +/* TIM4_REMAP: */ /** TIM4 remapping */ +#define AFIO_MAPR_TIM4_REMAP (1 << 12) + +/* USART2_REMAP[1:0]: */ /** USART2 remapping */ +#define AFIO_MAPR_USART2_REMAP (1 << 3) + +/* USART1_REMAP[1:0]: */ /** USART1 remapping */ +#define AFIO_MAPR_USART1_REMAP (1 << 2) + +/* I2C1_REMAP[1:0]: */ /** I2C1 remapping */ +#define AFIO_MAPR_I2C1_REMAP (1 << 1) + +/* SPI1_REMAP[1:0]: */ /** SPI1 remapping */ +#define AFIO_MAPR_SPI1_REMAP (1 << 0) +/**@}*/ + /* CAN_REMAP[1:0]: CAN1 alternate function remapping */ +/** @defgroup afio_remap_can1 Alternate Function Remap Controls for CAN 1 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_CAN1_REMAP_PORTA (0x0 << 13) #define AFIO_MAPR_CAN1_REMAP_PORTB (0x2 << 13) /* Not on 36pin pkg */ #define AFIO_MAPR_CAN1_REMAP_PORTD (0x3 << 13) - -/* TIM4_REMAP: TIM4 remapping */ -#define AFIO_MAPR_TIM4_REMAP (1 << 12) +/**@}*/ /* TIM3_REMAP[1:0]: TIM3 remapping */ +/** @defgroup afio_remap_tim3 Alternate Function Remap Controls for Timer 3 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_TIM3_REMAP_NO_REMAP (0x0 << 10) #define AFIO_MAPR_TIM3_REMAP_PARTIAL_REMAP (0x2 << 10) #define AFIO_MAPR_TIM3_REMAP_FULL_REMAP (0x3 << 10) +/**@}*/ /* TIM2_REMAP[1:0]: TIM2 remapping */ +/** @defgroup afio_remap_tim2 Alternate Function Remap Controls for Timer 2 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_TIM2_REMAP_NO_REMAP (0x0 << 8) #define AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP1 (0x1 << 8) #define AFIO_MAPR_TIM2_REMAP_PARTIAL_REMAP2 (0x2 << 8) #define AFIO_MAPR_TIM2_REMAP_FULL_REMAP (0x3 << 8) +/**@}*/ /* TIM1_REMAP[1:0]: TIM1 remapping */ +/** @defgroup afio_remap_tim1 Alternate Function Remap Controls for Timer 1 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_TIM1_REMAP_NO_REMAP (0x0 << 6) #define AFIO_MAPR_TIM1_REMAP_PARTIAL_REMAP (0x1 << 6) #define AFIO_MAPR_TIM1_REMAP_FULL_REMAP (0x3 << 6) +/**@}*/ /* USART3_REMAP[1:0]: USART3 remapping */ +/** @defgroup afio_remap_usart3 Alternate Function Remap Controls for USART 3 +@ingroup STM32F1xx_gpio_defines + +@{*/ #define AFIO_MAPR_USART3_REMAP_NO_REMAP (0x0 << 4) #define AFIO_MAPR_USART3_REMAP_PARTIAL_REMAP (0x1 << 4) #define AFIO_MAPR_USART3_REMAP_FULL_REMAP (0x3 << 4) +/**@}*/ -/* USART2_REMAP[1:0]: USART2 remapping */ -#define AFIO_MAPR_USART2_REMAP (1 << 3) +/** @defgroup afio_remap2 Alternate Function Remap Controls Secondary Set +@ingroup STM32F1xx_gpio_defines -/* USART1_REMAP[1:0]: USART1 remapping */ -#define AFIO_MAPR_USART1_REMAP (1 << 2) +@{*/ +/* FSMC_NADV_DISCONNECT: */ /** The NADV is disconnected from its allocated pin */ +#define AFIO_MAPR2_FSMC_NADV_DISCONNECT (1 << 10) -/* I2C1_REMAP[1:0]: I2C1 remapping */ -#define AFIO_MAPR_I2C1_REMAP (1 << 1) +/* TIM14_REMAP: */ /** TIM14 remapping */ +#define AFIO_MAPR2_TIM14_REMAP (1 << 9) -/* SPI1_REMAP[1:0]: SPI1 remapping */ -#define AFIO_MAPR_SPI1_REMAP (1 << 0) +/* TIM13_REMAP: */ /** TIM13 remapping */ +#define AFIO_MAPR2_TIM13_REMAP (1 << 8) + +/* TIM11_REMAP: */ /** TIM11 remapping */ +#define AFIO_MAPR2_TIM11_REMAP (1 << 7) + +/* TIM10_REMAP: */ /** TIM10 remapping */ +#define AFIO_MAPR2_TIM10_REMAP (1 << 6) + +/* TIM9_REMAP: */ /** TIM9 remapping */ +#define AFIO_MAPR2_TIM9_REMAP (1 << 5) + +/**@}*/ /* --- AFIO_EXTICR1 values ------------------------------------------------- */ /* --- AFIO_EXTICR2 values ------------------------------------------------- */ /* --- AFIO_EXTICR3 values ------------------------------------------------- */ /* --- AFIO_EXTICR4 values ------------------------------------------------- */ -/* EXTI0 - EXTI15 interrupt source selection registers */ - -/* Note: For using them we should define a function that calculates the right - * registers, using definitions is probably not a good idea. - */ +/** @defgroup afio_exti Alternate Function EXTI pin number +@ingroup STM32F1xx_gpio_defines + +@{*/ + +#define AFIO_EXTI0 0 +#define AFIO_EXTI1 1 +#define AFIO_EXTI2 2 +#define AFIO_EXTI3 3 +#define AFIO_EXTI4 4 +#define AFIO_EXTI5 5 +#define AFIO_EXTI6 6 +#define AFIO_EXTI7 7 +#define AFIO_EXTI8 8 +#define AFIO_EXTI9 9 +#define AFIO_EXTI10 10 +#define AFIO_EXTI11 11 +#define AFIO_EXTI12 12 +#define AFIO_EXTI13 13 +#define AFIO_EXTI14 14 +#define AFIO_EXTI15 15 + +/**@}*/ /* --- Function prototypes ------------------------------------------------- */ @@ -803,5 +958,10 @@ void gpio_toggle(u32 gpioport, u16 gpios); u16 gpio_port_read(u32 gpioport); void gpio_port_write(u32 gpioport, u16 data); void gpio_port_config_lock(u32 gpioport, u16 gpios); +void gpio_set_eventout(u8 evoutport, u8 evoutpin); +void gpio_primary_remap(u8 swjenable, u32 maps); +void gpio_secondary_remap(u32 maps); #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index 0477e15..63f6770 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -1,26 +1,17 @@ -/** @file - -@ingroup STM32F1xx +/** @defgroup STM32F1xx_rcc_defines RCC Defines @brief libopencm3 STM32F1xx Reset and Clock Control +@ingroup STM32F1xx_defines + @version 1.0.0 @author @htmlonly © @endhtmlonly 2009 Federico Ruiz-Ugalde \ @author @htmlonly © @endhtmlonly 2009 Uwe Hermann -@date 18 May 2012 +@date 18 August 2012 LGPL License Terms @ref lgpl_license - */ -/** @defgroup STM32F1xx_rcc_defines - -@brief Defined Constants and Types for the STM32F1xx Reset and Clock Control - -@ingroup STM32F1xx_defines - -LGPL License Terms @ref lgpl_license - */ /* * This file is part of the libopencm3 project. @@ -41,6 +32,7 @@ LGPL License Terms @ref lgpl_license * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ +/**@{*/ #ifndef LIBOPENCM3_RCC_H #define LIBOPENCM3_RCC_H @@ -86,6 +78,10 @@ LGPL License Terms @ref lgpl_license /* --- RCC_CFGR values ----------------------------------------------------- */ /* MCO: Microcontroller clock output */ +/** @defgroup rcc_cfgr_co RCC_CFGR Microcontroller Clock Output Source +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_MCO_NOCLK 0x0 #define RCC_CFGR_MCO_SYSCLK 0x4 #define RCC_CFGR_MCO_HSICLK 0x5 @@ -95,16 +91,26 @@ LGPL License Terms @ref lgpl_license #define RCC_CFGR_MCO_PLL3CLK_DIV2 0x9 /* (**) */ #define RCC_CFGR_MCO_XT1 0xa /* (**) */ #define RCC_CFGR_MCO_PLL3 0xb /* (**) */ +/**@}*/ /* USBPRE: USB prescaler (RCC_CFGR[22]) */ +/** @defgroup rcc_cfgr_usbpre RCC_CFGR USB prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_USBPRE_PLL_CLK_DIV1_5 0x0 #define RCC_CFGR_USBPRE_PLL_CLK_NODIV 0x1 +/**@}*/ /* OTGFSPRE: USB OTG FS prescaler (RCC_CFGR[22]; only in conn. line STM32s) */ #define RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3 0x0 #define RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV2 0x1 /* PLLMUL: PLL multiplication factor */ +/** @defgroup rcc_cfgr_pmf RCC_CFGR PLL Multiplication Factor +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL2 0x0 /* (XX) */ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL3 0x1 /* (XX) */ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL4 0x2 @@ -122,38 +128,69 @@ LGPL License Terms @ref lgpl_license #define RCC_CFGR_PLLMUL_PLL_CLK_MUL6_5 0xd /* 0xd: PLL x 6.5 for conn. line */ #define RCC_CFGR_PLLMUL_PLL_CLK_MUL16 0xe /* (XX) */ // #define PLLMUL_PLL_CLK_MUL16 0xf /* (XX) */ /* Errata? 17? */ +/**@}*/ /* TODO: conn. line differs. */ /* PLLXTPRE: HSE divider for PLL entry */ +/** @defgroup rcc_cfgr_hsepre RCC_CFGR HSE Divider for PLL +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_PLLXTPRE_HSE_CLK 0x0 #define RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2 0x1 +/**@}*/ /* PLLSRC: PLL entry clock source */ +/** @defgroup rcc_cfgr_pcs RCC_CFGR PLL Clock Source +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_PLLSRC_HSI_CLK_DIV2 0x0 #define RCC_CFGR_PLLSRC_HSE_CLK 0x1 #define RCC_CFGR_PLLSRC_PREDIV1_CLK 0x1 /* On conn. line */ +/**@}*/ /* ADCPRE: ADC prescaler */ +/****************************************************************************/ +/** @defgroup rcc_cfgr_adcpre RCC ADC Clock Prescaler enable values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_ADCPRE_PCLK2_DIV2 0x0 #define RCC_CFGR_ADCPRE_PCLK2_DIV4 0x1 #define RCC_CFGR_ADCPRE_PCLK2_DIV6 0x2 #define RCC_CFGR_ADCPRE_PCLK2_DIV8 0x3 +/**@}*/ /* PPRE2: APB high-speed prescaler (APB2) */ +/** @defgroup rcc_cfgr_apb2pre RCC_CFGR APB2 Prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_PPRE2_HCLK_NODIV 0x0 #define RCC_CFGR_PPRE2_HCLK_DIV2 0x4 #define RCC_CFGR_PPRE2_HCLK_DIV4 0x5 #define RCC_CFGR_PPRE2_HCLK_DIV8 0x6 #define RCC_CFGR_PPRE2_HCLK_DIV16 0x7 +/**@}*/ /* PPRE1: APB low-speed prescaler (APB1) */ +/** @defgroup rcc_cfgr_apb1pre RCC_CFGR APB1 Prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_PPRE1_HCLK_NODIV 0x0 #define RCC_CFGR_PPRE1_HCLK_DIV2 0x4 #define RCC_CFGR_PPRE1_HCLK_DIV4 0x5 #define RCC_CFGR_PPRE1_HCLK_DIV8 0x6 #define RCC_CFGR_PPRE1_HCLK_DIV16 0x7 +/**@}*/ /* HPRE: AHB prescaler */ +/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB Prescale Factors +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_HPRE_SYSCLK_NODIV 0x0 #define RCC_CFGR_HPRE_SYSCLK_DIV2 0x8 #define RCC_CFGR_HPRE_SYSCLK_DIV4 0x9 @@ -163,6 +200,7 @@ LGPL License Terms @ref lgpl_license #define RCC_CFGR_HPRE_SYSCLK_DIV128 0xd #define RCC_CFGR_HPRE_SYSCLK_DIV256 0xe #define RCC_CFGR_HPRE_SYSCLK_DIV512 0xf +/**@}*/ /* SWS: System clock switch status */ #define RCC_CFGR_SWS_SYSCLKSEL_HSICLK 0x0 @@ -170,9 +208,14 @@ LGPL License Terms @ref lgpl_license #define RCC_CFGR_SWS_SYSCLKSEL_PLLCLK 0x2 /* SW: System clock switch */ +/** @defgroup rcc_cfgr_scs RCC_CFGR System Clock Selection +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_CFGR_SW_SYSCLKSEL_HSICLK 0x0 #define RCC_CFGR_SW_SYSCLKSEL_HSECLK 0x1 #define RCC_CFGR_SW_SYSCLKSEL_PLLCLK 0x2 +/**@}*/ /* --- RCC_CIR values ------------------------------------------------------ */ @@ -211,6 +254,10 @@ LGPL License Terms @ref lgpl_license /* --- RCC_APB2RSTR values ------------------------------------------------- */ +/** @defgroup rcc_apb2rstr_rst RCC_APB2RSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_APB2RSTR_ADC3RST (1 << 15) /* (XX) */ #define RCC_APB2RSTR_USART1RST (1 << 14) #define RCC_APB2RSTR_TIM8RST (1 << 13) /* (XX) */ @@ -226,9 +273,14 @@ LGPL License Terms @ref lgpl_license #define RCC_APB2RSTR_IOPBRST (1 << 3) #define RCC_APB2RSTR_IOPARST (1 << 2) #define RCC_APB2RSTR_AFIORST (1 << 0) +/**@}*/ /* --- RCC_APB1RSTR values ------------------------------------------------- */ +/** @defgroup rcc_apb1rstr_rst RCC_APB1RSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_APB1RSTR_DACRST (1 << 29) #define RCC_APB1RSTR_PWRRST (1 << 28) #define RCC_APB1RSTR_BKPRST (1 << 27) @@ -251,6 +303,7 @@ LGPL License Terms @ref lgpl_license #define RCC_APB1RSTR_TIM4RST (1 << 2) #define RCC_APB1RSTR_TIM3RST (1 << 1) #define RCC_APB1RSTR_TIM2RST (1 << 0) +/**@}*/ /* --- RCC_AHBENR values --------------------------------------------------- */ @@ -269,7 +322,7 @@ LGPL License Terms @ref lgpl_license #define RCC_AHBENR_SRAMEN (1 << 2) #define RCC_AHBENR_DMA2EN (1 << 1) #define RCC_AHBENR_DMA1EN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_APB2ENR values -------------------------------------------------- */ @@ -292,7 +345,7 @@ LGPL License Terms @ref lgpl_license #define RCC_APB2ENR_IOPBEN (1 << 3) #define RCC_APB2ENR_IOPAEN (1 << 2) #define RCC_APB2ENR_AFIOEN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_APB1ENR values -------------------------------------------------- */ @@ -322,7 +375,7 @@ LGPL License Terms @ref lgpl_license #define RCC_APB1ENR_TIM4EN (1 << 2) #define RCC_APB1ENR_TIM3EN (1 << 1) #define RCC_APB1ENR_TIM2EN (1 << 0) -/*@}*/ +/**@}*/ /* --- RCC_BDCR values ----------------------------------------------------- */ @@ -347,8 +400,13 @@ LGPL License Terms @ref lgpl_license /* --- RCC_AHBRSTR values -------------------------------------------------- */ +/** @defgroup rcc_ahbrstr_rst RCC_AHBRSTR reset values +@ingroup STM32F1xx_rcc_defines + +@{*/ #define RCC_AHBRSTR_ETHMACRST (1 << 14) #define RCC_AHBRSTR_OTGFSRST (1 << 12) +/**@}*/ /* --- RCC_CFGR2 values ---------------------------------------------------- */ @@ -447,10 +505,6 @@ void rcc_set_usbpre(u32 usbpre); u32 rcc_get_system_clock_source(int i); void rcc_clock_setup_in_hsi_out_64mhz(void); void rcc_clock_setup_in_hsi_out_48mhz(void); - -/** - * Maximum speed possible for F100 (Value Line) on HSI - */ void rcc_clock_setup_in_hsi_out_24mhz(void); void rcc_clock_setup_in_hse_8mhz_out_24mhz(void); void rcc_clock_setup_in_hse_8mhz_out_72mhz(void); @@ -459,3 +513,5 @@ void rcc_clock_setup_in_hse_16mhz_out_72mhz(void); void rcc_backupdomain_reset(void); #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/iwdg.h b/include/libopencm3/stm32/iwdg.h index 2a8ee9d..a5f1ac1 100644 --- a/include/libopencm3/stm32/iwdg.h +++ b/include/libopencm3/stm32/iwdg.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F_iwdg_defines IWDG Defines + +@brief libopencm3 Defined Constants and Types for the STM32F Independent Watchdog Timer + +@ingroup STM32F_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +31,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_IWDG_H #define LIBOPENCM3_IWDG_H @@ -42,9 +58,14 @@ /* Bits [31:16]: Reserved. */ /* KEY[15:0]: Key value (write-only, reads as 0x0000) */ +/** @defgroup iwdg_key IWDG Key Values +@ingroup STM32F_iwdg_defines + +@{*/ #define IWDG_KR_RESET 0xaaaa #define IWDG_KR_UNLOCK 0x5555 #define IWDG_KR_START 0xcccc +/**@}*/ /* --- IWDG_PR values ------------------------------------------------------ */ @@ -52,6 +73,10 @@ /* PR[2:0]: Prescaler divider */ #define IWDG_PR_LSB 0 +/** @defgroup iwdg_prediv IWDG Prescaler divider +@ingroup STM32F_iwdg_defines + +@{*/ #define IWDG_PR_DIV4 0x0 #define IWDG_PR_DIV8 0x1 #define IWDG_PR_DIV16 0x2 @@ -59,6 +84,7 @@ #define IWDG_PR_DIV64 0x4 #define IWDG_PR_DIV128 0x5 #define IWDG_PR_DIV256 0x6 +/**@}*/ /* Double definition: 0x06 and 0x07 both mean DIV256 as per datasheet. */ /* #define IWDG_PR_DIV256 0x7 */ @@ -87,3 +113,5 @@ bool iwdg_prescaler_busy(void); void iwdg_reset(void); #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/pwr.h b/include/libopencm3/stm32/pwr.h index 423ab1a..7084382 100644 --- a/include/libopencm3/stm32/pwr.h +++ b/include/libopencm3/stm32/pwr.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F1xx_pwr_defines PWR Defines + +@ingroup STM32F_defines + +@brief libopencm3 STM32F Power Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 17 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +31,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_PWR_H #define LIBOPENCM3_PWR_H @@ -40,14 +56,20 @@ /* PLS[7:5]: PVD level selection */ #define PWR_CR_PLS_LSB 5 -#define PWR_CR_PLS_2V2 0x0 -#define PWR_CR_PLS_2V3 0x1 -#define PWR_CR_PLS_2V4 0x2 -#define PWR_CR_PLS_2V5 0x3 -#define PWR_CR_PLS_2V6 0x4 -#define PWR_CR_PLS_2V7 0x5 -#define PWR_CR_PLS_2V8 0x6 -#define PWR_CR_PLS_2V9 0x7 +/** @defgroup pwr_pls PVD level selection +@ingroup STM32F_pwr_defines + +@{*/ +#define PWR_CR_PLS_2V2 (0x0 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V3 (0x1 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V4 (0x2 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V5 (0x3 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V6 (0x4 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V7 (0x5 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V8 (0x6 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V9 (0x7 << PWR_CR_PLS_LSB) +/**@}*/ +#define PWR_CR_PLS_MASK (0x7 << PWR_CR_PLS_LSB) /* PVDE: Power voltage detector enable */ #define PWR_CR_PVDE (1 << 4) @@ -84,6 +106,22 @@ /* --- PWR function prototypes ------------------------------------------- */ -/* TODO */ +void pwr_disable_backup_domain_write_protect(void); +void pwr_enable_backup_domain_write_protect(void); +void pwr_enable_power_voltage_detect(u32 pvd_level); +void pwr_disable_power_voltage_detect(void); +void pwr_clear_standby_flag(void); +void pwr_clear_wakeup_flag(void); +void pwr_set_standby_mode(void); +void pwr_set_stop_mode(void); +void pwr_voltage_regulator_on_in_stop(void); +void pwr_voltage_regulator_low_power_in_stop(void); +void pwr_enable_wakeup_pin(void); +void pwr_disable_wakeup_pin(void); +bool pwr_voltage_high(void); +bool pwr_get_standby_flag(void); +bool pwr_get_wakeup_flag(void); #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/systick.h b/include/libopencm3/stm32/systick.h index 376bea0..aa6c287 100644 --- a/include/libopencm3/stm32/systick.h +++ b/include/libopencm3/stm32/systick.h @@ -1,3 +1,18 @@ +/** @defgroup STM32F_systick_defines SysTick Defines + +@brief libopencm3 Defined Constants and Types for the STM32F SysTick + +@ingroup STM32F_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 19 August 2012 + +LGPL License Terms @ref lgpl_license + */ + /* * This file is part of the libopencm3 project. * @@ -17,6 +32,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_SYSTICK_H #define LIBOPENCM3_SYSTICK_H @@ -45,8 +62,14 @@ /* CLKSOURCE: Clock source selection */ #define STK_CTRL_CLKSOURCE (1 << 2) #define STK_CTRL_CLKSOURCE_LSB 2 +/** @defgroup systick_clksource Clock source selection +@ingroup STM32F_systick_defines + +@{*/ #define STK_CTRL_CLKSOURCE_AHB_DIV8 0 #define STK_CTRL_CLKSOURCE_AHB 1 +/**@}*/ + /* TICKINT: SysTick exception request enable */ #define STK_CTRL_TICKINT (1 << 1) /* ENABLE: Counter enable */ @@ -80,3 +103,5 @@ void systick_counter_disable(void); u8 systick_get_countflag(void); #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/timer.h b/include/libopencm3/stm32/timer.h index 3066fd3..b1e1064 100644 --- a/include/libopencm3/stm32/timer.h +++ b/include/libopencm3/stm32/timer.h @@ -1,8 +1,8 @@ -/** @file +/** @defgroup STM32F_tim_defines Timers Defines -@ingroup STM32F1xx +@brief libopencm3 Defined Constants and Types for the STM32F1xx Timers -@brief libopencm3 STM32F1xx Timers +@ingroup STM32F_defines @version 1.0.0 @@ -11,15 +11,6 @@ @date 18 May 2012 LGPL License Terms @ref lgpl_license - */ -/** @defgroup STM32F1xx_tim_defines - -@brief Defined Constants and Types for the STM32F1xx Timers - -@ingroup STM32F1xx_defines - -LGPL License Terms @ref lgpl_license - */ /* * This file is part of the libopencm3 project. @@ -40,6 +31,8 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_TIMER_H #define LIBOPENCM3_TIMER_H @@ -62,7 +55,7 @@ LGPL License Terms @ref lgpl_license #define TIM6 TIM6_BASE #define TIM7 TIM7_BASE #define TIM8 TIM8_BASE -/*@}*/ +/**@}*/ /* --- Timer registers ----------------------------------------------------- */ @@ -266,7 +259,7 @@ LGPL License Terms @ref lgpl_license #define TIM_CR1_CKD_CK_INT_MUL_2 (0x1 << 8) #define TIM_CR1_CKD_CK_INT_MUL_4 (0x2 << 8) #define TIM_CR1_CKD_CK_INT_MASK (0x3 << 8) -/*@}*/ +/**@}*/ /* ARPE: Auto-reload preload enable */ #define TIM_CR1_ARPE (1 << 7) @@ -282,7 +275,7 @@ LGPL License Terms @ref lgpl_license #define TIM_CR1_CMS_CENTER_2 (0x2 << 5) #define TIM_CR1_CMS_CENTER_3 (0x3 << 5) #define TIM_CR1_CMS_MASK (0x3 << 5) -/*@}*/ +/**@}*/ /* DIR: Direction */ /****************************************************************************/ @@ -292,7 +285,7 @@ LGPL License Terms @ref lgpl_license @{*/ #define TIM_CR1_DIR_UP (0 << 4) #define TIM_CR1_DIR_DOWN (1 << 4) -/*@}*/ +/**@}*/ /* OPM: One pulse mode */ #define TIM_CR1_OPM (1 << 3) @@ -334,7 +327,7 @@ LGPL License Terms @ref lgpl_license /* OIS1:*//** Output idle state 1 (OC1 output) */ #define TIM_CR2_OIS1 (1 << 8) #define TIM_CR2_OIS_MASK (0x7f << 8) -/*@}*/ +/**@}*/ /* TI1S: TI1 selection */ #define TIM_CR2_TI1S (1 << 7) @@ -354,7 +347,7 @@ LGPL License Terms @ref lgpl_license #define TIM_CR2_MMS_COMPARE_OC3REF (0x6 << 4) #define TIM_CR2_MMS_COMPARE_OC4REF (0x7 << 4) #define TIM_CR2_MMS_MASK (0x7 << 4) -/*@}*/ +/**@}*/ /* CCDS: Capture/compare DMA selection */ #define TIM_CR2_CCDS (1 << 3) @@ -424,7 +417,7 @@ LGPL License Terms @ref lgpl_license /** External Trigger input (ETRF) */ #define TIM_SMCR_TS_ETRF (0x7 << 4) #define TIM_SMCR_TS_MASK (0x7 << 4) -/*@}*/ +/**@}*/ /* SMS[2:0]: Slave mode selection */ /** @defgroup tim_sms SMS Slave mode selection @@ -452,7 +445,7 @@ and generates an update of the registers. */ /** External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. */ #define TIM_SMCR_SMS_ECM1 (0x7 << 0) #define TIM_SMCR_SMS_MASK (0x7 << 0) -/*@}*/ +/**@}*/ /* --- TIMx_DIER values ---------------------------------------------------- */ @@ -505,7 +498,7 @@ and generates an update of the registers. */ /* UIE:*//** Update interrupt enable */ #define TIM_DIER_UIE (1 << 0) -/*@}*/ +/**@}*/ /* --- TIMx_SR values ------------------------------------------------------ */ /****************************************************************************/ @@ -549,7 +542,7 @@ and generates an update of the registers. */ /* UIF:*//** Update interrupt flag */ #define TIM_SR_UIF (1 << 0) -/*@}*/ +/**@}*/ /* --- TIMx_EGR values ----------------------------------------------------- */ @@ -582,7 +575,7 @@ and generates an update of the registers. */ /* UG:*//** Update generation */ #define TIM_EGR_UG (1 << 0) -/*@}*/ +/**@}*/ /* --- TIMx_CCMR1 values --------------------------------------------------- */ @@ -923,7 +916,7 @@ and generates an update of the registers. */ #define TIM_BDTR_LOCK_LEVEL_2 (0x2 << 8) #define TIM_BDTR_LOCK_LEVEL_3 (0x3 << 8) #define TIM_BDTR_LOCK_MASK (0x3 << 8) -/*@}*/ +/**@}*/ /* DTG[7:0]: Dead-time generator set-up */ #define TIM_BDTR_DTG_MASK 0x00FF @@ -1107,6 +1100,7 @@ void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc); void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol); void timer_slave_set_mode(u32 timer, u8 mode); void timer_slave_set_trigger(u32 timer, u8 trigger); -void timer_force_event(u32 timer, u8 event); #endif +/**@}*/ + diff --git a/lib/stm32/dac.c b/lib/stm32/dac.c index deec130..7978059 100644 --- a/lib/stm32/dac.c +++ b/lib/stm32/dac.c @@ -1,6 +1,6 @@ -/** @file +/** @defgroup STM32F-dac-file DAC -@ingroup STM32F +@ingroup STM32F-files @brief libopencm3 STM32Fxx Digital to Analog Converter @@ -8,7 +8,7 @@ @author @htmlonly © @endhtmlonly 2012 Ken Sarkies -@date 30 June 2012 +@date 18 August 2012 This library supports the Digital to Analog Conversion System in the STM32F series of ARM Cortex Microcontrollers by ST Microelectronics. @@ -121,6 +121,8 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ +/**@{*/ + #include #define MASK8 0xFF @@ -133,7 +135,7 @@ 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] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_enable(data_channel dac_channel) @@ -156,7 +158,7 @@ void dac_enable(data_channel dac_channel) Disable a digital to analog converter channel. -@param[in] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_disable(data_channel dac_channel) @@ -182,7 +184,7 @@ 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] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_buffer_enable(data_channel dac_channel) @@ -206,7 +208,7 @@ Disable a digital to analog converter channel output drive buffer. Disabling thi reduce power consumption slightly and will increase the output impedance of the DAC. The buffers are enabled by default after a reset. -@param[in] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_buffer_disable(data_channel dac_channel) @@ -230,7 +232,7 @@ 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] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_dma_enable(data_channel dac_channel) @@ -253,7 +255,7 @@ void dac_dma_enable(data_channel dac_channel) Disable a digital to analog converter channel DMA mode. -@param[in] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_dma_disable(data_channel dac_channel) @@ -279,7 +281,7 @@ external trigger to initiate register transfers from the buffer register to the output register, followed by a DMA transfer to the buffer register if DMA is enabled. The trigger source must also be selected. -@param[in] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_trigger_enable(data_channel dac_channel) @@ -302,7 +304,7 @@ void dac_trigger_enable(data_channel dac_channel) Disable a digital to analog converter channel external trigger. -@param[in] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_trigger_disable(data_channel dac_channel) @@ -326,7 +328,7 @@ 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] u32 dac_trig_src. Taken from @ref dac_trig2_sel or @ref dac_trig1_sel or +@param[in] dac_trig_src u32. Taken from @ref dac_trig2_sel or @ref dac_trig1_sel or a logical OR of one of each of these to set both channels simultaneously. */ @@ -344,7 +346,7 @@ in the DAC output registers. @note The DAC trigger must be enabled for this to work. -@param[in] u32 dac_trig_src. Taken from @ref dac_wave1_en or @ref dac_wave2_en or +@param[in] dac_wave_ens u32. Taken from @ref dac_wave1_en or @ref dac_wave2_en or a logical OR of one of each of these to set both channels simultaneously. */ @@ -358,7 +360,7 @@ void dac_set_waveform_generation(u32 dac_wave_ens) Disable a digital to analog converter channel superimposed waveform generation. -@param[in] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_disable_waveform_generation(data_channel dac_channel) @@ -390,7 +392,7 @@ signal output. @note This must be called before enabling the DAC as the settings will then become read-only. @note The DAC trigger must be enabled for this to work. -@param[in] u32 dac_mamp. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a logical OR +@param[in] dac_mamp u32. Taken from @ref dac_mamp2 or @ref dac_mamp1 or a logical OR of one of each of these to set both channels simultaneously. */ @@ -414,9 +416,9 @@ formatted according to the datasheets: @li right-aligned 12 bit data in bits 0-11 for channel 1 and 16-27 for channel 2 @li left aligned 12 bit data in bits 4-15 for channel 1 and 20-31 for channel 2 -@param[in] u32 dac_data with appropriate alignment. -@param[in] enum ::data_align, dac_data_format. Alignment and size. -@param[in] enum ::data_channel, dac_channel. +@param[in] dac_data u32 with appropriate alignment. +@param[in] dac_data_format enum ::data_align. Alignment and size. +@param[in] dac_channel enum ::data_channel. */ void dac_load_data_buffer_single(u32 dac_data, data_align dac_data_format, data_channel dac_channel) @@ -471,9 +473,9 @@ 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] u32 dac_data for channel 1 with appropriate alignment. -@param[in] u32 dac_data for channel 2 with appropriate alignment. -@param[in] enum ::data_align, dac_data_format. Right or left aligned, and 8 or 12 bit. +@param[in] dac_data1 u32 for channel 1 with appropriate alignment. +@param[in] dac_data2 u32 for channel 2 with appropriate alignment. +@param[in] dac_data_format enum ::data_align. Right or left aligned, and 8 or 12 bit. */ void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data_format) @@ -497,7 +499,7 @@ void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data 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] enum ::data_channel, dac_channel. +@param[in] dac_channel enum ::data_channel. */ void dac_software_trigger(data_channel dac_channel) @@ -514,4 +516,5 @@ void dac_software_trigger(data_channel dac_channel) break; } } +/**@}*/ diff --git a/lib/stm32/f1/dma.c b/lib/stm32/f1/dma.c index 6bcb396..04cb8a1 100644 --- a/lib/stm32/f1/dma.c +++ b/lib/stm32/f1/dma.c @@ -1,3 +1,24 @@ +/** @defgroup STM32F1xx-dma-file DMA + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx DMA Controller + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 18 August 2012 + +This library supports the DMA +Control System in the STM32F1xx series of ARM Cortex Microcontrollers +by ST Microelectronics. It can provide for two DMA controllers, +one with 7 channels and one with 5. Channels are hardware dedicated +and each is shared with a number of different sources (only one can be +used at a time, under the responsibility of the programmer). + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,8 +38,19 @@ * along with this library. If not, see . */ +/**@{*/ + #include +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Reset + +The channel is disabled and configuration registers are cleared. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_channel_reset(u32 dma, u8 channel) { /* Disable channel. */ @@ -35,18 +67,51 @@ void dma_channel_reset(u32 dma, u8 channel) DMA_IFCR(dma) |= DMA_IFCR_CIF(channel); } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Memory to Memory Transfers + +Memory to memory transfers do not require a trigger to activate each transfer. +Transfers begin immediately the channel has been enabled, and proceed without +intervention. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_mem2mem_mode(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_MEM2MEM; DMA_CCR(dma, channel) &= ~DMA_CCR_CIRC; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set Priority + +Channel Priority has four levels: low to very high. This has precedence over the +hardware priority. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] prio unsigned int32. Priority level @ref dma_ch_pri. +*/ + void dma_set_priority(u32 dma, u8 channel, u32 prio) { DMA_CCR(dma, channel) &= ~(DMA_CCR_PL_MASK); DMA_CCR(dma, channel) |= prio; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set Memory Word Width + +Set the memory word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for +alignment information if the source and destination widths do not match. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] mem_size unsigned int32. Memory word width @ref dma_ch_memwidth. +*/ + void dma_set_memory_size(u32 dma, u8 channel, u32 mem_size) { @@ -54,89 +119,249 @@ void dma_set_memory_size(u32 dma, u8 channel, u32 mem_size) DMA_CCR(dma, channel) |= mem_size; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set Peripheral Word Width + +Set the peripheral word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for +alignment information if the source and destination widths do not match, or +if the peripheral does not support byte or half-word writes. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] peripheral_size unsigned int32. Peripheral word width @ref dma_ch_perwidth. +*/ + void dma_set_peripheral_size(u32 dma, u8 channel, u32 peripheral_size) { DMA_CCR(dma, channel) &= ~(DMA_CCR_PSIZE_MASK); DMA_CCR(dma, channel) |= peripheral_size; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Memory Increment after Transfer + +Following each transfer the current memory address is incremented by +1, 2 or 4 depending on the data size set in @ref dma_set_memory_size. The +value held by the base memory address register is unchanged. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_memory_increment_mode(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_MINC; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Memory Increment after Transfer + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_peripheral_increment_mode(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_PINC; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Memory Circular Mode + +After the number of bytes/words to be transferred has been completed, the +original transfer block size, memory and peripheral base addresses are +reloaded and the process repeats. + +@note This cannot be used with memory to memory mode, which is explictly +disabled here. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_circular_mode(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_CIRC; DMA_CCR(dma, channel) &= ~DMA_CCR_MEM2MEM; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Transfers from a Peripheral + +The data direction is set to read from a peripheral. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_set_read_from_peripheral(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_DIR; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Transfers from Memory + +The data direction is set to read from memory. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_set_read_from_memory(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_DIR; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_transfer_error_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_TEIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Error + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_disable_transfer_error_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_TEIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Half Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_half_transfer_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_HTIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Half Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_disable_half_transfer_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_HTIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable Interrupt on Transfer Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_transfer_complete_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_TCIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable Interrupt on Transfer Complete + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_disable_transfer_complete_interrupt(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_TCIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Enable + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_enable_channel(u32 dma, u8 channel) { DMA_CCR(dma, channel) |= DMA_CCR_EN; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Disable + +@note The DMA channel registers retain their values when the channel is disabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +*/ + void dma_disable_channel(u32 dma, u8 channel) { DMA_CCR(dma, channel) &= ~DMA_CCR_EN; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set the Peripheral Address + +Set the address of the peripheral register to or from which data is to be transferred. +Refer to the documentation for the specific peripheral. + +@note The DMA channel must be disabled before setting this address. This function +has no effect if the channel is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] address unsigned int32. Peripheral Address. +*/ + void dma_set_peripheral_address(u32 dma, u8 channel, u32 address) { - DMA_CPAR(dma, channel) = (u32) address; + if (!(DMA_CCR(dma, channel) & DMA_CCR_EN)) + DMA_CPAR(dma, channel) = (u32) address; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set the Base Memory Address + +@note The DMA channel must be disabled before setting this address. This function +has no effect if the channel is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] address unsigned int32. Memory Initial Address. +*/ + void dma_set_memory_address(u32 dma, u8 channel, u32 address) { - DMA_CMAR(dma, channel) = (u32) address; + if (!(DMA_CCR(dma, channel) & DMA_CCR_EN)) + DMA_CMAR(dma, channel) = (u32) address; } +/*-----------------------------------------------------------------------------*/ +/** @brief DMA Channel Set the Transfer Block Size + +@note The DMA channel must be disabled before setting this count value. The count +is not changed if the channel is enabled. + +@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2 +@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2 +@param[in] number unsigned int16. Number of data words to transfer (65535 maximum). +*/ + void dma_set_number_of_data(u32 dma, u8 channel, u16 number) { DMA_CNDTR(dma, channel) = number; } +/**@}*/ + diff --git a/lib/stm32/f1/gpio.c b/lib/stm32/f1/gpio.c index 9ef6037..0602012 100644 --- a/lib/stm32/f1/gpio.c +++ b/lib/stm32/f1/gpio.c @@ -1,3 +1,61 @@ +/** @defgroup STM32F1xx_gpio_file GPIO + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx General Purpose I/O + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Uwe Hermann +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +This library supports the General Purpose I/O System in the STM32F1xx series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Each I/O port has 16 individually configurable bits. Many I/O pins share GPIO +functionality with a number of alternate functions and must be configured to the +alternate function mode if these are to be accessed. A feature is available to +remap alternative functions to a limited set of alternative pins in the event +of a clash of requirements. + +The data registers associated with each port for input and output are 32 bit with +the upper 16 bits unused. The output buffer must be written as a 32 bit word, but +individual bits may be set or reset separately in atomic operations to avoid race +conditions during interrupts. Bits may also be individually locked to prevent +accidental configuration changes. Once locked the configuration cannot be changed +until after the next reset. + +Each port bit can be configured as analog or digital input, the latter can be +floating or pulled up or down. As outputs they can be configured as either +push-pull or open drain, digital I/O or alternate function, and with maximum +output speeds of 2MHz, 10MHz, or 50MHz. + +On reset all ports are configured as digital floating input. + +@section gpio_api_ex Basic GPIO Handling API. + +Example 1: Push-pull digital output actions on ports C2 and C9 + +@code + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO2 | GPIO9); + gpio_set(GPIOC, GPIO2 | GPIO9); + gpio_clear(GPIOC, GPIO2); + gpio_toggle(GPIOC, GPIO2 | GPIO9); + gpio_port_write(GPIOC, 0x204); +@endcode + +Example 1: Digital input on port C12 + +@code + gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT, GPIO12); + reg16 = gpio_port_read(GPIOC); +@endcode + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -33,9 +91,23 @@ * TODO: * - GPIO remapping support */ +/**@{*/ #include +/*-----------------------------------------------------------------------------*/ +/** @brief Set GPIO Pin Mode + +Sets the mode (input/output) and configuration (analog/digitial and +open drain/push pull), for a set of GPIO pins on a given GPIO port. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] mode Unsigned int8. Pin mode @ref gpio_mode +@param[in] cnf Unsigned int8. Pin configuration @ref gpio_cnf +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be set, use logical OR '|' to separate them. +*/ + void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios) { u16 i, offset = 0; @@ -73,69 +145,99 @@ void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios) GPIO_CRH(gpioport) = crh; } -/** - * Set one or more pins of the given GPIO port to 1. - * - * @param gpioport The GPIO port to use (GPIOA - GPIOG). - * @param gpios The GPIO pin(s) to set to 1 (GPIO0 - GPIO15, or GPIO_ALL). - * If multiple pins shall be set, use '|' to separate them. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Set a Group of Pins Atomic + +Set one or more pins of the given GPIO port to 1 in an atomic operation. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use logical OR '|' to separate them. +*/ void gpio_set(u32 gpioport, u16 gpios) { GPIO_BSRR(gpioport) = gpios; } -/** - * Clear one or more pins of the given GPIO port to 0. - * - * @param gpioport The GPIO port to use (GPIOA - GPIOG). - * @param gpios The GPIO pin(s) to set to 0 (GPIO0 - GPIO15, or GPIO_ALL). - * If multiple pins shall be cleared, use '|' to separate them. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Clear a Group of Pins Atomic + +Clear one or more pins of the given GPIO port to 0 in an atomic operation. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use logical OR '|' to separate them. +*/ void gpio_clear(u32 gpioport, u16 gpios) { GPIO_BRR(gpioport) = gpios; } +/*-----------------------------------------------------------------------------*/ +/** @brief Read a Group of Pins. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be read, use logical OR '|' to separate them. +@return Unsigned int16 value of the pin values. The bit position of the pin value + returned corresponds to the pin number. +*/ u16 gpio_get(u32 gpioport, u16 gpios) { return gpio_port_read(gpioport) & gpios; } -/** - * Toggle one or more pins of the given GPIO port. - * - * @param gpioport The GPIO port to use (GPIOA - GPIOG). - * @param gpios The GPIO pin(s) to toggle (GPIO0 - GPIO15, or GPIO_ALL). - * If multiple pins shall be toggled, use '|' to separate them. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Toggle a Group of Pins + +Toggle one or more pins of the given GPIO port. This is not an atomic operation. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be changed, use logical OR '|' to separate them. +*/ void gpio_toggle(u32 gpioport, u16 gpios) { GPIO_ODR(gpioport) ^= gpios; } -/** - * Read the current value of the given GPIO port. - * - * @param gpioport The GPIO port to read (GPIOA - GPIOG). - * @return The value of the current GPIO port. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Read from a Port + +Read the current value of the given GPIO port. Only the lower 16 bits contain +valid pin data. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@return Unsigned int16. The value held in the specified GPIO port. +*/ u16 gpio_port_read(u32 gpioport) { return (u16)GPIO_IDR(gpioport); } -/** - * Write to the given GPIO port. - * - * @param gpioport The GPIO port to write to (GPIOA - GPIOG). - * @param data The data to write to the specified GPIO port. - */ +/*-----------------------------------------------------------------------------*/ +/** @brief Write to a Port + +Write a value to the given GPIO port. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] data Unsigned int16. The value to be written to the GPIO port. +*/ void gpio_port_write(u32 gpioport, u16 data) { GPIO_ODR(gpioport) = data; } +/*-----------------------------------------------------------------------------*/ +/** @brief Lock the Configuration of a Group of Pins + +The configuration of one or more pins of the given GPIO port is locked. There is +no mechanism to unlock these via software. Unlocking occurs at the next reset. + +@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id +@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id + If multiple pins are to be locked, use logical OR '|' to separate them. +*/ void gpio_port_config_lock(u32 gpioport, u16 gpios) { u32 reg32; @@ -152,3 +254,64 @@ void gpio_port_config_lock(u32 gpioport, u16 gpios) /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */ } + +/*-----------------------------------------------------------------------------*/ +/** @brief Map the EVENTOUT signal + +Enable the EVENTOUT signal and select the port and pin to be used. + +@param[in] evoutport Unsigned int8. Port for EVENTOUT signal @ref afio_evcr_port +@param[in] evoutpin Unsigned int8. Pin for EVENTOUT signal @ref afio_evcr_pin +*/ +void gpio_set_eventout(u8 evoutport, u8 evoutpin) +{ + AFIO_EVCR = AFIO_EVCR_EVOE | evoutport | evoutpin; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Map Alternate Function Port Bits (Main Set) + +A number of alternate function ports can be remapped to defined alternative +port bits to avoid clashes in cases where multiple alternate functions are present. +Refer to the datasheets for the particular mapping desired. This provides the main +set of remap functionality. See @ref gpio_secondary_remap for a number of lesser used +remaps. + +The AFIO remapping feature is used only with the STM32F10x series. + +@note The Serial Wire JTAG disable controls allow certain GPIO ports to become available +in place of some of the SWJ signals. Full SWJ capability is obtained by setting this to +zero. The value of this must be specified for every call to this function as its current +value cannot be ascertained from the hardware. + +@param[in] swjdisable Unsigned int8. Disable parts of the SWJ capability @ref afio_swj_disable. +@param[in] maps Unsigned int32. Logical OR of map enable controls from @ref afio_remap, + @ref afio_remap_can1, @ref afio_remap_tim3, @ref afio_remap_tim2, @ref afio_remap_tim1, + @ref afio_remap_usart3. For connectivity line devices only @ref afio_remap_cld are + also available. +*/ +void gpio_primary_remap(u8 swjdisable, u32 maps) +{ + AFIO_MAPR = swjdisable | (maps & 0x1FFFFF); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief Map Alternate Function Port Bits (Secondary Set) + +A number of alternate function ports can be remapped to defined alternative +port bits to avoid clashes in cases where multiple alternate functions are present. +Refer to the datasheets for the particular mapping desired. This provides the second +smaller and less used set of remap functionality. See @ref gpio_primary_remap for +the main set of remaps. + +The AFIO remapping feature is used only with the STM32F10x series. + +@param[in] maps Unsigned int32. Logical OR of map enable controls from @ref afio_remap2 +*/ +void gpio_secondary_remap(u32 maps) +{ + AFIO_MAPR2 = maps; +} + +/**@}*/ + diff --git a/lib/stm32/f1/pwr.c b/lib/stm32/f1/pwr.c new file mode 100644 index 0000000..83c3dba --- /dev/null +++ b/lib/stm32/f1/pwr.c @@ -0,0 +1,217 @@ +/** @defgroup STM32F1xx-pwr-file PWR + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Power Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +This library supports the power control system for the +STM32F1 series of ARM Cortex Microcontrollers by ST Microelectronics. + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Backup Domain Write Protection. + +This allows backup domain registers to be changed. These registers are write +protected after a reset. +*/ + +void pwr_disable_backup_domain_write_protect(void) +{ + PWR_CR |= PWR_CR_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Re-enable Backup Domain Write Protection. + +This protects backup domain registers from inadvertent change. +*/ + +void pwr_enable_backup_domain_write_protect(void) +{ + PWR_CR &= ~PWR_CR_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Power Voltage Detector. + +This provides voltage level threshold detection. The result of detection is +provided in the power voltage detector output flag (see @ref pwr_voltage_high) +or by setting the EXTI16 interrupt (see datasheet for configuration details). + +@param[in] pvd_level u32. Taken from @ref pwr_pls. +*/ + +void pwr_enable_power_voltage_detect(u32 pvd_level) +{ + PWR_CR &= ~PWR_CR_PLS_MASK; + PWR_CR |= (PWR_CR_PVDE | pvd_level); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Power Voltage Detector. + +*/ + +void pwr_disable_power_voltage_detect(void) +{ + PWR_CR &= ~PWR_CR_PVDE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Standby Flag. + +This is set when the processor returns from a standby mode. +*/ + +void pwr_clear_standby_flag(void) +{ + PWR_CR |= PWR_CR_CSBF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Wakeup Flag. + +This is set when the processor receives a wakeup signal. +*/ + +void pwr_clear_wakeup_flag(void) +{ + PWR_CR |= PWR_CR_CWUF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Standby Mode in Deep Sleep. + +*/ + +void pwr_set_standby_mode(void) +{ + PWR_CR |= PWR_CR_PDDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Stop Mode in Deep Sleep. + +*/ + +void pwr_set_stop_mode(void) +{ + PWR_CR &= ~PWR_CR_PDDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Voltage Regulator On in Stop Mode. + +*/ + +void pwr_voltage_regulator_on_in_stop(void) +{ + PWR_CR &= ~PWR_CR_LPDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Voltage Regulator Low Power in Stop Mode. + +*/ + +void pwr_voltage_regulator_low_power_in_stop(void) +{ + PWR_CR |= PWR_CR_LPDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Wakeup Pin. + +The wakeup pin is used for waking the processor from standby mode. +*/ + +void pwr_enable_wakeup_pin(void) +{ + PWR_CSR |= PWR_CR_EWUP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Release Wakeup Pin. + +The wakeup pin is used for general purpose I/O. +*/ + +void pwr_disable_wakeup_pin(void) +{ + PWR_CSR &= ~PWR_CR_EWUP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Voltage Detector Output. + +The voltage detector threshold must be set when the power voltage detector is +enabled, see @ref pwr_enable_power_voltage_detect. + +@returns boolean: TRUE if the power voltage is above the preset voltage +threshold. +*/ + +bool pwr_voltage_high(void) +{ + return (PWR_CSR & PWR_CR_PVDO); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Standby Flag. + +The standby flag is set when the processor returns from a standby state. It is +cleared by software (see @ref pwr_clear_standby_flag). + +@returns boolean: TRUE if the processor was in standby state. +*/ + +bool pwr_get_standby_flag(void) +{ + return (PWR_CSR & PWR_CR_SBF); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Wakeup Flag. + +The wakeup flag is set when a wakeup event has been received. It is +cleared by software (see @ref pwr_clear_wakeup_flag). + +@returns boolean: TRUE if a wakeup event was received. +*/ + +bool pwr_get_wakeup_flag(void) +{ + return (PWR_CSR & PWR_CR_WUF); +} +/**@}*/ + diff --git a/lib/stm32/f1/rcc.c b/lib/stm32/f1/rcc.c index c03153a..5fd9c62 100644 --- a/lib/stm32/f1/rcc.c +++ b/lib/stm32/f1/rcc.c @@ -1,4 +1,4 @@ -/** @file +/** @defgroup STM32F1xx-rcc-file RCC @ingroup STM32F1xx @@ -10,25 +10,26 @@ @author @htmlonly © @endhtmlonly 2009 Uwe Hermann @author @htmlonly © @endhtmlonly 2010 Thomas Otto -@date 18 May 2012 +@date 18 August 2012 -This library supports the Reset and Clock -Control System in the STM32F1xx series of ARM Cortex Microcontrollers -by ST Microelectronics. +This library supports the Reset and Clock Control System in the STM32F1xx +series of ARM Cortex Microcontrollers by ST Microelectronics. + +@note Full support for connection line devices is not yet provided. Clock settings and resets for many peripherals are given here rather than in the -peripheral library. +corresponding peripheral library. The library also provides a number of common configurations for the processor -system clock. Not all possible configurations are given here. - -@bugs None known +system clock. Not all possible configurations are included. 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 * * This library is free software: you can redistribute it and/or modify @@ -45,6 +46,7 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ +/**@{*/ #include #include @@ -54,12 +56,12 @@ u32 rcc_ppre1_frequency = 8000000; /** Default ppre2 peripheral clock frequency after reset. */ u32 rcc_ppre2_frequency = 8000000; -//----------------------------------------------------------------------------- -/** @brief RCC Clear the Oscillator Ready Interrupt +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Clear the Oscillator Ready Interrupt Flag Clear the interrupt flag that was set when a clock oscillator became ready to use. -@param[in] enum ::osc_t. Oscillator ID +@param[in] osc enum ::osc_t. Oscillator ID */ void rcc_osc_ready_int_clear(osc_t osc) @@ -83,6 +85,12 @@ void rcc_osc_ready_int_clear(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Enable the Oscillator Ready Interrupt + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_ready_int_enable(osc_t osc) { switch (osc) { @@ -104,6 +112,12 @@ void rcc_osc_ready_int_enable(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Disable the Oscillator Ready Interrupt + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_ready_int_disable(osc_t osc) { switch (osc) { @@ -125,6 +139,13 @@ void rcc_osc_ready_int_disable(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Read the Oscillator Ready Interrupt Flag + +@param[in] osc enum ::osc_t. Oscillator ID +@returns int. Boolean value for flag set. +*/ + int rcc_osc_ready_int_flag(osc_t osc) { switch (osc) { @@ -149,16 +170,33 @@ int rcc_osc_ready_int_flag(osc_t osc) return -1; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Clear the Clock Security System Interrupt Flag + +*/ + void rcc_css_int_clear(void) { RCC_CIR |= RCC_CIR_CSSC; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Read the Clock Security System Interrupt Flag + +@returns int. Boolean value for flag set. +*/ + int rcc_css_int_flag(void) { return ((RCC_CIR & RCC_CIR_CSSF) != 0); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Wait for Oscillator Ready. + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_wait_for_osc_ready(osc_t osc) { switch (osc) { @@ -180,6 +218,20 @@ void rcc_wait_for_osc_ready(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Turn on an Oscillator. + +Enable an oscillator and power on. Each oscillator requires an amount of time to +settle to a usable state. Refer to datasheets for time delay information. A status +flag is available to indicate when the oscillator becomes ready (see +@ref rcc_osc_ready_int_flag and @ref rcc_wait_for_osc_ready). + +@note The LSE clock is in the backup domain and cannot be enabled until the +backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect). + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_on(osc_t osc) { switch (osc) { @@ -201,6 +253,20 @@ void rcc_osc_on(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Turn off an Oscillator. + +Disable an oscillator and power off. + +@note An oscillator cannot be turned off if it is selected as the system clock. +@note The LSE clock is in the backup domain and cannot be disabled until the +backup domain write protection has been removed (see +@ref pwr_disable_backup_domain_write_protect) or the backup domain has been +(see reset @ref rcc_backupdomain_reset). + +@param[in] osc enum ::osc_t. Oscillator ID +*/ + void rcc_osc_off(osc_t osc) { switch (osc) { @@ -222,16 +288,39 @@ void rcc_osc_off(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Enable the Clock Security System. + +*/ + void rcc_css_enable(void) { RCC_CR |= RCC_CR_CSSON; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Disable the Clock Security System. + +*/ + void rcc_css_disable(void) { RCC_CR &= ~RCC_CR_CSSON; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Enable Bypass. + +Enable an external clock to bypass the internal clock (high speed and low speed +clocks only). The external clock must be enabled (see @ref rcc_osc_on) +and the internal clock must be disabled (see @ref rcc_osc_off) for this to have effect. + +@note The LSE clock is in the backup domain and cannot be bypassed until the +backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect). + +@param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect. +*/ + void rcc_osc_bypass_enable(osc_t osc) { switch (osc) { @@ -249,6 +338,19 @@ void rcc_osc_bypass_enable(osc_t osc) } } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Disable Bypass. + +Re-enable the internal clock (high speed and low speed clocks only). The internal +clock must be disabled (see @ref rcc_osc_off) for this to have effect. + +@note The LSE clock is in the backup domain and cannot have bypass removed until the +backup domain write protection has been removed (see @ref pwr_disable_backup_domain_write_protect) +or the backup domain has been reset (see @ref rcc_backupdomain_reset). + +@param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect. +*/ + void rcc_osc_bypass_disable(osc_t osc) { switch (osc) { @@ -266,18 +368,20 @@ void rcc_osc_bypass_disable(osc_t osc) } } -//----------------------------------------------------------------------------- -/** @brief RCC Enable a peripheral clock. +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Enable Peripheral Clocks. -Enable the clock on a particular peripheral. Several peripherals could be -enabled simultaneously if they are controlled by the same register. +Enable the clock on particular peripherals. There are three registers +involved, each one controlling the enabling of clocks associated with the AHB, +APB1 and APB2 respectively. Several peripherals could be +enabled simultaneously only if they are controlled by the same register. -@param[in] Unsigned int32 *reg. Pointer to a Clock Enable Register - (either RCC_AHBENR, RCC_APB1RENR or RCC_APB2RENR) -@param[in] Unsigned int32 en. OR of all enables to be set +@param[in] *reg Unsigned int32. Pointer to a Clock Enable Register + (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) +@param[in] en Unsigned int32. Logical OR of all enables to be set @li If register is RCC_AHBER, from @ref rcc_ahbenr_en -@li If register is RCC_APB1RENR, from @ref rcc_apb1enr_en -@li If register is RCC_APB2RENR, from @ref rcc_apb2enr_en +@li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en +@li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en */ void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en) @@ -285,21 +389,75 @@ void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en) *reg |= en; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Disable Peripheral Clocks. + +Enable the clock on particular peripherals. There are three registers +involved, each one controlling the enabling of clocks associated with the AHB, +APB1 and APB2 respectively. Several peripherals could be +disabled simultaneously only if they are controlled by the same register. + +@param[in] *reg Unsigned int32. Pointer to a Clock Enable Register + (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) +@param[in] en Unsigned int32. Logical OR of all enables to be used for disabling. +@li If register is RCC_AHBER, from @ref rcc_ahbenr_en +@li If register is RCC_APB1ENR, from @ref rcc_apb1enr_en +@li If register is RCC_APB2ENR, from @ref rcc_apb2enr_en +*/ + void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en) { *reg &= ~en; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Reset Peripherals. + +Reset particular peripherals. There are three registers +involved, each one controlling reset of peripherals associated with the AHB, +APB1 and APB2 respectively. Several peripherals could be reset simultaneously +only if they are controlled by the same register. + +@param[in] *reg Unsigned int32. Pointer to a Reset Register + (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) +@param[in] reset Unsigned int32. Logical OR of all resets. +@li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst +@li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst +@li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst +*/ + void rcc_peripheral_reset(volatile u32 *reg, u32 reset) { *reg |= reset; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Remove Reset on Peripherals. + +Remove the reset on particular peripherals. There are three registers +involved, each one controlling reset of peripherals associated with the AHB, +APB1 and APB2 respectively. Several peripherals could have the reset removed +simultaneously only if they are controlled by the same register. + +@param[in] *reg Unsigned int32. Pointer to a Reset Register + (either RCC_AHBENR, RCC_APB1ENR or RCC_APB2ENR) +@param[in] clear_reset Unsigned int32. Logical OR of all resets to be removed: +@li If register is RCC_AHBRSTR, from @ref rcc_ahbrstr_rst +@li If register is RCC_APB1RSTR, from @ref rcc_apb1rstr_rst +@li If register is RCC_APB2RSTR, from @ref rcc_apb2rstr_rst +*/ + void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset) { *reg &= ~clear_reset; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the System Clock. + +@param[in] clk Unsigned int32. System Clock Selection @ref rcc_cfgr_scs +*/ + void rcc_set_sysclk_source(u32 clk) { u32 reg32; @@ -309,6 +467,14 @@ void rcc_set_sysclk_source(u32 clk) RCC_CFGR = (reg32 | clk); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Multiplication Factor. + +@note This only has effect when the PLL is disabled. + +@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf +*/ + void rcc_set_pll_multiplication_factor(u32 mul) { u32 reg32; @@ -318,6 +484,14 @@ void rcc_set_pll_multiplication_factor(u32 mul) RCC_CFGR = (reg32 | (mul << 18)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Clock Source. + +@note This only has effect when the PLL is disabled. + +@param[in] pllsrc Unsigned int32. PLL clock source @ref rcc_cfgr_pcs +*/ + void rcc_set_pll_source(u32 pllsrc) { u32 reg32; @@ -327,6 +501,14 @@ void rcc_set_pll_source(u32 pllsrc) RCC_CFGR = (reg32 | (pllsrc << 16)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the HSE Frequency Divider used as PLL Clock Source. + +@note This only has effect when the PLL is disabled. + +@param[in] pllxtpre Unsigned int32. HSE division factor @ref rcc_cfgr_hsepre +*/ + void rcc_set_pllxtpre(u32 pllxtpre) { u32 reg32; @@ -336,6 +518,14 @@ void rcc_set_pllxtpre(u32 pllxtpre) RCC_CFGR = (reg32 | (pllxtpre << 17)); } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Setup the A/D Clock + +The ADC's have a common clock prescale setting. + +@param[in] adcpre u32. Prescale divider taken from @ref rcc_cfgr_adcpre +*/ + void rcc_set_adcpre(u32 adcpre) { u32 reg32; @@ -345,6 +535,12 @@ void rcc_set_adcpre(u32 adcpre) RCC_CFGR = (reg32 | (adcpre << 14)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the APB2 Prescale Factor. + +@param[in] ppre2 Unsigned int32. APB2 prescale factor @ref rcc_cfgr_apb2pre +*/ + void rcc_set_ppre2(u32 ppre2) { u32 reg32; @@ -354,6 +550,14 @@ void rcc_set_ppre2(u32 ppre2) RCC_CFGR = (reg32 | (ppre2 << 11)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the APB1 Prescale Factor. + +@note The APB1 clock frequency must not exceed 36MHz. + +@param[in] ppre1 Unsigned int32. APB1 prescale factor @ref rcc_cfgr_apb1pre +*/ + void rcc_set_ppre1(u32 ppre1) { u32 reg32; @@ -363,6 +567,12 @@ void rcc_set_ppre1(u32 ppre1) RCC_CFGR = (reg32 | (ppre1 << 8)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the AHB Prescale Factor. + +@param[in] hpre Unsigned int32. AHB prescale factor @ref rcc_cfgr_ahbpre +*/ + void rcc_set_hpre(u32 hpre) { u32 reg32; @@ -372,6 +582,17 @@ void rcc_set_hpre(u32 hpre) RCC_CFGR = (reg32 | (hpre << 4)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set the USB Prescale Factor. + +The prescale factor can be set to 1 (no prescale) for use when the PLL clock is +48MHz, or 1.5 to generate the 48MHz USB clock from a 64MHz PLL clock. + +@note This bit cannot be reset while the USB clock is enabled. + +@param[in] usbpre Unsigned int32. USB prescale factor @ref rcc_cfgr_usbpre +*/ + void rcc_set_usbpre(u32 usbpre) { u32 reg32; @@ -381,16 +602,31 @@ void rcc_set_usbpre(u32 usbpre) RCC_CFGR = (reg32 | (usbpre << 22)); } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Get the System Clock Source. + +@returns Unsigned int32. System clock source: +@li 00 indicates HSE +@li 01 indicates LSE +@li 02 indicates PLL +*/ + u32 rcc_system_clock_source(void) { /* Return the clock source which is used as system clock. */ return ((RCC_CFGR & 0x000c) >> 2); } +/*-----------------------------------------------------------------------------*/ /* * These functions are setting up the whole clock system for the most common * input clock and output clock configurations. */ +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 64MHz from HSI + +*/ + void rcc_clock_setup_in_hsi_out_64mhz(void) { /* Enable internal high-speed oscillator. */ @@ -438,6 +674,11 @@ void rcc_clock_setup_in_hsi_out_64mhz(void) rcc_ppre2_frequency = 64000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 48MHz from HSI + +*/ + void rcc_clock_setup_in_hsi_out_48mhz(void) { /* Enable internal high-speed oscillator. */ @@ -486,6 +727,11 @@ void rcc_clock_setup_in_hsi_out_48mhz(void) rcc_ppre2_frequency = 48000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSI + +*/ + void rcc_clock_setup_in_hsi_out_24mhz(void) { /* Enable internal high-speed oscillator. */ rcc_osc_on(HSI); @@ -532,6 +778,10 @@ void rcc_clock_setup_in_hsi_out_24mhz(void) { rcc_ppre2_frequency = 24000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSE at 8MHz + +*/ void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) { @@ -591,6 +841,11 @@ void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) rcc_ppre2_frequency = 24000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 72MHz from HSE at 8MHz + +*/ + void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) { /* Enable internal high-speed oscillator. */ @@ -649,6 +904,11 @@ void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) rcc_ppre2_frequency = 72000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSE at 12MHz + +*/ + void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) { /* Enable internal high-speed oscillator. */ @@ -707,6 +967,11 @@ void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) rcc_ppre2_frequency = 72000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Set System Clock PLL at 24MHz from HSE at 16MHz + +*/ + void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) { /* Enable internal high-speed oscillator. */ @@ -765,6 +1030,12 @@ void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) rcc_ppre2_frequency = 72000000; } +/*-----------------------------------------------------------------------------*/ +/** @brief RCC Reset the backup domain + +The backup domain register is reset to disable all controls. +*/ + void rcc_backupdomain_reset(void) { /* Set the backup domain software reset. */ @@ -773,3 +1044,5 @@ void rcc_backupdomain_reset(void) /* Clear the backup domain software reset. */ RCC_BDCR &= ~RCC_BDCR_BDRST; } +/**@}*/ + diff --git a/lib/stm32/f1/timer.c b/lib/stm32/f1/timer.c index 11cb954..c5ea921 100644 --- a/lib/stm32/f1/timer.c +++ b/lib/stm32/f1/timer.c @@ -1,4 +1,4 @@ -/** @file +/** @defgroup STM32F1xx-timer-file Timers @ingroup STM32F1xx @@ -8,7 +8,7 @@ @author @htmlonly © @endhtmlonly 2010 Edward Cheeseman -@date 8 July 2012 +@date 18 August 2012 This library supports the General Purpose and Advanced Control Timers for the STM32F1xx series of ARM Cortex Microcontrollers by ST Microelectronics. @@ -93,6 +93,8 @@ push-pull outputs where the PWM output will appear. * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP); */ +/**@{*/ + #include #include @@ -561,8 +563,8 @@ void timer_set_dma_on_update_event(u32 timer_peripheral) /** @brief Enable Timer Capture/Compare Control Update with Trigger. If the capture/compare control bits CCxE, CCxNE and OCxM are set to be -preloaded, they are updated by software setting the COM bit (@ref ) or when a -rising edge occurs on the trigger input TRGI. +preloaded, they are updated by software generating the COMG event (@ref +timer_generate_event) or when a rising edge occurs on the trigger input TRGI. @note This setting is only valid for the advanced timer channels with complementary outputs. @@ -580,7 +582,8 @@ void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral) /** @brief Disable Timer Capture/Compare Control Update with Trigger. If the capture/compare control bits CCxE, CCxNE and OCxM are set to be -preloaded, they are updated by software setting the COM bit (@ref ). +preloaded, they are updated by software generating the COMG event (@ref +timer_generate_event). @note This setting is only valid for the advanced timer channels with complementary outputs. @@ -1391,7 +1394,7 @@ the Break and Deadtime Register. @note This setting is only valid for the advanced timers. @note It is necessary to call this function to enable the output on an advanced -timer even if break or deadtime features are not being used<\b>. +timer even if break or deadtime features are not being used. @param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8 */ @@ -1681,24 +1684,24 @@ Set the input filter parameters for an input channel, specifying: @param[in] flt ::tim_ic_filter. Input Capture Filter identifier. */ -void timer_ic_set_filter(u32 timer, enum tim_ic_id ic, enum tim_ic_filter flt) +void timer_ic_set_filter(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_filter flt) { switch (ic) { case TIM_IC1: - TIM_CCMR1(timer) &= ~TIM_CCMR1_IC1F_MASK; - TIM_CCMR1(timer) |= flt << 4; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1F_MASK; + TIM_CCMR1(timer_peripheral) |= flt << 4; break; case TIM_IC2: - TIM_CCMR1(timer) &= ~TIM_CCMR1_IC2F_MASK; - TIM_CCMR1(timer) |= flt << 12; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2F_MASK; + TIM_CCMR1(timer_peripheral) |= flt << 12; break; case TIM_IC3: - TIM_CCMR2(timer) &= ~TIM_CCMR2_IC3F_MASK; - TIM_CCMR2(timer) |= flt << 4; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3F_MASK; + TIM_CCMR2(timer_peripheral) |= flt << 4; break; case TIM_IC4: - TIM_CCMR2(timer) &= ~TIM_CCMR2_IC4F_MASK; - TIM_CCMR2(timer) |= flt << 12; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4F_MASK; + TIM_CCMR2(timer_peripheral) |= flt << 12; break; } } @@ -1713,24 +1716,24 @@ Set the number of events between each capture. @param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler. */ -void timer_ic_set_prescaler(u32 timer, enum tim_ic_id ic, enum tim_ic_psc psc) +void timer_ic_set_prescaler(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_psc psc) { switch (ic) { case TIM_IC1: - TIM_CCMR1(timer) &= ~TIM_CCMR1_IC1PSC_MASK; - TIM_CCMR1(timer) |= psc << 2; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1PSC_MASK; + TIM_CCMR1(timer_peripheral) |= psc << 2; break; case TIM_IC2: - TIM_CCMR1(timer) &= ~TIM_CCMR1_IC2PSC_MASK; - TIM_CCMR1(timer) |= psc << 10; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2PSC_MASK; + TIM_CCMR1(timer_peripheral) |= psc << 10; break; case TIM_IC3: - TIM_CCMR2(timer) &= ~TIM_CCMR2_IC3PSC_MASK; - TIM_CCMR2(timer) |= psc << 4; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3PSC_MASK; + TIM_CCMR2(timer_peripheral) |= psc << 4; break; case TIM_IC4: - TIM_CCMR2(timer) &= ~TIM_CCMR2_IC4PSC_MASK; - TIM_CCMR2(timer) |= psc << 10; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4PSC_MASK; + TIM_CCMR2(timer_peripheral) |= psc << 10; break; } } @@ -1756,7 +1759,7 @@ internal trigger input selected through TS bit @param[in] in ::tim_ic_input. Input Capture channel direction and source input. */ -void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in) +void timer_ic_set_input(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_input in) { in &= 3; @@ -1768,20 +1771,20 @@ void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in) switch (ic) { case TIM_IC1: - TIM_CCMR1(timer) &= ~TIM_CCMR1_CC1S_MASK; - TIM_CCMR1(timer) |= in; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; + TIM_CCMR1(timer_peripheral) |= in; break; case TIM_IC2: - TIM_CCMR1(timer) &= ~TIM_CCMR1_CC2S_MASK; - TIM_CCMR1(timer) |= in << 8; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; + TIM_CCMR1(timer_peripheral) |= in << 8; break; case TIM_IC3: - TIM_CCMR2(timer) &= ~TIM_CCMR2_CC3S_MASK; - TIM_CCMR2(timer) |= in; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; + TIM_CCMR2(timer_peripheral) |= in; break; case TIM_IC4: - TIM_CCMR2(timer) &= ~TIM_CCMR2_CC4S_MASK; - TIM_CCMR2(timer) |= in << 8; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; + TIM_CCMR2(timer_peripheral) |= in << 8; break; } } @@ -1794,12 +1797,12 @@ void timer_ic_set_input(u32 timer, enum tim_ic_id ic, enum tim_ic_input in) @param[in] pol ::tim_ic_pol. Input Capture polarity. */ -void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol) +void timer_ic_set_polarity(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_pol pol) { if (pol) - TIM_CCER(timer) |= (0x2 << (ic * 4)); + TIM_CCER(timer_peripheral) |= (0x2 << (ic * 4)); else - TIM_CCER(timer) &= ~(0x2 << (ic * 4)); + TIM_CCER(timer_peripheral) &= ~(0x2 << (ic * 4)); } /*---------------------------------------------------------------------------*/ @@ -1809,9 +1812,9 @@ void timer_ic_set_polarity(u32 timer, enum tim_ic_id ic, enum tim_ic_pol pol) @param[in] ic ::tim_ic_id. Input Capture channel designator. */ -void timer_ic_enable(u32 timer, enum tim_ic_id ic) +void timer_ic_enable(u32 timer_peripheral, enum tim_ic_id ic) { - TIM_CCER(timer) |= (0x1 << (ic * 4)); + TIM_CCER(timer_peripheral) |= (0x1 << (ic * 4)); } /*---------------------------------------------------------------------------*/ @@ -1821,9 +1824,9 @@ void timer_ic_enable(u32 timer, enum tim_ic_id ic) @param[in] ic ::tim_ic_id. Input Capture channel designator. */ -void timer_ic_disable(u32 timer, enum tim_ic_id ic) +void timer_ic_disable(u32 timer_peripheral, enum tim_ic_id ic) { - TIM_CCER(timer) &= ~(0x1 << (ic * 4)); + TIM_CCER(timer_peripheral) &= ~(0x1 << (ic * 4)); } /*---------------------------------------------------------------------------*/ @@ -1838,10 +1841,10 @@ Set the input filter parameters for the external trigger, specifying: @param[in] flt ::tim_ic_filter. Input Capture Filter identifier. */ -void timer_slave_set_filter(u32 timer, enum tim_ic_filter flt) +void timer_slave_set_filter(u32 timer_peripheral, enum tim_ic_filter flt) { - TIM_SMCR(timer) &= ~TIM_SMCR_ETF_MASK; - TIM_SMCR(timer) |= flt << 8; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETF_MASK; + TIM_SMCR(timer_peripheral) |= flt << 8; } /*---------------------------------------------------------------------------*/ @@ -1853,10 +1856,10 @@ Set the external trigger frequency division ratio. @param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler. */ -void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc) +void timer_slave_set_prescaler(u32 timer_peripheral, enum tim_ic_psc psc) { - TIM_SMCR(timer) &= ~TIM_SMCR_ETPS_MASK; - TIM_SMCR(timer) |= psc << 12; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETPS_MASK; + TIM_SMCR(timer_peripheral) |= psc << 12; } /*---------------------------------------------------------------------------*/ @@ -1866,12 +1869,12 @@ void timer_slave_set_prescaler(u32 timer, enum tim_ic_psc psc) @param[in] pol ::tim_ic_pol. Input Capture polarity. */ -void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol) +void timer_slave_set_polarity(u32 timer_peripheral, enum tim_ic_pol pol) { if (pol) - TIM_SMCR(timer) |= TIM_SMCR_ETP; + TIM_SMCR(timer_peripheral) |= TIM_SMCR_ETP; else - TIM_SMCR(timer) &= ~TIM_SMCR_ETP; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETP; } /*---------------------------------------------------------------------------*/ @@ -1881,10 +1884,10 @@ void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol) @param[in] mode Unsigned int8. Slave mode @ref tim_sms */ -void timer_slave_set_mode(u32 timer, u8 mode) +void timer_slave_set_mode(u32 timer_peripheral, u8 mode) { - TIM_SMCR(timer) &= ~TIM_SMCR_SMS_MASK; - TIM_SMCR(timer) |= mode; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_SMS_MASK; + TIM_SMCR(timer_peripheral) |= mode; } /*---------------------------------------------------------------------------*/ @@ -1894,28 +1897,13 @@ void timer_slave_set_mode(u32 timer, u8 mode) @param[in] trigger Unsigned int8. Slave trigger source @ref tim_ts */ -void timer_slave_set_trigger(u32 timer, u8 trigger) +void timer_slave_set_trigger(u32 timer_peripheral, u8 trigger) { - TIM_SMCR(timer) &= ~TIM_SMCR_TS_MASK; - TIM_SMCR(timer) |= trigger; -} - -/*---------------------------------------------------------------------------*/ -/** @brief Force Timer Event - -A number of events can be forced by software action. All events are cleared by -hardware on completion. - -@param[in] timer_peripheral Unsigned int32. Timer register address base -@param[in] event Unsigned int8. Event identifier @ref tim_event_gen. -More than one event can be forced at the same time by logical OR of the event -identifiers. -*/ - -void timer_force_event(u32 timer, u8 event) -{ - TIM_EGR(timer) = event; + TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_TS_MASK; + TIM_SMCR(timer_peripheral) |= trigger; } /* TODO Timer DMA burst */ +/**@}*/ + diff --git a/lib/stm32/iwdg.c b/lib/stm32/iwdg.c index 0968e7f..84304ad 100644 --- a/lib/stm32/iwdg.c +++ b/lib/stm32/iwdg.c @@ -1,6 +1,6 @@ -/** @file +/** @defgroup STM32F-iwdg-file IWDG -@ingroup STM32F +@ingroup STM32F-files @brief libopencm3 STM32F1xx Independent Watchdog Timer @@ -8,7 +8,7 @@ @author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net -@date 11 June 2012 +@date 18 August 2012 This library supports the Independent Watchdog Timer System in the STM32F1xx series of ARM Cortex Microcontrollers by ST Microelectronics. @@ -22,8 +22,6 @@ Note that the User Configuration option byte provides a means of automatically enabling the IWDG timer at power on (with counter value 0xFFF). If the relevant bit is not set, the IWDG timer must be enabled by software. -@bugs None known - @note: Tested: CPU STM32F103RET6, Board ET-ARM Stamp STM32 LGPL License Terms @ref lgpl_license @@ -45,9 +43,13 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ +/**@{*/ + #include #define LSI_FREQUENCY 32000 +#define COUNT_LENGTH 12 +#define COUNT_MASK ((1 << COUNT_LENGTH)-1) /*-----------------------------------------------------------------------------*/ /** @brief IWDG Enable Watchdog Timer @@ -73,13 +75,10 @@ A delay of up to 5 clock cycles of the LSI clock (about 156 microseconds) can occasionally occur if the prescale or preload registers are currently busy loading a previous value. -@param[in] u32 Period in milliseconds (< 32760) from a watchdog reset until +@param[in] period u32 Period in milliseconds (< 32760) from a watchdog reset until a system reset is issued. */ -#define COUNT_LENGTH 12 -#define COUNT_MASK ((1 << COUNT_LENGTH)-1) - void iwdg_set_period_ms(u32 period) { u32 count, prescale, reload, exponent; @@ -141,4 +140,5 @@ void iwdg_reset(void) { IWDG_KR = IWDG_KR_RESET; } +/**@}*/ diff --git a/lib/stm32/systick.c b/lib/stm32/systick.c index c49d11d..cfac213 100644 --- a/lib/stm32/systick.c +++ b/lib/stm32/systick.c @@ -1,3 +1,23 @@ +/** @defgroup STM32F-systick-file SysTick + +@ingroup STM32F-files + +@brief libopencm3 STM32Fxx System Tick Timer + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Thomas Otto + +@date 19 August 2012 + +This library supports the System Tick timer in the +STM32F series of ARM Cortex Microcontrollers by ST Microelectronics. + +The System Tick timer is part of the ARM Cortex core. It is a 24 bit +down counter that can be configured with an automatical reload value. + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,44 +37,97 @@ * along with this library. If not, see . */ +/**@{*/ #include +/*-----------------------------------------------------------------------------*/ +/** @brief SysTick Set the Automatic Reload Value. + +The counter is set to the reload value when the counter starts and after it +reaches zero. + +@param[in] value u32. 24 bit reload value. +*/ + void systick_set_reload(u32 value) { STK_LOAD = (value & 0x00FFFFFF); } +/*-----------------------------------------------------------------------------*/ +/** @brief SysTick Read the Automatic Reload Value. + +@returns 24 bit reload value as u32. +*/ + u32 systick_get_value(void) { return STK_VAL; } +/*-----------------------------------------------------------------------------*/ +/** @brief Set the SysTick Clock Source. + +The clock source can be either the AHB clock or the same clock divided by 8. + +@param[in] clocksource u8. Clock source from @ref systick_clksource. +*/ + void systick_set_clocksource(u8 clocksource) { if (clocksource < 2) STK_CTRL |= (clocksource << STK_CTRL_CLKSOURCE_LSB); } +/*-----------------------------------------------------------------------------*/ +/** @brief Enable SysTick Interrupt. + +*/ + void systick_interrupt_enable(void) { STK_CTRL |= STK_CTRL_TICKINT; } +/*-----------------------------------------------------------------------------*/ +/** @brief Disable SysTick Interrupt. + +*/ + void systick_interrupt_disable(void) { STK_CTRL &= ~STK_CTRL_TICKINT; } +/*-----------------------------------------------------------------------------*/ +/** @brief Enable SysTick Counter. + +*/ + void systick_counter_enable(void) { STK_CTRL |= STK_CTRL_ENABLE; } +/*-----------------------------------------------------------------------------*/ +/** @brief Disable SysTick Counter. + +*/ + void systick_counter_disable(void) { STK_CTRL &= ~STK_CTRL_ENABLE; } +/*-----------------------------------------------------------------------------*/ +/** @brief SysTick Read the Counter Flag. + +The count flag is set when the timer count becomes zero, and is cleared when the +flag is read. + +@returns Boolean if flag set. +*/ + u8 systick_get_countflag(void) { if (STK_CTRL & STK_CTRL_COUNTFLAG) @@ -62,3 +135,5 @@ u8 systick_get_countflag(void) else return 0; } +/**@}*/ + -- cgit v1.2.3 From acc276a612d4ea4babf47f8719225eb4a5833036 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Fri, 31 Aug 2012 09:54:31 +0930 Subject: ADC documentation added In adc.h additional defines needed to assist documentation - lines 172-191 added, and 384,436-451 are duplicates of earlier defines to complete parameter sets (compiler has no trouble with these). Minor doc corrections to other files. No code changes (apart from additional defines). --- include/libopencm3/stm32/doc-stm32f.h | 2 +- include/libopencm3/stm32/f1/adc.h | 226 +++++++++++++-- include/libopencm3/stm32/f1/nvic_f1.h | 8 +- include/libopencm3/stm32/nvic.h | 4 +- lib/stm32/dac.c | 4 +- lib/stm32/f1/adc.c | 504 +++++++++++++++++++++++++++++++++- lib/stm32/iwdg.c | 4 +- lib/stm32/nvic.c | 4 +- lib/stm32/systick.c | 4 +- 9 files changed, 725 insertions(+), 35 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/doc-stm32f.h b/include/libopencm3/stm32/doc-stm32f.h index 0f3f850..b0532de 100644 --- a/include/libopencm3/stm32/doc-stm32f.h +++ b/include/libopencm3/stm32/doc-stm32f.h @@ -13,7 +13,7 @@ LGPL License Terms @ref lgpl_license */ -/** @defgroup STM32F-files STM32F Top Level Files +/** @defgroup STM32F_files STM32F Top Level Files @brief Common Files for ST Microelectronics STM32F series. diff --git a/include/libopencm3/stm32/f1/adc.h b/include/libopencm3/stm32/f1/adc.h index 563e75d..64865f4 100644 --- a/include/libopencm3/stm32/f1/adc.h +++ b/include/libopencm3/stm32/f1/adc.h @@ -1,3 +1,17 @@ +/** @defgroup STM32F1xx_adc_defines ADC Defines + +@brief Defined Constants and Types for the STM32F1xx Analog to Digital Converters + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Edward Cheeseman + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,6 +31,8 @@ * along with this library. If not, see . */ +/**@{*/ + #ifndef LIBOPENCM3_ADC_H #define LIBOPENCM3_ADC_H @@ -26,9 +42,15 @@ /* --- Convenience macros -------------------------------------------------- */ /* ADC port base addresses (for convenience) */ +/****************************************************************************/ +/** @defgroup adc_reg_base ADC register base addresses +@ingroup STM32F1xx_adc_defines + +@{*/ #define ADC1 ADC1_BASE #define ADC2 ADC2_BASE #define ADC3 ADC3_BASE +/**@}*/ /* --- ADC registers ------------------------------------------------------- */ @@ -140,6 +162,35 @@ #define ADC2_DR ADC_DR(ADC2) #define ADC3_DR ADC_DR(ADC3) +/* --- ADC Channels ------------------------------------------------------- */ + +/****************************************************************************/ +/** @defgroup adc_channel ADC Channel Numbers +@ingroup STM32F1xx_adc_defines + +@{*/ +#define ADC_CHANNEL0 0x00 +#define ADC_CHANNEL1 0x01 +#define ADC_CHANNEL2 0x02 +#define ADC_CHANNEL3 0x03 +#define ADC_CHANNEL4 0x04 +#define ADC_CHANNEL5 0x05 +#define ADC_CHANNEL6 0x06 +#define ADC_CHANNEL7 0x07 +#define ADC_CHANNEL8 0x08 +#define ADC_CHANNEL9 0x09 +#define ADC_CHANNEL10 0x0A +#define ADC_CHANNEL11 0x0B +#define ADC_CHANNEL12 0x0C +#define ADC_CHANNEL13 0x0D +#define ADC_CHANNEL14 0x0E +#define ADC_CHANNEL15 0x0F +#define ADC_CHANNEL16 0x10 +#define ADC_CHANNEL17 0x11 +#define ADC_MASK 0x1F +#define ADC_SHIFT 0 +/**@}*/ + /* --- ADC_SR values ------------------------------------------------------- */ #define ADC_SR_STRT (1 << 4) @@ -171,20 +222,42 @@ * SIM: Slow interleaved mode only. * ATM: Alternate trigger mode only. */ +/****************************************************************************/ +/* ADC_CR1 DUALMOD[3:0] ADC Mode Selection */ +/** @defgroup adc_cr1_dualmod ADC Mode Selection +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Independent (non-dual) mode */ #define ADC_CR1_DUALMOD_IND (0x0 << 16) +/** Combined regular simultaneous + injected simultaneous mode. */ #define ADC_CR1_DUALMOD_CRSISM (0x1 << 16) +/** Combined regular simultaneous + alternate trigger mode. */ #define ADC_CR1_DUALMOD_CRSATM (0x2 << 16) +/** Combined injected simultaneous + fast interleaved mode. */ #define ADC_CR1_DUALMOD_CISFIM (0x3 << 16) +/** Combined injected simultaneous + slow interleaved mode. */ #define ADC_CR1_DUALMOD_CISSIM (0x4 << 16) +/** Injected simultaneous mode only. */ #define ADC_CR1_DUALMOD_ISM (0x5 << 16) +/** Regular simultaneous mode only. */ #define ADC_CR1_DUALMOD_RSM (0x6 << 16) +/** Fast interleaved mode only. */ #define ADC_CR1_DUALMOD_FIM (0x7 << 16) +/** Slow interleaved mode only. */ #define ADC_CR1_DUALMOD_SIM (0x8 << 16) +/** Alternate trigger mode only. */ #define ADC_CR1_DUALMOD_ATM (0x9 << 16) #define ADC_CR1_DUALMOD_MASK (0xF << 16) #define ADC_CR1_DUALMOD_SHIFT 16 +/**@}*/ /* DISCNUM[2:0]: Discontinous mode channel count. */ +/****************************************************************************/ +/** @defgroup adc_cr1_discnum ADC Number of channels in discontinuous mode. +@ingroup STM32F1xx_adc_defines + +@{*/ #define ADC_CR1_DISCNUM_1CHANNELS (0x0 << 13) #define ADC_CR1_DISCNUM_2CHANNELS (0x1 << 13) #define ADC_CR1_DISCNUM_3CHANNELS (0x2 << 13) @@ -195,29 +268,30 @@ #define ADC_CR1_DISCNUM_8CHANNELS (0x7 << 13) #define ADC_CR1_DISCNUM_MASK (0x7 << 13) #define ADC_CR1_DISCNUM_SHIFT 13 +/**@}*/ -/* JDISCEN: Discontinous mode on injected channels. */ +/* JDISCEN: */ /** Discontinous mode on injected channels. */ #define ADC_CR1_JDISCEN (1 << 12) -/* DISCEN: Discontinous mode on regular channels. */ +/* DISCEN: */ /** Discontinous mode on regular channels. */ #define ADC_CR1_DISCEN (1 << 11) -/* JAUTO: Automatic Injection Group conversion. */ +/* JAUTO: */ /** Automatic Injection Group conversion. */ #define ADC_CR1_JAUTO (1 << 10) -/* AWDSGL: Enable the watchdog on a single channel in scan mode. */ +/* AWDSGL: */ /** Enable the watchdog on a single channel in scan mode. */ #define ADC_CR1_AWDSGL (1 << 9) -/* SCAN: Scan mode. */ +/* SCAN: */ /** Scan mode. */ #define ADC_CR1_SCAN (1 << 8) -/* JEOCIE: Interrupt enable for injected channels. */ +/* JEOCIE: */ /** Interrupt enable for injected channels. */ #define ADC_CR1_JEOCIE (1 << 7) -/* AWDIE: Analog watchdog interrupt enable. */ +/* AWDIE: */ /** Analog watchdog interrupt enable. */ #define ADC_CR1_AWDIE (1 << 6) -/* EOCIE: Interrupt enable EOC. */ +/* EOCIE: */ /** Interrupt enable EOC. */ #define ADC_CR1_EOCIE (1 << 5) /* AWDCH[4:0]: Analog watchdog channel bits. (Up to 17 other values reserved) */ @@ -227,6 +301,12 @@ * ADC2: Analog channel 16 and 17 are internally connected to V_SS. * ADC3: Analog channel 9, 14, 15, 16 and 17 are internally connected to V_SS. */ +/****************************************************************************/ +/* ADC_CR1 AWDCH[4:0] ADC watchdog channel */ +/** @defgroup adc_watchdog_channel ADC watchdog channel +@ingroup STM32F1xx_adc_defines + +@{*/ #define ADC_CR1_AWDCH_CHANNEL0 (0x00 << 0) #define ADC_CR1_AWDCH_CHANNEL1 (0x01 << 0) #define ADC_CR1_AWDCH_CHANNEL2 (0x02 << 0) @@ -247,39 +327,70 @@ #define ADC_CR1_AWDCH_CHANNEL17 (0x11 << 0) #define ADC_CR1_AWDCH_MASK (0x1F << 0) #define ADC_CR1_AWDCH_SHIFT 0 +/**@}*/ /* --- ADC_CR2 values ------------------------------------------------------ */ -/* TSVREFE: Temperature sensor and V_REFINT enable. (ADC1 only!) */ +/* TSVREFE: */ /** Temperature sensor and V_REFINT enable. (ADC1 only!) */ #define ADC_CR2_TSVREFE (1 << 23) -/* SWSTART: Start conversion of regular channels. */ +/* SWSTART: */ /** Start conversion of regular channels. */ #define ADC_CR2_SWSTART (1 << 22) -/* JSWSTART: Start conversion of injected channels. */ +/* JSWSTART: */ /** Start conversion of injected channels. */ #define ADC_CR2_JSWSTART (1 << 21) -/* EXTTRIG: External trigger conversion mode for regular channels. */ +/* EXTTRIG: */ /** External trigger conversion mode for regular channels. */ #define ADC_CR2_EXTTRIG (1 << 20) /* EXTSEL[2:0]: External event select for regular group. */ /* The following are only valid for ADC1 and ADC2. */ +/****************************************************************************/ +/* ADC_CR2 EXTSEL[2:0] ADC Trigger Identifier for ADC1 and ADC2 */ +/** @defgroup adc_trigger_regular_12 ADC Trigger Identifier for ADC1 and ADC2 +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Timer 1 Compare Output 1 */ #define ADC_CR2_EXTSEL_TIM1_CC1 (0x0 << 17) +/** Timer 1 Compare Output 2 */ #define ADC_CR2_EXTSEL_TIM1_CC2 (0x1 << 17) +/** Timer 1 Compare Output 3 */ #define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 17) +/** Timer 2 Compare Output 2 */ #define ADC_CR2_EXTSEL_TIM2_CC2 (0x3 << 17) +/** Timer 3 Trigger Output */ #define ADC_CR2_EXTSEL_TIM3_TRGO (0x4 << 17) +/** Timer 4 Compare Output 4 */ #define ADC_CR2_EXTSEL_TIM4_CC4 (0x5 << 17) +/** External Interrupt 11 */ #define ADC_CR2_EXTSEL_EXTI11 (0x6 << 17) +/** Software Trigger */ #define ADC_CR2_EXTSEL_SWSTART (0x7 << 17) +/**@}*/ /* The following are only valid for ADC3 */ +/****************************************************************************/ +/* ADC_CR2 EXTSEL[2:0] ADC Trigger Identifier for ADC3 */ +/** @defgroup adc_trigger_regular_3 ADC Trigger Identifier for ADC3 +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Timer 2 Compare Output 1 */ #define ADC_CR2_EXTSEL_TIM3_CC1 (0x0 << 17) +/** Timer 2 Compare Output 3 */ #define ADC_CR2_EXTSEL_TIM2_CC3 (0x1 << 17) +/** Timer 1 Compare Output 3 */ +#define ADC_CR2_EXTSEL_TIM1_CC3 (0x2 << 17) +/** Timer 8 Compare Output 1 */ #define ADC_CR2_EXTSEL_TIM8_CC1 (0x3 << 17) +/** Timer 8 Trigger Output */ #define ADC_CR2_EXTSEL_TIM8_TRGO (0x4 << 17) +/** Timer 5 Compare Output 1 */ #define ADC_CR2_EXTSEL_TIM5_CC1 (0x5 << 17) +/** Timer 5 Compare Output 3 */ #define ADC_CR2_EXTSEL_TIM5_CC3 (0x6 << 17) +/**@}*/ #define ADC_CR2_EXTSEL_MASK (0x7 << 17) #define ADC_CR2_EXTSEL_SHIFT 17 @@ -291,21 +402,54 @@ /* JEXTSEL[2:0]: External event selection for injected group. */ /* The following are only valid for ADC1 and ADC2. */ +/****************************************************************************/ +/* ADC_CR2 JEXTSEL[2:0] ADC Injected Trigger Identifier for ADC1 and ADC2 */ +/** @defgroup adc_trigger_injected_12 ADC Injected Trigger Identifier for ADC1 and ADC2 +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Timer 1 Trigger Output */ #define ADC_CR2_JEXTSEL_TIM1_TRGO (0x0 << 12) +/** Timer 1 Compare Output 4 */ #define ADC_CR2_JEXTSEL_TIM1_CC4 (0x1 << 12) +/** Timer 2 Trigger Output */ #define ADC_CR2_JEXTSEL_TIM2_TRGO (0x2 << 12) +/** Timer 2 Compare Output 1 */ #define ADC_CR2_JEXTSEL_TIM2_CC1 (0x3 << 12) +/** Timer 3 Compare Output 4 */ #define ADC_CR2_JEXTSEL_TIM3_CC4 (0x4 << 12) +/** Timer 4 Trigger Output */ #define ADC_CR2_JEXTSEL_TIM4_TRGO (0x5 << 12) +/** External Interrupt 15 */ #define ADC_CR2_JEXTSEL_EXTI15 (0x6 << 12) +/** Injected Software Trigger */ #define ADC_CR2_JEXTSEL_JSWSTART (0x7 << 12) /* Software start. */ +/**@}*/ /* The following are the different meanings for ADC3 only. */ +/****************************************************************************/ +/* ADC_CR2 JEXTSEL[2:0] ADC Injected Trigger Identifier for ADC3 */ +/** @defgroup adc_trigger_injected_3 ADC Injected Trigger Identifier for ADC3 +@ingroup STM32F1xx_adc_defines + +@{*/ +/** Timer 1 Trigger Output */ +#define ADC_CR2_JEXTSEL_TIM1_TRGO (0x0 << 12) +/** Timer 1 Compare Output 4 */ +#define ADC_CR2_JEXTSEL_TIM1_CC4 (0x1 << 12) +/** Timer 4 Compare Output 3 */ #define ADC_CR2_JEXTSEL_TIM4_CC3 (0x2 << 12) +/** Timer 8 Compare Output 2 */ #define ADC_CR2_JEXTSEL_TIM8_CC2 (0x3 << 12) +/** Timer 8 Compare Output 4 */ #define ADC_CR2_JEXTSEL_TIM8_CC4 (0x4 << 12) +/** Timer 5 Trigger Output */ #define ADC_CR2_JEXTSEL_TIM5_TRGO (0x5 << 12) +/** Timer53 Compare Output 4 */ #define ADC_CR2_JEXTSEL_TIM5_CC4 (0x6 << 12) +/** Injected Software Trigger */ +#define ADC_CR2_JEXTSEL_JSWSTART (0x7 << 12) /* Software start. */ +/**@}*/ #define ADC_CR2_JEXTSEL_MASK (0x7 << 12) #define ADC_CR2_JEXTSEL_SHIFT 12 @@ -340,7 +484,6 @@ #define ADC_CR2_ADON (1 << 0) /* --- ADC_SMPR1 values ---------------------------------------------------- */ - #define ADC_SMPR1_SMP17_LSB 21 #define ADC_SMPR1_SMP16_LSB 18 #define ADC_SMPR1_SMP15_LSB 15 @@ -357,6 +500,12 @@ #define ADC_SMPR1_SMP12_MSK (0x7 << ADC_SMP12_LSB) #define ADC_SMPR1_SMP11_MSK (0x7 << ADC_SMP11_LSB) #define ADC_SMPR1_SMP10_MSK (0x7 << ADC_SMP10_LSB) +/****************************************************************************/ +/* ADC_SMPR1 ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_r1 ADC Sample Time Selection for ADC1 +@ingroup STM32F1xx_adc_defines + +@{*/ #define ADC_SMPR1_SMP_1DOT5CYC 0x0 #define ADC_SMPR1_SMP_7DOT5CYC 0x1 #define ADC_SMPR1_SMP_13DOT5CYC 0x2 @@ -365,6 +514,7 @@ #define ADC_SMPR1_SMP_55DOT5CYC 0x5 #define ADC_SMPR1_SMP_71DOT5CYC 0x6 #define ADC_SMPR1_SMP_239DOT5CYC 0x7 +/**@}*/ /* --- ADC_SMPR2 values ---------------------------------------------------- */ @@ -388,6 +538,12 @@ #define ADC_SMPR2_SMP2_MSK (0x7 << ADC_SMP2_LSB) #define ADC_SMPR2_SMP1_MSK (0x7 << ADC_SMP1_LSB) #define ADC_SMPR2_SMP0_MSK (0x7 << ADC_SMP0_LSB) +/****************************************************************************/ +/* ADC_SMPR2 ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_r2 ADC Sample Time Selection for ADC2 +@ingroup STM32F1xx_adc_defines + +@{*/ #define ADC_SMPR2_SMP_1DOT5CYC 0x0 #define ADC_SMPR2_SMP_7DOT5CYC 0x1 #define ADC_SMPR2_SMP_13DOT5CYC 0x2 @@ -396,9 +552,15 @@ #define ADC_SMPR2_SMP_55DOT5CYC 0x5 #define ADC_SMPR2_SMP_71DOT5CYC 0x6 #define ADC_SMPR2_SMP_239DOT5CYC 0x7 +/**@}*/ /* --- ADC_SMPRx generic values -------------------------------------------- */ +/****************************************************************************/ +/* ADC_SMPRG ADC Sample Time Selection for Channels */ +/** @defgroup adc_sample_rg ADC Sample Time Selection Generic +@ingroup STM32F1xx_adc_defines +@{*/ #define ADC_SMPR_SMP_1DOT5CYC 0x0 #define ADC_SMPR_SMP_7DOT5CYC 0x1 #define ADC_SMPR_SMP_13DOT5CYC 0x2 @@ -407,6 +569,7 @@ #define ADC_SMPR_SMP_55DOT5CYC 0x5 #define ADC_SMPR_SMP_71DOT5CYC 0x6 #define ADC_SMPR_SMP_239DOT5CYC 0x7 +/**@}*/ /* --- ADC_JOFRx, ADC_HTR, ADC_LTR values ---------------------------------- */ @@ -429,6 +592,13 @@ #define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQ15_LSB) #define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQ14_LSB) #define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQ13_LSB) +/* TODO Fix error +#define ADC_SQR1_L_MSK (0xf << ADC_SQR1_L_LSB) +#define ADC_SQR1_SQ16_MSK (0x1f << ADC_SQR1_SQ16_LSB) +#define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQR1_SQ15_LSB) +#define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQR1_SQ14_LSB) +#define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQR1_SQ13_LSB) +*/ /* --- ADC_SQR2 values ----------------------------------------------------- */ @@ -444,6 +614,14 @@ #define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQ9_LSB) #define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQ8_LSB) #define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQ7_LSB) +/* TODO Fix error +#define ADC_SQR2_SQ12_MSK (0x1f << ADC_SQR2_SQ12_LSB) +#define ADC_SQR2_SQ11_MSK (0x1f << ADC_SQR2_SQ11_LSB) +#define ADC_SQR2_SQ10_MSK (0x1f << ADC_SQR2_SQ10_LSB) +#define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQR2_SQ9_LSB) +#define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQR2_SQ8_LSB) +#define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQR2_SQ7_LSB) +*/ /* --- ADC_SQR3 values ----------------------------------------------------- */ @@ -459,7 +637,14 @@ #define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQ3_LSB) #define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQ2_LSB) #define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQ1_LSB) - +/* TODO Fix error +#define ADC_SQR3_SQ6_MSK (0x1f << ADC_SQR3_SQ6_LSB) +#define ADC_SQR3_SQ5_MSK (0x1f << ADC_SQR3_SQ5_LSB) +#define ADC_SQR3_SQ4_MSK (0x1f << ADC_SQR3_SQ4_LSB) +#define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQR3_SQ3_LSB) +#define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQR3_SQ2_LSB) +#define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQR3_SQ1_LSB) +*/ /* --- ADC_JSQR values ----------------------------------------------------- */ #define ADC_JSQR_JL_LSB 20 @@ -472,6 +657,13 @@ #define ADC_JSQR_JSQ3_MSK (0x1f << ADC_JSQ3_LSB) #define ADC_JSQR_JSQ2_MSK (0x1f << ADC_JSQ2_LSB) #define ADC_JSQR_JSQ1_MSK (0x1f << ADC_JSQ1_LSB) +/* TODO Fix error +#define ADC_JSQR_JL_MSK (0x2 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JSQ4_MSK (0x1f << ADC_JSQR_JSQ4_LSB) +#define ADC_JSQR_JSQ3_MSK (0x1f << ADC_JSQR_JSQ3_LSB) +#define ADC_JSQR_JSQ2_MSK (0x1f << ADC_JSQR_JSQ2_LSB) +#define ADC_JSQR_JSQ1_MSK (0x1f << ADC_JSQR_JSQ1_LSB) +*/ /* --- ADC_JDRx, ADC_DR values --------------------------------------------- */ @@ -481,12 +673,10 @@ #define ADC_JDATA_MSK (0xffff << ADC_JDATA_LSB) #define ADC_DATA_MSK (0xffff << ADC_DA) #define ADC_ADC2DATA_MSK (0xffff << ADC_ADC2DATA_LSB) - /* ADC1 only (dual mode) */ + /* ADC1 only (dual mode) */ /* --- Function prototypes ------------------------------------------------- */ - -/* TODO */ void adc_enable_analog_watchdog_regular(u32 adc); void adc_disable_analog_watchdog_regular(u32 adc); void adc_enable_analog_watchdog_injected(u32 adc); @@ -533,3 +723,5 @@ void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]); void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]); #endif +/**@}*/ + diff --git a/include/libopencm3/stm32/f1/nvic_f1.h b/include/libopencm3/stm32/f1/nvic_f1.h index bb0e03d..5223bb6 100644 --- a/include/libopencm3/stm32/f1/nvic_f1.h +++ b/include/libopencm3/stm32/f1/nvic_f1.h @@ -1,8 +1,4 @@ -/** @defgroup STM32F_nvic_f1_defines STM32F NVIC Defines - -@brief Defined Constants and Types for the STM32F1xx Nested Vectored Interrupt Controller - -@ingroup STM32F_defines +/** @brief Defined Constants and Types for the STM32F1xx Nested Vectored Interrupt Controller @version 1.0.0 @@ -113,6 +109,6 @@ LGPL License Terms @ref lgpl_license #define NVIC_CAN2_RX1_IRQ 65 #define NVIC_CAN2_SCE_IRQ 66 #define NVIC_OTG_FS_IRQ 67 -/*@}*/ +/**@}*/ #endif diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h index 6a98737..a46ca2a 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/stm32/nvic.h @@ -1,4 +1,4 @@ -/** @defgroup STM32F_nvic_defines STM32F NVIC Defines +/** @defgroup STM32F_nvic_defines NVIC Defines @brief libopencm3 STM32F Nested Vectored Interrupt Controller @@ -96,7 +96,7 @@ IRQ numbers -3 and -6 to -9 are reserved /* irq number -3 reserved */ #define NVIC_PENDSV_IRQ -2 #define NVIC_SYSTICK_IRQ -1 -/*@}*/ +/**@}*/ /* Note: User interrupts are family specific and are defined in a family diff --git a/lib/stm32/dac.c b/lib/stm32/dac.c index 7978059..55440bf 100644 --- a/lib/stm32/dac.c +++ b/lib/stm32/dac.c @@ -1,6 +1,6 @@ -/** @defgroup STM32F-dac-file DAC +/** @defgroup STM32F_dac_file DAC -@ingroup STM32F-files +@ingroup STM32F_files @brief libopencm3 STM32Fxx Digital to Analog Converter diff --git a/lib/stm32/f1/adc.c b/lib/stm32/f1/adc.c index f07164f..6f4de48 100644 --- a/lib/stm32/f1/adc.c +++ b/lib/stm32/f1/adc.c @@ -1,3 +1,70 @@ +/** @defgroup STM32F1xx_adc_file ADC + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Analog to Digital Converters + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2009 Edward Cheeseman +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +This library supports the A/D Converter Control System in the STM32F1xx series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Devices can have up to three A/D converters each with their own set of registers. +However all the A/D converters share a common clock which is prescaled from the APB2 +clock by default by a minimum factor of 2 to a maximum of 8. + +Each A/D converter has up to 18 channels: +@li On ADC1 the analog channels 16 and 17 are internally connected to the temperature +sensor and VREFINT, respectively. +@li On ADC2 the analog channels 16 and 17 are internally connected to VSS. +@li On ADC3 the analog channels 9, 14, 15, 16 and 17 are internally connected to VSS. + +The conversions can occur as a one-off conversion whereby the process stops once +conversion is complete. The conversions can also be continuous wherein a new +conversion starts immediately the previous conversion has ended. + +Conversion can occur as a single channel conversion or a scan of a group of +channels in either continuous or one-off mode. If more than one channel is converted +in a scan group, DMA must be used to transfer the data as there is only one +result register available. An interrupt can be set to occur at the end of +conversion, which occurs after all channels have been scanned. + +A discontinuous mode allows a subgroup of group of a channels to be converted in +bursts of a given length. + +Injected conversions allow a second group of channels to be converted separately +from the regular group. An interrupt can be set to occur at the end of +conversion, which occurs after all channels have been scanned. + +@section adc_api_ex Basic ADC Handling API. + +Example 1: Simple single channel conversion polled. Enable the peripheral clock +and ADC, reset ADC and set the prescaler divider. Set dual mode to independent. + +@code + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + adc_power_on(ADC1); + adc_calibration(ADC1); + rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); + rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST); + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); + adc_set_dual_mode(ADC_CR1_DUALMOD_IND); + adc_disable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); + adc_set_single_channel(ADC1, ADC_CHANNEL0); + adc_start_conversion_regular(ADC1); + while (! adc_eoc(ADC1)); + reg16 = adc_read_regular(ADC1); +@endcode + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -27,10 +94,12 @@ * rcc_peripheral_clear_reset(&RCC_APB2RSTR, ADC1RST); * * rcc_set_adc_clk(ADC_PRE_PLCK2_DIV2); - * adc_set_mode(ADC1, TODO); + * adc_set_dual_mode(ADC1, TODO); * reg16 = adc_read(ADC1, ADC_CH_0); */ +/**@{*/ + #include void rcc_set_adc_clk(u32 prescaler) @@ -50,6 +119,14 @@ void adc_set_mode(u32 block, /* TODO */ u8 mode) mode = mode; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read from a Conversion Result Register + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] reg Unsigned int8. Register number (1 ... 4). +@returns Unsigned int32 conversion result. +*/ + void adc_read(u32 block, u32 channel) { /* TODO */ @@ -59,61 +136,167 @@ void adc_read(u32 block, u32 channel) channel = channel; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Regular Conversions + +The analog watchdog allows the monitoring of an analog signal between two threshold +levels. The thresholds must be preset. Comparison is done before data alignment +takes place, so the thresholds are left-aligned. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_analog_watchdog_regular(u32 adc) { ADC_CR1(adc) |= ADC_CR1_AWDEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog for Regular Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_analog_watchdog_regular(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_AWDEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for Injected Conversions + +The analog watchdog allows the monitoring of an analog signal between two threshold +levels. The thresholds must be preset. Comparison is done before data alignment +takes place, so the thresholds are left-aligned. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_analog_watchdog_injected(u32 adc) { ADC_CR1(adc) |= ADC_CR1_JAWDEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog for Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_analog_watchdog_injected(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_JAWDEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Regular Conversions + +In this mode the ADC converts, on each trigger, a subgroup of up to 8 of the +defined regular channel group. The subgroup is defined by the number of +consecutive channels to be converted. After a subgroup has been converted +the next trigger will start conversion of the immediately following subgroup +of the same length or until the whole group has all been converted. When the +the whole group has been converted, the next trigger will restart conversion +of the subgroup at the beginning of the whole group. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] length Unsigned int8. Number of channels in the group @ref adc_cr1_discnum +*/ + void adc_enable_discontinous_mode_regular(u32 adc) { ADC_CR1(adc) |= ADC_CR1_DISCEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Regular Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_discontinous_mode_regular(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_DISCEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Discontinuous Mode for Injected Conversions + +In this mode the ADC converts sequentially one channel of the defined group of +injected channels, cycling back to the first channel in the group once the +entire group has been converted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_discontinous_mode_injected(u32 adc) { ADC_CR1(adc) |= ADC_CR1_JDISCEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Discontinuous Mode for Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_discontinous_mode_injected(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_JDISCEN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Automatic Injected Conversions + +The ADC converts a defined injected group of channels immediately after the +regular channels have been converted. The external trigger on the injected +channels is disabled as required. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_automatic_injected_group_conversion(u32 adc) { ADC_CR1(adc) |= ADC_CR1_JAUTO; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Automatic Injected Conversions + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_automatic_injected_group_conversion(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_JAUTO; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for All Regular and 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. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_analog_watchdog_on_all_channels(u32 adc) { ADC_CR1(adc) |= ADC_CR1_AWDSGL; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog for a Selected Channel + +The analog watchdog allows the monitoring of an analog signal between two threshold +levels. The thresholds must be preset. Comparison is done before data alignment +takes place, so the thresholds are left-aligned. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] channel Unsigned int8. ADC channel number @ref adc_watchdog_channel +*/ + void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel) { u32 reg32; @@ -125,56 +308,140 @@ void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel) ADC_CR1(adc) &= ~ADC_CR1_AWDSGL; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Scan Mode + +In this mode a conversion consists of a scan of the predefined set of channels, +regular and injected, each channel conversion immediately following the +previous one. It can use single, continuous or discontinuous mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_scan_mode(u32 adc) { ADC_CR1(adc) |= ADC_CR1_SCAN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Scan Mode + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_scan_mode(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_SCAN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Injected End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_jeoc_interrupt(u32 adc) { ADC_CR1(adc) |= ADC_CR1_JEOCIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Injected End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_jeoc_interrupt(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_JEOCIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Analog Watchdog Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_awd_interrupt(u32 adc) { ADC_CR1(adc) |= ADC_CR1_AWDIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Analog Watchdog Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_awd_interrupt(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_AWDIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Regular End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_eoc_interrupt(u32 adc) { ADC_CR1(adc) |= ADC_CR1_EOCIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable Regular End-Of-Conversion Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_eoc_interrupt(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_EOCIE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable The Temperature Sensor + +This enables both the sensor and the reference voltage measurements on channels +16 and 17. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_temperature_sensor(u32 adc) { ADC_CR2(adc) |= ADC_CR2_TSVREFE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable The Temperature Sensor + +Disabling this will reduce power consumption from the sensor and the reference +voltage measurements. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_temperature_sensor(u32 adc) { ADC_CR2(adc) &= ~ADC_CR2_TSVREFE; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Regular Channels + +This starts conversion on a set of defined regular channels if the ADC trigger +is set to be a software trigger. It is cleared by hardware once conversion +starts. + +Note this is a software trigger and requires triggering to be enabled and the +trigger source to be set appropriately otherwise conversion will not start. +This is not the same as the ADC start conversion operation. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_start_conversion_regular(u32 adc) { /* Start conversion on regular channels. */ @@ -184,6 +451,20 @@ void adc_start_conversion_regular(u32 adc) while (ADC_CR2(adc) & ADC_CR2_SWSTART); } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Software Triggered Conversion on Injected Channels + +This starts conversion on a set of defined injected channels if the ADC trigger +is set to be a software trigger. It is cleared by hardware once conversion +starts. + +Note this is a software trigger and requires triggering to be enabled and the +trigger source to be set appropriately otherwise conversion will not start. +This is not the same as the ADC start conversion operation. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_start_conversion_injected(u32 adc) { /* Start conversion on injected channels. */ @@ -193,6 +474,36 @@ void adc_start_conversion_injected(u32 adc) while (ADC_CR2(adc) & ADC_CR2_JSWSTART); } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + +This enables an external trigger for set of defined regular channels. + +For ADC1 and ADC2 +@li Timer 1 CC1 event +@li Timer 1 CC2 event +@li Timer 1 CC3 event +@li Timer 2 CC2 event +@li Timer 3 TRGO event +@li Timer 4 CC4 event +@li EXTI (TIM8_TRGO is also possible on some devices, see datasheet) +@li Software Start + +For ADC3 +@li Timer 3 CC1 event +@li Timer 2 CC3 event +@li Timer 1 CC3 event +@li Timer 8 CC1 event +@li Timer 8 TRGO event +@li Timer 5 CC1 event +@li Timer 5 CC3 event +@li Software Start + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_regular_12 +for ADC1 and ADC2, or @ref adc_trigger_regular_3 for ADC3 +*/ + void adc_enable_external_trigger_regular(u32 adc, u32 trigger) { u32 reg32; @@ -204,11 +515,47 @@ void adc_enable_external_trigger_regular(u32 adc, u32 trigger) ADC_CR2(adc) |= ADC_CR2_EXTTRIG; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_external_trigger_regular(u32 adc) { ADC_CR2(adc) &= ~ADC_CR2_EXTTRIG; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + +This enables an external trigger for set of defined injected channels. + +For ADC1 and ADC2 +@li Timer 1 TRGO event +@li Timer 1 CC4 event +@li Timer 2 TRGO event +@li Timer 2 CC1 event +@li Timer 3 CC4 event +@li Timer 4 TRGO event +@li EXTI (TIM8 CC4 is also possible on some devices, see datasheet) +@li Software Start + +For ADC3 +@li Timer 1 TRGO event +@li Timer 1 CC4 event +@li Timer 4 CC3 event +@li Timer 8 CC2 event +@li Timer 8 CC4 event +@li Timer 5 TRGO event +@li Timer 5 CC4 event +@li Software Start + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_injected_12 +for ADC1 and ADC2, or @ref adc_trigger_injected_3 for ADC3 +*/ + void adc_enable_external_trigger_injected(u32 adc, u32 trigger) { u32 reg32; @@ -220,65 +567,169 @@ void adc_enable_external_trigger_injected(u32 adc, u32 trigger) ADC_CR2(adc) |= ADC_CR2_JEXTTRIG; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Injected Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_external_trigger_injected(u32 adc) { ADC_CR2(adc) &= ~ADC_CR2_JEXTTRIG; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Data as Left Aligned + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_set_left_aligned(u32 adc) { ADC_CR2(adc) |= ADC_CR2_ALIGN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Data as Right Aligned + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_set_right_aligned(u32 adc) { ADC_CR2(adc) &= ~ADC_CR2_ALIGN; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable DMA Transfers + +Only available for ADC1 through DMA1 channel1, and ADC3 through DMA2 channel5. +ADC2 will use DMA if it is set as slave in dual mode with ADC1 in DMA transfer +mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_enable_dma(u32 adc) { if ((adc == ADC1) | (adc == ADC3)) ADC_CR2(adc) |= ADC_CR2_DMA; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Disable DMA Transfers + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_disable_dma(u32 adc) { if ((adc == ADC1) | (adc == ADC3)) ADC_CR2(adc) &= ~ADC_CR2_DMA; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Initialize Calibration Registers + +This resets the calibration registers. It is not clear if this is required to be +done before every calibration operation. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_reset_calibration(u32 adc) { ADC_CR2(adc) |= ADC_CR2_RSTCAL; while (ADC_CR2(adc) & ADC_CR2_RSTCAL); } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Calibration + +The calibration data for the ADC is recomputed. The hardware clears the +calibration status flag when calibration is complete. This function does not return +until this happens and the ADC is ready for use. + +The ADC must have been powered down for at least 2 ADC clock cycles, then powered on. +before calibration starts + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_calibration(u32 adc) { ADC_CR2(adc) |= ADC_CR2_CAL; while (ADC_CR2(adc) & ADC_CR2_CAL); } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Continuous Conversion Mode + +In this mode the ADC starts a new conversion of a single channel or a channel +group immediately following completion of the previous channel group conversion. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_set_continous_conversion_mode(u32 adc) { ADC_CR2(adc) |= ADC_CR2_CONT; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Enable Single Conversion Mode + +In this mode the ADC performs a conversion of one channel or a channel group +and stops. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_set_single_conversion_mode(u32 adc) { ADC_CR2(adc) &= ~ADC_CR2_CONT; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Power On + +If the ADC is in power-down mode then it is powered up. The application needs +to wait a time of about 3 microseconds for stabilization before using the ADC. +If the ADC is already on this function call will initiate a conversion. + +@todo fix this. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_on(u32 adc) { ADC_CR2(adc) |= ADC_CR2_ADON; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Off + +Turn off the ADC to reduce power consumption to a few microamps. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + void adc_off(u32 adc) { ADC_CR2(adc) &= ~ADC_CR2_ADON; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for a Single Channel + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] channel Unsigned int8. ADC Channel integer 0..18 or from @ref adc_channel +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg +*/ + void adc_set_conversion_time(u32 adc, u8 channel, u8 time) { u32 reg32; @@ -296,6 +747,16 @@ void adc_set_conversion_time(u32 adc, u8 channel, u8 time) } } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for All Channels + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5, same for +all channels. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg +*/ + void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) { u8 i; @@ -310,6 +771,13 @@ void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) ADC_SMPR1(adc) = reg32; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Upper Threshold + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] threshold Unsigned int8. Upper threshold value +*/ + void adc_set_watchdog_high_threshold(u32 adc, u16 threshold) { u32 reg32 = 0; @@ -319,6 +787,13 @@ void adc_set_watchdog_high_threshold(u32 adc, u16 threshold) ADC_HTR(adc) = reg32; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Analog Watchdog Lower Threshold + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] threshold Unsigned int8. Lower threshold value +*/ + void adc_set_watchdog_low_threshold(u32 adc, u16 threshold) { u32 reg32 = 0; @@ -328,6 +803,18 @@ void adc_set_watchdog_low_threshold(u32 adc, u16 threshold) ADC_LTR(adc) = reg32; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set a Regular Channel Conversion Sequence + +Define a sequence of channels to be converted as a regular group with a length +from 1 to 16 channels. If this is called during conversion, the current conversion +is reset and conversion begins again with the newly defined group. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] length Unsigned int8. Number of channels in the group. +@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..18. +*/ + void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]) { u32 reg32_1 = 0, reg32_2 = 0, reg32_3 = 0; @@ -352,6 +839,18 @@ void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]) ADC_SQR3(adc) = reg32_3; } +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set an Injected Channel Conversion Sequence + +Defines a sequence of channels to be converted as an injected group with a length +from 1 to 4 channels. If this is called during conversion, the current conversion +is reset and conversion begins again with the newly defined group. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] length Unsigned int8. Number of channels in the group. +@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..18 +*/ + void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]) { u32 reg32 = 0; @@ -368,3 +867,6 @@ void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]) ADC_JSQR(adc) = reg32; } + +/**@}*/ + diff --git a/lib/stm32/iwdg.c b/lib/stm32/iwdg.c index 84304ad..251bec1 100644 --- a/lib/stm32/iwdg.c +++ b/lib/stm32/iwdg.c @@ -1,6 +1,6 @@ -/** @defgroup STM32F-iwdg-file IWDG +/** @defgroup STM32F_iwdg_file IWDG -@ingroup STM32F-files +@ingroup STM32F_files @brief libopencm3 STM32F1xx Independent Watchdog Timer diff --git a/lib/stm32/nvic.c b/lib/stm32/nvic.c index e17e78c..84fa674 100644 --- a/lib/stm32/nvic.c +++ b/lib/stm32/nvic.c @@ -1,6 +1,6 @@ -/** @defgroup STM32F-nvic-file NVIC +/** @defgroup STM32F_nvic_file NVIC -@ingroup STM32F-files +@ingroup STM32F_files @brief libopencm3 STM32F Nested Vectored Interrupt Controller diff --git a/lib/stm32/systick.c b/lib/stm32/systick.c index cfac213..36077cc 100644 --- a/lib/stm32/systick.c +++ b/lib/stm32/systick.c @@ -1,6 +1,6 @@ -/** @defgroup STM32F-systick-file SysTick +/** @defgroup STM32F_systick_file SysTick -@ingroup STM32F-files +@ingroup STM32F_files @brief libopencm3 STM32Fxx System Tick Timer -- cgit v1.2.3 From 9af50d6e5cf0681b276438acfd92c9975290f1b2 Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Fri, 31 Aug 2012 21:47:30 +0930 Subject: STM32F1xx Additional minor changes to adc.h and adc.c --- include/libopencm3/stm32/f1/adc.h | 8 ++++---- lib/stm32/f1/adc.c | 12 +++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/stm32/f1/adc.h b/include/libopencm3/stm32/f1/adc.h index 64865f4..5a3fd20 100644 --- a/include/libopencm3/stm32/f1/adc.h +++ b/include/libopencm3/stm32/f1/adc.h @@ -187,9 +187,9 @@ LGPL License Terms @ref lgpl_license #define ADC_CHANNEL15 0x0F #define ADC_CHANNEL16 0x10 #define ADC_CHANNEL17 0x11 +/**@}*/ #define ADC_MASK 0x1F #define ADC_SHIFT 0 -/**@}*/ /* --- ADC_SR values ------------------------------------------------------- */ @@ -248,9 +248,9 @@ LGPL License Terms @ref lgpl_license #define ADC_CR1_DUALMOD_SIM (0x8 << 16) /** Alternate trigger mode only. */ #define ADC_CR1_DUALMOD_ATM (0x9 << 16) +/**@}*/ #define ADC_CR1_DUALMOD_MASK (0xF << 16) #define ADC_CR1_DUALMOD_SHIFT 16 -/**@}*/ /* DISCNUM[2:0]: Discontinous mode channel count. */ /****************************************************************************/ @@ -266,9 +266,9 @@ LGPL License Terms @ref lgpl_license #define ADC_CR1_DISCNUM_6CHANNELS (0x5 << 13) #define ADC_CR1_DISCNUM_7CHANNELS (0x6 << 13) #define ADC_CR1_DISCNUM_8CHANNELS (0x7 << 13) +/**@}*/ #define ADC_CR1_DISCNUM_MASK (0x7 << 13) #define ADC_CR1_DISCNUM_SHIFT 13 -/**@}*/ /* JDISCEN: */ /** Discontinous mode on injected channels. */ #define ADC_CR1_JDISCEN (1 << 12) @@ -325,9 +325,9 @@ LGPL License Terms @ref lgpl_license #define ADC_CR1_AWDCH_CHANNEL15 (0x0F << 0) #define ADC_CR1_AWDCH_CHANNEL16 (0x10 << 0) #define ADC_CR1_AWDCH_CHANNEL17 (0x11 << 0) +/**@}*/ #define ADC_CR1_AWDCH_MASK (0x1F << 0) #define ADC_CR1_AWDCH_SHIFT 0 -/**@}*/ /* --- ADC_CR2 values ------------------------------------------------------ */ diff --git a/lib/stm32/f1/adc.c b/lib/stm32/f1/adc.c index 6f4de48..433cdd2 100644 --- a/lib/stm32/f1/adc.c +++ b/lib/stm32/f1/adc.c @@ -272,12 +272,17 @@ void adc_disable_automatic_injected_group_conversion(u32 adc) } /*-----------------------------------------------------------------------------*/ -/** @brief ADC Enable Analog Watchdog for All Regular and Injected Channels +/** @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 */ @@ -293,6 +298,11 @@ The analog watchdog allows the monitoring of an analog signal between two thresh levels. The thresholds must be preset. Comparison is done before data alignment takes place, so the thresholds are left-aligned. +@note The analog watchdog must be enabled for either or both of the regular or +injected channels. If neither are enabled, the analog watchdog feature will be +disabled. If both are enabled, the same channel number is monitored. +@ref adc_enable_analog_watchdog_injected, @ref adc_enable_analog_watchdog_regular. + @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base @param[in] channel Unsigned int8. ADC channel number @ref adc_watchdog_channel */ -- cgit v1.2.3 From 3aab6220d83d5b9fcd318e9d87225ff405cad783 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 2 Sep 2012 17:12:58 +0200 Subject: Add C linkage declaration for C++ usage --- include/libopencm3/cm3/common.h | 10 ++++++++++ include/libopencm3/lm3s/gpio.h | 4 ++++ include/libopencm3/lpc17xx/gpio.h | 4 ++++ include/libopencm3/lpc43xx/gpio.h | 4 ++++ include/libopencm3/lpc43xx/i2c.h | 4 ++++ include/libopencm3/lpc43xx/nvic.h | 4 ++++ include/libopencm3/lpc43xx/scu.h | 4 ++++ include/libopencm3/lpc43xx/ssp.h | 4 ++++ include/libopencm3/lpc43xx/systick.h | 4 ++++ include/libopencm3/stm32/can.h | 4 ++++ include/libopencm3/stm32/crc.h | 4 ++++ include/libopencm3/stm32/dac.h | 4 ++++ include/libopencm3/stm32/exti.h | 4 ++++ include/libopencm3/stm32/f1/adc.h | 3 +++ include/libopencm3/stm32/f1/desig.h | 4 ++++ include/libopencm3/stm32/f1/dma.h | 4 ++++ include/libopencm3/stm32/f1/flash.h | 4 ++++ include/libopencm3/stm32/f1/gpio.h | 4 ++++ include/libopencm3/stm32/f1/rcc.h | 4 ++++ include/libopencm3/stm32/f1/rtc.h | 4 ++++ include/libopencm3/stm32/f1/scb.h | 5 +++++ include/libopencm3/stm32/f2/flash.h | 4 ++++ include/libopencm3/stm32/f2/gpio.h | 4 ++++ include/libopencm3/stm32/f2/rcc.h | 4 ++++ include/libopencm3/stm32/f2/scb.h | 5 +++++ include/libopencm3/stm32/f2/timer.h | 4 ++++ include/libopencm3/stm32/f4/flash.h | 4 ++++ include/libopencm3/stm32/f4/gpio.h | 4 ++++ include/libopencm3/stm32/f4/pwr.h | 4 ++++ include/libopencm3/stm32/f4/rcc.h | 4 ++++ include/libopencm3/stm32/f4/scb.h | 5 +++++ include/libopencm3/stm32/f4/timer.h | 4 ++++ include/libopencm3/stm32/i2c.h | 4 ++++ include/libopencm3/stm32/iwdg.h | 4 ++++ include/libopencm3/stm32/nvic.h | 4 ++++ include/libopencm3/stm32/pwr.h | 4 ++++ include/libopencm3/stm32/spi.h | 4 ++++ include/libopencm3/stm32/systick.h | 4 ++++ include/libopencm3/stm32/timer.h | 5 +++++ include/libopencm3/stm32/usart.h | 4 ++++ include/libopencm3/usb/usbd.h | 4 ++++ 41 files changed, 173 insertions(+) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/cm3/common.h b/include/libopencm3/cm3/common.h index 54cd2e4..7ef18fe 100644 --- a/include/libopencm3/cm3/common.h +++ b/include/libopencm3/cm3/common.h @@ -32,6 +32,16 @@ typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; +/* This must be placed around external function declaration for C++ + * support. */ +#ifdef __cplusplus +# define BEGIN_DECLS extern "C" { +# define END_DECLS } +#else +# define BEGIN_DECLS +# define END_DECLS +#endif + /* Generic memory-mapped I/O accessor functions */ #define MMIO8(addr) (*(volatile u8 *)(addr)) #define MMIO16(addr) (*(volatile u16 *)(addr)) diff --git a/include/libopencm3/lm3s/gpio.h b/include/libopencm3/lm3s/gpio.h index 852609f..5296b74 100644 --- a/include/libopencm3/lm3s/gpio.h +++ b/include/libopencm3/lm3s/gpio.h @@ -69,7 +69,11 @@ #define GPIO_CR(port) MMIO32(port + 0x524) #define GPIO_AMSEL(port) MMIO32(port + 0x528) +BEGIN_DECLS + void gpio_set(u32 gpioport, u8 gpios); void gpio_clear(u32 gpioport, u8 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/lpc17xx/gpio.h b/include/libopencm3/lpc17xx/gpio.h index 7b07ac5..15afd87 100644 --- a/include/libopencm3/lpc17xx/gpio.h +++ b/include/libopencm3/lpc17xx/gpio.h @@ -132,7 +132,11 @@ /* Overall interrupt status */ #define GPIO_IS MMIO32(GPIOINTERRPUT_BASE + 0x80) +BEGIN_DECLS + void gpio_set(u32 gpioport, u32 gpios); void gpio_clear(u32 gpioport, u32 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/lpc43xx/gpio.h b/include/libopencm3/lpc43xx/gpio.h index 8abd546..daa21fd 100644 --- a/include/libopencm3/lpc43xx/gpio.h +++ b/include/libopencm3/lpc43xx/gpio.h @@ -153,8 +153,12 @@ //TODO interrupts +BEGIN_DECLS + void gpio_set(u32 gpioport, u32 gpios); void gpio_clear(u32 gpioport, u32 gpios); void gpio_toggle(u32 gpioport, u32 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/lpc43xx/i2c.h b/include/libopencm3/lpc43xx/i2c.h index 249962c..b163af8 100644 --- a/include/libopencm3/lpc43xx/i2c.h +++ b/include/libopencm3/lpc43xx/i2c.h @@ -133,10 +133,14 @@ /* --- I2C funtion prototypes----------------------------------------------- */ +BEGIN_DECLS + void i2c0_init(void); void i2c0_tx_start(void); void i2c0_tx_byte(u8 byte); u8 i2c0_rx_byte(void); void i2c0_stop(void); +END_DECLS + #endif diff --git a/include/libopencm3/lpc43xx/nvic.h b/include/libopencm3/lpc43xx/nvic.h index b996ab8..cdbf070 100644 --- a/include/libopencm3/lpc43xx/nvic.h +++ b/include/libopencm3/lpc43xx/nvic.h @@ -134,6 +134,8 @@ /* --- NVIC functions ------------------------------------------------------ */ +BEGIN_DECLS + void nvic_enable_irq(u8 irqn); void nvic_disable_irq(u8 irqn); u8 nvic_get_pending_irq(u8 irqn); @@ -144,4 +146,6 @@ u8 nvic_get_irq_enabled(u8 irqn); void nvic_set_priority(u8 irqn, u8 priority); void nvic_generate_software_interrupt(u8 irqn); +END_DECLS + #endif diff --git a/include/libopencm3/lpc43xx/scu.h b/include/libopencm3/lpc43xx/scu.h index 6e1be7f..c1b9fc2 100644 --- a/include/libopencm3/lpc43xx/scu.h +++ b/include/libopencm3/lpc43xx/scu.h @@ -725,6 +725,10 @@ typedef enum { #define SCU_UART_RX_TX (SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EPD_EN_PULLDOWN | SCU_CONF_EZI_EN_IN_BUFFER) #define SCU_SSP_IO (SCU_CONF_EPUN_DIS_PULLUP | SCU_CONF_EHS_FAST | SCU_CONF_EZI_EN_IN_BUFFER | SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +BEGIN_DECLS + void scu_pinmux(scu_grp_pin_t group_pin, u32 scu_conf); +END_DECLS + #endif diff --git a/include/libopencm3/lpc43xx/ssp.h b/include/libopencm3/lpc43xx/ssp.h index ed69668..b3d95db 100644 --- a/include/libopencm3/lpc43xx/ssp.h +++ b/include/libopencm3/lpc43xx/ssp.h @@ -157,6 +157,8 @@ typedef enum { SSP_SLAVE_OUT_DISABLE = BIT3 } ssp_slave_option_t; /* This option is relevant only in slave mode */ +BEGIN_DECLS + void ssp_disable(ssp_num_t ssp_num); /* @@ -178,4 +180,6 @@ u16 ssp_read(ssp_num_t ssp_num); void ssp_write(ssp_num_t ssp_num, u16 data); +END_DECLS + #endif diff --git a/include/libopencm3/lpc43xx/systick.h b/include/libopencm3/lpc43xx/systick.h index 9f8b38d..2ae52c2 100644 --- a/include/libopencm3/lpc43xx/systick.h +++ b/include/libopencm3/lpc43xx/systick.h @@ -70,6 +70,8 @@ /* --- Function Prototypes ------------------------------------------------- */ +BEGIN_DECLS + void systick_set_reload(u32 value); u32 systick_get_value(void); void systick_set_clocksource(u8 clocksource); @@ -81,4 +83,6 @@ u8 systick_get_countflag(void); u32 systick_get_calib(void); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/can.h b/include/libopencm3/stm32/can.h index 0a05798..d6636d5 100644 --- a/include/libopencm3/stm32/can.h +++ b/include/libopencm3/stm32/can.h @@ -615,6 +615,8 @@ /* --- CAN functions -------------------------------------------------------- */ +BEGIN_DECLS + void can_reset(u32 canport); int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart, bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp); @@ -639,4 +641,6 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext, void can_fifo_release(u32 canport, u8 fifo); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/crc.h b/include/libopencm3/stm32/crc.h index 7d80259..3848191 100644 --- a/include/libopencm3/stm32/crc.h +++ b/include/libopencm3/stm32/crc.h @@ -53,6 +53,8 @@ /* --- CRC function prototypes --------------------------------------------- */ +BEGIN_DECLS + /* TODO */ /** @@ -75,4 +77,6 @@ u32 crc_calculate(u32 data); */ u32 crc_calculate_block(u32 *datap, int size); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/dac.h b/include/libopencm3/stm32/dac.h index 3a57132..75d4edb 100644 --- a/include/libopencm3/stm32/dac.h +++ b/include/libopencm3/stm32/dac.h @@ -393,6 +393,8 @@ typedef enum { /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void dac_enable(data_channel dac_channel); void dac_disable(data_channel dac_channel); void dac_buffer_enable(data_channel dac_channel); @@ -409,6 +411,8 @@ void dac_load_data_buffer_single(u32 dac_data, data_align dac_data_format, data_ void dac_load_data_buffer_dual(u32 dac_data1, u32 dac_data2, data_align dac_data_format); void dac_software_trigger(data_channel dac_channel); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/exti.h b/include/libopencm3/stm32/exti.h index d1935ad..7645825 100644 --- a/include/libopencm3/stm32/exti.h +++ b/include/libopencm3/stm32/exti.h @@ -61,10 +61,14 @@ typedef enum trigger_e { EXTI_TRIGGER_BOTH, } exti_trigger_type; +BEGIN_DECLS + void exti_set_trigger(u32 extis, exti_trigger_type trig); void exti_enable_request(u32 extis); void exti_disable_request(u32 extis); void exti_reset_request(u32 extis); void exti_select_source(u32 exti, u32 gpioport); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f1/adc.h b/include/libopencm3/stm32/f1/adc.h index 563e75d..f13b7c7 100644 --- a/include/libopencm3/stm32/f1/adc.h +++ b/include/libopencm3/stm32/f1/adc.h @@ -485,6 +485,7 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS /* TODO */ void adc_enable_analog_watchdog_regular(u32 adc); @@ -532,4 +533,6 @@ void adc_set_watchdog_low_threshold(u32 adc, u16 threshold); void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]); void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f1/desig.h b/include/libopencm3/stm32/f1/desig.h index 743e946..74cfb35 100644 --- a/include/libopencm3/stm32/f1/desig.h +++ b/include/libopencm3/stm32/f1/desig.h @@ -36,6 +36,8 @@ #define DESIG_UID_63_32 MMIO32(DESIG_UNIQUE_ID_BASE + 0x04) #define DESIG_UID_95_64 MMIO32(DESIG_UNIQUE_ID_BASE + 0x08) +BEGIN_DECLS + /** * Read the onboard flash size * @return flash size in KB @@ -49,4 +51,6 @@ u16 desig_get_flash_size(void); */ void desig_get_unique_id(u32 result[]); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f1/dma.h b/include/libopencm3/stm32/f1/dma.h index 64eafe0..b08803f 100644 --- a/include/libopencm3/stm32/f1/dma.h +++ b/include/libopencm3/stm32/f1/dma.h @@ -346,6 +346,8 @@ LGPL License Terms @ref lgpl_license /* --- function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void dma_channel_reset(u32 dma, u8 channel); void dma_enable_mem2mem_mode(u32 dma, u8 channel); void dma_set_priority(u32 dma, u8 channel, u32 prio); @@ -368,6 +370,8 @@ void dma_set_peripheral_address(u32 dma, u8 channel, u32 address); void dma_set_memory_address(u32 dma, u8 channel, u32 address); void dma_set_number_of_data(u32 dma, u8 channel, u16 number); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/f1/flash.h b/include/libopencm3/stm32/f1/flash.h index 2c026d6..919b4d4 100644 --- a/include/libopencm3/stm32/f1/flash.h +++ b/include/libopencm3/stm32/f1/flash.h @@ -89,6 +89,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void flash_prefetch_buffer_enable(void); void flash_prefetch_buffer_disable(void); void flash_halfcycle_enable(void); @@ -110,4 +112,6 @@ void flash_wait_for_last_operation(void); void flash_erase_option_bytes(void); void flash_program_option_bytes(u32 address, u16 data); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f1/gpio.h b/include/libopencm3/stm32/f1/gpio.h index 2f4292a..a1e74cc 100644 --- a/include/libopencm3/stm32/f1/gpio.h +++ b/include/libopencm3/stm32/f1/gpio.h @@ -950,6 +950,8 @@ Line Devices only /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios); void gpio_set(u32 gpioport, u16 gpios); void gpio_clear(u32 gpioport, u16 gpios); @@ -962,6 +964,8 @@ void gpio_set_eventout(u8 evoutport, u8 evoutpin); void gpio_primary_remap(u8 swjenable, u32 maps); void gpio_secondary_remap(u32 maps); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/f1/rcc.h b/include/libopencm3/stm32/f1/rcc.h index 63f6770..855e43b 100644 --- a/include/libopencm3/stm32/f1/rcc.h +++ b/include/libopencm3/stm32/f1/rcc.h @@ -476,6 +476,8 @@ typedef enum { PLL, HSE, HSI, LSE, LSI } osc_t; +BEGIN_DECLS + void rcc_osc_ready_int_clear(osc_t osc); void rcc_osc_ready_int_enable(osc_t osc); void rcc_osc_ready_int_disable(osc_t osc); @@ -512,6 +514,8 @@ void rcc_clock_setup_in_hse_12mhz_out_72mhz(void); void rcc_clock_setup_in_hse_16mhz_out_72mhz(void); void rcc_backupdomain_reset(void); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/f1/rtc.h b/include/libopencm3/stm32/f1/rtc.h index 5e203ab..04aea01 100644 --- a/include/libopencm3/stm32/f1/rtc.h +++ b/include/libopencm3/stm32/f1/rtc.h @@ -126,6 +126,8 @@ typedef enum { RTC_SEC, RTC_ALR, RTC_OW, } rtcflag_t; +BEGIN_DECLS + void rtc_awake_from_off(osc_t clock_source); void rtc_enter_config_mode(void); void rtc_exit_config_mode(void); @@ -144,4 +146,6 @@ u32 rtc_check_flag(rtcflag_t flag_val); void rtc_awake_from_standby(void); void rtc_auto_awake(osc_t clock_source, u32 prescale_val); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f1/scb.h b/include/libopencm3/stm32/f1/scb.h index 12a74a2..181aa7a 100644 --- a/include/libopencm3/stm32/f1/scb.h +++ b/include/libopencm3/stm32/f1/scb.h @@ -293,10 +293,15 @@ /* BFAR [31:0]: Bus fault address */ /* --- SCB functions ------------------------------------------------------- */ + +BEGIN_DECLS + void scb_reset_core(void); void scb_reset_system(void); void scb_set_priority_grouping(u32 prigroup); /* TODO: */ +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f2/flash.h b/include/libopencm3/stm32/f2/flash.h index 5b4483f..2c78757 100644 --- a/include/libopencm3/stm32/f2/flash.h +++ b/include/libopencm3/stm32/f2/flash.h @@ -116,6 +116,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void flash_dcache_enable(void); void flash_dcache_disable(void); void flash_icache_enable(void); @@ -145,4 +147,6 @@ void flash_program_byte(u32 address, u8 data, u32 program_size); void flash_wait_for_last_operation(void); void flash_program_option_bytes(u32 data); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f2/gpio.h b/include/libopencm3/stm32/f2/gpio.h index 1a9fd0f..6616769 100644 --- a/include/libopencm3/stm32/f2/gpio.h +++ b/include/libopencm3/stm32/f2/gpio.h @@ -254,6 +254,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + /* * Note: The F2 series has a completely new GPIO peripheral with different * configuration options. Here we implement a different API partly to more @@ -275,4 +277,6 @@ u16 gpio_port_read(u32 gpioport); void gpio_port_write(u32 gpioport, u16 data); void gpio_port_config_lock(u32 gpioport, u16 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f2/rcc.h b/include/libopencm3/stm32/f2/rcc.h index dfce266..4ffa242 100644 --- a/include/libopencm3/stm32/f2/rcc.h +++ b/include/libopencm3/stm32/f2/rcc.h @@ -479,6 +479,8 @@ typedef enum { PLL, HSE, HSI, LSE, LSI } osc_t; +BEGIN_DECLS + void rcc_osc_ready_int_clear(osc_t osc); void rcc_osc_ready_int_enable(osc_t osc); void rcc_osc_ready_int_disable(osc_t osc); @@ -509,4 +511,6 @@ u32 rcc_get_system_clock_source(int i); void rcc_clock_setup_hse_3v3(const clock_scale_t *clock); void rcc_backupdomain_reset(void); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f2/scb.h b/include/libopencm3/stm32/f2/scb.h index 12a74a2..181aa7a 100644 --- a/include/libopencm3/stm32/f2/scb.h +++ b/include/libopencm3/stm32/f2/scb.h @@ -293,10 +293,15 @@ /* BFAR [31:0]: Bus fault address */ /* --- SCB functions ------------------------------------------------------- */ + +BEGIN_DECLS + void scb_reset_core(void); void scb_reset_system(void); void scb_set_priority_grouping(u32 prigroup); /* TODO: */ +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f2/timer.h b/include/libopencm3/stm32/f2/timer.h index 3436bba..737d6f0 100644 --- a/include/libopencm3/stm32/f2/timer.h +++ b/include/libopencm3/stm32/f2/timer.h @@ -52,6 +52,10 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void timer_set_option(u32 timer_peripheral, u32 option); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/flash.h b/include/libopencm3/stm32/f4/flash.h index f85d56f..2221333 100644 --- a/include/libopencm3/stm32/f4/flash.h +++ b/include/libopencm3/stm32/f4/flash.h @@ -115,6 +115,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void flash_dcache_enable(void); void flash_dcache_disable(void); void flash_icache_enable(void); @@ -144,4 +146,6 @@ void flash_program_byte(u32 address, u8 data, u32 program_size); void flash_wait_for_last_operation(void); void flash_program_option_bytes(u32 data); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/gpio.h b/include/libopencm3/stm32/f4/gpio.h index a5b4361..b7da9c6 100644 --- a/include/libopencm3/stm32/f4/gpio.h +++ b/include/libopencm3/stm32/f4/gpio.h @@ -254,6 +254,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + /* * Note: The F4 series has a completely new GPIO peripheral with different * configuration options. Here we implement a different API partly to more @@ -275,4 +277,6 @@ u16 gpio_port_read(u32 gpioport); void gpio_port_write(u32 gpioport, u16 data); void gpio_port_config_lock(u32 gpioport, u16 gpios); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/pwr.h b/include/libopencm3/stm32/f4/pwr.h index ede1ae7..25fb163 100644 --- a/include/libopencm3/stm32/f4/pwr.h +++ b/include/libopencm3/stm32/f4/pwr.h @@ -63,6 +63,10 @@ typedef enum { SCALE2, } vos_scale_t; +BEGIN_DECLS + void pwr_set_vos_scale(vos_scale_t scale); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/rcc.h b/include/libopencm3/stm32/f4/rcc.h index 648ccb0..1688584 100644 --- a/include/libopencm3/stm32/f4/rcc.h +++ b/include/libopencm3/stm32/f4/rcc.h @@ -482,6 +482,8 @@ typedef enum { PLL, HSE, HSI, LSE, LSI } osc_t; +BEGIN_DECLS + void rcc_osc_ready_int_clear(osc_t osc); void rcc_osc_ready_int_enable(osc_t osc); void rcc_osc_ready_int_disable(osc_t osc); @@ -512,4 +514,6 @@ u32 rcc_get_system_clock_source(int i); void rcc_clock_setup_hse_3v3(const clock_scale_t *clock); void rcc_backupdomain_reset(void); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/scb.h b/include/libopencm3/stm32/f4/scb.h index 12a74a2..181aa7a 100644 --- a/include/libopencm3/stm32/f4/scb.h +++ b/include/libopencm3/stm32/f4/scb.h @@ -293,10 +293,15 @@ /* BFAR [31:0]: Bus fault address */ /* --- SCB functions ------------------------------------------------------- */ + +BEGIN_DECLS + void scb_reset_core(void); void scb_reset_system(void); void scb_set_priority_grouping(u32 prigroup); /* TODO: */ +END_DECLS + #endif diff --git a/include/libopencm3/stm32/f4/timer.h b/include/libopencm3/stm32/f4/timer.h index 6d19990..988d02c 100644 --- a/include/libopencm3/stm32/f4/timer.h +++ b/include/libopencm3/stm32/f4/timer.h @@ -52,6 +52,10 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void timer_set_option(u32 timer_peripheral, u32 option); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/i2c.h b/include/libopencm3/stm32/i2c.h index 1606b64..13257eb 100644 --- a/include/libopencm3/stm32/i2c.h +++ b/include/libopencm3/stm32/i2c.h @@ -316,6 +316,8 @@ /* --- I2C funtion prototypes----------------------------------------------- */ +BEGIN_DECLS + void i2c_reset(u32 i2c); void i2c_peripheral_enable(u32 i2c); void i2c_peripheral_disable(u32 i2c); @@ -331,4 +333,6 @@ void i2c_set_trise(u32 i2c, u16 trise); void i2c_send_7bit_address(u32 i2c, u8 slave, u8 readwrite); void i2c_send_data(u32 i2c, u8 data); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/iwdg.h b/include/libopencm3/stm32/iwdg.h index a5f1ac1..4e44907 100644 --- a/include/libopencm3/stm32/iwdg.h +++ b/include/libopencm3/stm32/iwdg.h @@ -106,12 +106,16 @@ LGPL License Terms @ref lgpl_license /* --- IWDG function prototypes---------------------------------------------- */ +BEGIN_DECLS + void iwdg_start(void); void iwdg_set_period_ms(u32 period); bool iwdg_reload_busy(void); bool iwdg_prescaler_busy(void); void iwdg_reset(void); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h index 6a98737..d6dfa35 100644 --- a/include/libopencm3/stm32/nvic.h +++ b/include/libopencm3/stm32/nvic.h @@ -116,6 +116,8 @@ IRQ numbers -3 and -6 to -9 are reserved /* --- NVIC functions ------------------------------------------------------ */ +BEGIN_DECLS + void nvic_enable_irq(u8 irqn); void nvic_disable_irq(u8 irqn); u8 nvic_get_pending_irq(u8 irqn); @@ -126,6 +128,8 @@ u8 nvic_get_irq_enabled(u8 irqn); void nvic_set_priority(u8 irqn, u8 priority); void nvic_generate_software_interrupt(u16 irqn); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/pwr.h b/include/libopencm3/stm32/pwr.h index 7084382..e709f3d 100644 --- a/include/libopencm3/stm32/pwr.h +++ b/include/libopencm3/stm32/pwr.h @@ -106,6 +106,8 @@ LGPL License Terms @ref lgpl_license /* --- PWR function prototypes ------------------------------------------- */ +BEGIN_DECLS + void pwr_disable_backup_domain_write_protect(void); void pwr_enable_backup_domain_write_protect(void); void pwr_enable_power_voltage_detect(u32 pvd_level); @@ -122,6 +124,8 @@ bool pwr_voltage_high(void); bool pwr_get_standby_flag(void); bool pwr_get_wakeup_flag(void); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/spi.h b/include/libopencm3/stm32/spi.h index e64dd0f..11ba820 100644 --- a/include/libopencm3/stm32/spi.h +++ b/include/libopencm3/stm32/spi.h @@ -297,6 +297,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void spi_reset(u32 spi_peripheral); int spi_init_master(u32 spi, u32 br, u32 cpol, u32 cpha, u32 dff, u32 lsbfirst); void spi_enable(u32 spi); @@ -343,4 +345,6 @@ void spi_disable_tx_dma(u32 spi); void spi_enable_rx_dma(u32 spi); void spi_disable_rx_dma(u32 spi); +END_DECLS + #endif diff --git a/include/libopencm3/stm32/systick.h b/include/libopencm3/stm32/systick.h index aa6c287..e42c4e6 100644 --- a/include/libopencm3/stm32/systick.h +++ b/include/libopencm3/stm32/systick.h @@ -93,6 +93,8 @@ LGPL License Terms @ref lgpl_license /* --- Function Prototypes ------------------------------------------------- */ +BEGIN_DECLS + void systick_set_reload(u32 value); u32 systick_get_value(void); void systick_set_clocksource(u8 clocksource); @@ -102,6 +104,8 @@ void systick_counter_enable(void); void systick_counter_disable(void); u8 systick_get_countflag(void); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/timer.h b/include/libopencm3/stm32/timer.h index b1e1064..b6f8949 100644 --- a/include/libopencm3/stm32/timer.h +++ b/include/libopencm3/stm32/timer.h @@ -1022,6 +1022,9 @@ enum tim_ic_pol { }; /* --- TIM function prototypes ------------------------------------------------------- */ + +BEGIN_DECLS + void timer_reset(u32 timer_peripheral); void timer_enable_irq(u32 timer_peripheral, u32 irq); void timer_disable_irq(u32 timer_peripheral, u32 irq); @@ -1101,6 +1104,8 @@ void timer_slave_set_polarity(u32 timer, enum tim_ic_pol pol); void timer_slave_set_mode(u32 timer, u8 mode); void timer_slave_set_trigger(u32 timer, u8 trigger); +END_DECLS + #endif /**@}*/ diff --git a/include/libopencm3/stm32/usart.h b/include/libopencm3/stm32/usart.h index 5c7f285..9ec6c3d 100644 --- a/include/libopencm3/stm32/usart.h +++ b/include/libopencm3/stm32/usart.h @@ -294,6 +294,8 @@ /* --- Function prototypes ------------------------------------------------- */ +BEGIN_DECLS + void usart_set_baudrate(u32 usart, u32 baud); void usart_set_databits(u32 usart, u32 bits); void usart_set_stopbits(u32 usart, u32 stopbits); @@ -313,4 +315,6 @@ void usart_disable_rx_dma(u32 usart); void usart_enable_tx_dma(u32 usart); void usart_disable_tx_dma(u32 usart); +END_DECLS + #endif diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index f453bc2..e4b3578 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -22,6 +22,8 @@ #include +BEGIN_DECLS + typedef struct _usbd_driver usbd_driver; extern const usbd_driver stm32f103_usb_driver; extern const usbd_driver stm32f107_usb_driver; @@ -73,4 +75,6 @@ extern void usbd_ep_nak_set(u8 addr, u8 nak); /* Optional */ extern void usbd_cable_connect(u8 on); +END_DECLS + #endif -- cgit v1.2.3 From 5ad8f26ede984cbf820707a11e1ddbc8ea52d06b Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 2 Sep 2012 17:15:13 +0200 Subject: Fix comments typo --- include/libopencm3/lpc43xx/i2c.h | 2 +- include/libopencm3/stm32/sdio.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/libopencm3/stm32') diff --git a/include/libopencm3/lpc43xx/i2c.h b/include/libopencm3/lpc43xx/i2c.h index b163af8..29e797e 100644 --- a/include/libopencm3/lpc43xx/i2c.h +++ b/include/libopencm3/lpc43xx/i2c.h @@ -131,7 +131,7 @@ #define I2C_WRITE 0 #define I2C_READ 1 -/* --- I2C funtion prototypes----------------------------------------------- */ +/* --- I2C function prototypes --------------------------------------------- */ BEGIN_DECLS diff --git a/include/libopencm3/stm32/sdio.h b/include/libopencm3/stm32/sdio.h index cf9b056..16244ed 100644 --- a/include/libopencm3/stm32/sdio.h +++ b/include/libopencm3/stm32/sdio.h @@ -142,7 +142,7 @@ #define SDIO_CMD_WAITRESP_SHIFT 6 /* 00: No response, expect CMDSENT flag */ #define SDIO_CMD_WAITRESP_NO_0 (0x0 << SDIO_CMD_WAITRESP_SHIFT) -/* 01: Short response, expect CMDREND or CCRCFAIL flag +/* 01: Short response, expect CMDREND or CCRCFAIL flag */ #define SDIO_CMD_WAITRESP_SHORT (0x1 << SDIO_CMD_WAITRESP_SHIFT) /* 10: No response, expect CMDSENT flag */ #define SDIO_CMD_WAITRESP_NO_2 (0x2 << SDIO_CMD_WAITRESP_SHIFT) -- cgit v1.2.3