aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/stm32/can.c148
-rw-r--r--lib/stm32/common/gpio_common_all.c139
-rw-r--r--lib/stm32/common/gpio_common_f24.c195
-rw-r--r--lib/stm32/f1/Makefile5
-rw-r--r--lib/stm32/f1/adc.c114
-rw-r--r--lib/stm32/f1/dma.c6
-rw-r--r--lib/stm32/f1/gpio.c138
-rw-r--r--lib/stm32/f2/Makefile7
-rw-r--r--lib/stm32/f2/gpio.c28
-rw-r--r--lib/stm32/f4/Makefile7
-rw-r--r--lib/stm32/f4/gpio.c28
-rw-r--r--lib/stm32/gpio2.c150
-rw-r--r--lib/stm32/l1/Makefile5
-rw-r--r--lib/stm32/l1/gpio.c28
14 files changed, 644 insertions, 354 deletions
diff --git a/lib/stm32/can.c b/lib/stm32/can.c
index 3ee86c3..7fde585 100644
--- a/lib/stm32/can.c
+++ b/lib/stm32/can.c
@@ -1,3 +1,21 @@
+/** @defgroup can_file CAN
+
+@ingroup STM32F_files
+
+@brief <b>libopencm3 STM32Fxxx CAN</b>
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2010 Piotr Esden-Tempski <piotr@esden.net>
+
+@date 12 November 2012
+
+Devices can have up to two CAN peripherals. The peripherals support up to 1MBit
+transmission rate. The peripheral has several filters for incoming messages that
+can be distributed between two FIFOs and three transmit mailboxes.
+
+LGPL License Terms @ref lgpl_license
+*/
/*
* This file is part of the libopencm3 project.
*
@@ -29,6 +47,14 @@
# error "stm32 family not defined."
#endif
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Reset
+
+The CAN peripheral and all its associated configuration registers are placed in the
+reset condition. The reset is effective via the RCC peripheral reset system.
+
+@param[in] canport Unsigned int32. CAN block register address base @ref can_reg_base.
+ */
void can_reset(u32 canport)
{
if (canport == CAN1) {
@@ -40,6 +66,24 @@ void can_reset(u32 canport)
}
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Init
+
+Initialize the selected CAN peripheral block.
+
+@param[in] canport Unsigend int32. CAN register base address @ref can_reg_base.
+@param[in] ttcm bool. Time triggered communication mode.
+@param[in] abom bool. Automatic bus-off management.
+@param[in] awum bool. Automatic wakeup mode.
+@param[in] nart bool. No automatic retransmission.
+@param[in] rflm bool. Receive FIFO locked mode.
+@param[in] txfp bool. Transmit FIFO priority.
+@param[in] sjw Unsigned int32. Resynchronization time quanta jump width.
+@param[in] ts1 Unsigned int32. Time segment 1 time quanta width.
+@param[in] ts2 Unsigned int32. Time segment 2 time quanta width.
+@param[in] brp Unsigned int32. Baud rate prescaler.
+@returns int 0 on success, 1 on initialization failure.
+*/
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,
bool loopback, bool silent)
@@ -129,6 +173,20 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
return ret;
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Filter Init
+
+Initialize incoming message filter and assign to FIFO.
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] nr Unsigned int32. ID number of the filter.
+@param[in] scale_32bit bool. 32-bit scale for the filter?
+@param[in] id_list_mode bool. ID list filter mode?
+@param[in] fr1 Unsigned int32. First filter register content.
+@param[in] fr2 Unsigned int32. Second filter register content.
+@param[in] fifo Unsigned int32. FIFO id.
+@param[in] enable bool. Enable filter?
+ */
void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode,
u32 fr1, u32 fr2, u32 fifo, bool enable)
{
@@ -175,6 +233,18 @@ void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode,
CAN_FMR(canport) &= ~CAN_FMR_FINIT;
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Initialize a 16bit Message ID Mask Filter
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] nr Unsigned int32. ID number of the filter.
+@param[in] id1 Unsigned int16. First message ID to filter.
+@param[in] mask1 Unsigned int16. First message ID bit mask.
+@param[in] id2 Unsigned int16. Second message ID to filter.
+@param[in] mask2 Unsigned int16. Second message ID bit mask.
+@param[in] fifo Unsigned int32. FIFO id.
+@param[in] enable bool. Enable filter?
+ */
void can_filter_id_mask_16bit_init(u32 canport, u32 nr, u16 id1, u16 mask1,
u16 id2, u16 mask2, u32 fifo, bool enable)
{
@@ -183,12 +253,34 @@ void can_filter_id_mask_16bit_init(u32 canport, u32 nr, u16 id1, u16 mask1,
((u32)id2 << 16) | (u32)mask2, fifo, enable);
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Initialize a 32bit Message ID Mask Filter
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] nr Unsigned int32. ID number of the filter.
+@param[in] id Unsigned int32. Message ID to filter.
+@param[in] mask Unsigned int32. Message ID bit mask.
+@param[in] fifo Unsigned int32. FIFO id.
+@param[in] enable bool. Enable filter?
+ */
void can_filter_id_mask_32bit_init(u32 canport, u32 nr, u32 id, u32 mask,
u32 fifo, bool enable)
{
can_filter_init(canport, nr, true, false, id, mask, fifo, enable);
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Initialize a 16bit Message ID List Filter
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] nr Unsigned int32. ID number of the filter.
+@param[in] id1 Unsigned int16. First message ID to match.
+@param[in] id2 Unsigned int16. Second message ID to match.
+@param[in] id3 Unsigned int16. Third message ID to match.
+@param[in] id4 Unsigned int16. Fourth message ID to match.
+@param[in] fifo Unsigned int32. FIFO id.
+@param[in] enable bool. Enable filter?
+ */
void can_filter_id_list_16bit_init(u32 canport, u32 nr, u16 id1, u16 id2,
u16 id3, u16 id4, u32 fifo, bool enable)
{
@@ -197,27 +289,62 @@ void can_filter_id_list_16bit_init(u32 canport, u32 nr, u16 id1, u16 id2,
((u32)id3 << 16) | (u32)id4, fifo, enable);
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Initialize a 32bit Message ID List Filter
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] nr Unsigned int32. ID number of the filter.
+@param[in] id1 Unsigned int32. First message ID to match.
+@param[in] id2 Unsigned int32. Second message ID to match.
+@param[in] fifo Unsigned int32. FIFO id.
+@param[in] enable bool. Enable filter?
+ */
void can_filter_id_list_32bit_init(u32 canport, u32 nr, u32 id1, u32 id2,
u32 fifo, bool enable)
{
can_filter_init(canport, nr, true, true, id1, id2, fifo, enable);
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Enable IRQ
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] irq Unsigned int32. IRQ bit(s).
+ */
void can_enable_irq(u32 canport, u32 irq)
{
CAN_IER(canport) |= irq;
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Disable IRQ
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] irq Unsigned int32. IRQ bit(s).
+ */
void can_disable_irq(u32 canport, u32 irq)
{
CAN_IER(canport) &= ~irq;
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Transmit Message
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] id Unsigned int32. Message ID.
+@param[in] ext bool. Extended message ID?
+@param[in] rtr bool. Request transmit?
+@param[in] length Unsigned int8. Message payload length.
+@param[in] data Unsigned int8[]. Message payload data.
+@returns int 0, 1 or 2 on success and depending on which outgoing mailbox got
+selected. -1 if no mailbox was available and no transmission got queued.
+ */
int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data)
{
int ret = 0, i;
u32 mailbox = 0;
+ /* Check which transmit mailbox is empty if any. */
if ((CAN_TSR(canport) & CAN_TSR_TME0) == CAN_TSR_TME0) {
ret = 0;
mailbox = CAN_MBOX0;
@@ -231,7 +358,7 @@ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data)
ret = -1;
}
- /* Check if we have an empty mailbox. */
+ /* If we have no empty mailbox return with an error. */
if (ret == -1)
return ret;
@@ -269,6 +396,12 @@ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data)
return ret;
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Release FIFO
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] fifo Unsigned int8. FIFO id.
+ */
void can_fifo_release(u32 canport, u8 fifo)
{
if (fifo == 0)
@@ -277,6 +410,19 @@ void can_fifo_release(u32 canport, u8 fifo)
CAN_RF1R(canport) |= CAN_RF1R_RFOM1;
}
+/*-----------------------------------------------------------------------------*/
+/** @brief CAN Receive Message
+
+@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base.
+@param[in] fifo Unsigned int8. FIFO id.
+@param[in] release bool. Release the FIFO automatically after coping data out.
+@param[out] id Unsigned int32 pointer. Message ID.
+@param[out] ext bool pointer. The message ID is extended?
+@param[out] rtr bool pointer. Request of transmission?
+@param[out] fmi Unsigned int32 pointer. ID of the matched filter.
+@param[out] length Unsigned int8 pointer. Length of message payload.
+@param[out] data Unsigned int8[]. Message payload data.
+ */
void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
bool *rtr, u32 *fmi, u8 *length, u8 *data)
{
diff --git a/lib/stm32/common/gpio_common_all.c b/lib/stm32/common/gpio_common_all.c
new file mode 100644
index 0000000..d23e415
--- /dev/null
+++ b/lib/stm32/common/gpio_common_all.c
@@ -0,0 +1,139 @@
+/** @addtogroup gpio_file */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define WEAK __attribute__ ((weak))
+
+#include <libopencm3/stm32/gpio.h>
+
+/**@{*/
+
+/*-----------------------------------------------------------------------------*/
+/** @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;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @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_BSRR(gpioport) = (gpios << 16);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @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;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @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;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @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);
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @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;
+
+ /* Special "Lock Key Writing Sequence", see datasheet. */
+ GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
+ GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */
+ GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
+ reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */
+ reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */
+
+ /* Tell the compiler the variable is actually used. It will get optimized out anyways. */
+ reg32 = reg32;
+
+ /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */
+}
+
+/**@}*/
+
diff --git a/lib/stm32/common/gpio_common_f24.c b/lib/stm32/common/gpio_common_f24.c
new file mode 100644
index 0000000..d464a50
--- /dev/null
+++ b/lib/stm32/common/gpio_common_f24.c
@@ -0,0 +1,195 @@
+/** @addtogroup gpio_file
+
+@version 1.0.0
+
+@author @htmlonly &copy; @endhtmlonly 2009 Uwe Hermann <uwe@hermann-uwe.de>
+@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net>
+
+@date 18 August 2012
+
+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 with pullup on ports C2 and C9
+
+@code
+ gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT,
+ GPIO_PUPD_PULLUP, GPIO2 | GPIO9);
+ gpio_output_options(GPIOC, GPIO_OTYPE_PP,
+ GPIO_OSPEED_25MHZ, GPIO2 | GPIO9);
+ gpio_set(GPIOC, GPIO2 | GPIO9);
+ gpio_clear(GPIOC, GPIO2);
+ gpio_toggle(GPIOC, GPIO2 | GPIO9);
+ gpio_port_write(GPIOC, 0x204);
+@endcode
+
+Example 2: Digital input on port C12 with pullup
+
+@code
+ gpio_mode_setup(GPIOC, GPIO_MODE_INPUT,
+ GPIO_PUPD_PULLUP, GPIO12);
+ reg16 = gpio_port_read(GPIOC);
+@endcode
+
+LGPL License Terms @ref lgpl_license
+*/
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**@{*/
+
+#include <libopencm3/stm32/common/gpio_common_all.h>
+#include <libopencm3/stm32/gpio.h>
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Set GPIO Pin Mode
+
+Sets the Pin Direction and Analog/Digital Mode, and Output Pin Pullup,
+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] pull_up_down Unsigned int8. Pin pullup/pulldown configuration @ref gpio_pup
+@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
+ If multiple pins are to be set, use bitwise OR '|' to separate them.
+*/
+void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios)
+{
+ u16 i;
+ u32 moder, pupd;
+
+ /*
+ * We want to set the config only for the pins mentioned in gpios,
+ * but keeping the others, so read out the actual config first.
+ */
+ moder = GPIO_MODER(gpioport);
+ pupd = GPIO_PUPDR(gpioport);
+
+ for (i = 0; i < 16; i++) {
+ if (!((1 << i) & gpios))
+ continue;
+
+ moder &= ~GPIO_MODE_MASK(i);
+ moder |= GPIO_MODE(i, mode);
+ pupd &= ~GPIO_PUPD_MASK(i);
+ pupd |= GPIO_PUPD(i, pull_up_down);
+ }
+
+ /* Set mode and pull up/down control registers. */
+ GPIO_MODER(gpioport) = moder;
+ GPIO_PUPDR(gpioport) = pupd;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Set GPIO Output Options
+
+When the pin is set to output mode, this sets the configuration (analog/digital and
+open drain/push pull) and speed, for a set of GPIO pins on a given GPIO port.
+
+@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
+@param[in] otype Unsigned int8. Pin output type @ref gpio_output_type
+@param[in] speed Unsigned int8. Pin speed @ref gpio_speed
+@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
+ If multiple pins are to be set, use bitwise OR '|' to separate them.
+*/
+void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios)
+{
+ u16 i;
+ u32 ospeedr;
+
+ if (otype == 0x1)
+ GPIO_OTYPER(gpioport) |= gpios;
+ else
+ GPIO_OTYPER(gpioport) &= ~gpios;
+
+ ospeedr = GPIO_OSPEEDR(gpioport);
+
+ for (i = 0; i < 16; i++) {
+ if (!((1 << i) & gpios))
+ continue;
+ ospeedr &= ~GPIO_OSPEED_MASK(i);
+ ospeedr |= GPIO_OSPEED(i, speed);
+ }
+
+ GPIO_OSPEEDR(gpioport) = ospeedr;
+}
+
+/*-----------------------------------------------------------------------------*/
+/** @brief Set GPIO Alternate Function Selection
+
+Set the alternate function mapping number for each pin. Most pins have alternate
+functions associated with them. When set to AF mode, a pin may be used for one of
+its allocated alternate functions selected by the number given here. To determine
+the number to be used for the desired function refer to the individual datasheet
+for the particular device. A table is given under the Pin Selection chapter.
+
+Note that a number of pins may be set but only with a single AF number. In practice
+this would rarely be useful as each pin is likely to require a different number.
+
+@param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
+@param[in] alt_func_num Unsigned int8. Pin alternate function number @ref gpio_af_num
+@param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
+ If multiple pins are to be set, use bitwise OR '|' to separate them.
+*/
+void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios)
+{
+ u16 i;
+ u32 afrl, afrh;
+
+ afrl = GPIO_AFRL(gpioport);
+ afrh = GPIO_AFRH(gpioport);
+
+ for (i = 0; i < 8; i++) {
+ if (!((1 << i) & gpios))
+ continue;
+ afrl &= ~GPIO_AFR_MASK(i);
+ afrl |= GPIO_AFR(i, alt_func_num);
+ }
+
+ for (i = 8; i < 16; i++) {
+ if (!((1 << i) & gpios))
+ continue;
+ afrl &= ~GPIO_AFR_MASK(i - 8);
+ afrh |= GPIO_AFR(i - 8, alt_func_num);
+ }
+
+ GPIO_AFRL(gpioport) = afrl;
+ GPIO_AFRH(gpioport) = afrh;
+}
+/**@}*/
+
diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile
index ed8ae29..2572554 100644
--- a/lib/stm32/f1/Makefile
+++ b/lib/stm32/f1/Makefile
@@ -32,9 +32,10 @@ OBJS = rcc.o gpio.o usart.o adc.o spi.o flash.o \
rtc.o i2c.o dma.o exti.o ethernet.o \
usb_f103.o usb.o usb_control.o usb_standard.o can.o \
timer.o usb_f107.o desig.o crc.o dac.o iwdg.o pwr.o \
- usb_fx07_common.o
+ usb_fx07_common.o \
+ gpio_common_all.o
-VPATH += ../../usb:../:../../cm3
+VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include
diff --git a/lib/stm32/f1/adc.c b/lib/stm32/f1/adc.c
index 0a05aac..71eb926 100644
--- a/lib/stm32/f1/adc.c
+++ b/lib/stm32/f1/adc.c
@@ -187,7 +187,7 @@ void adc_set_dual_mode(u32 mode)
This flag is set after all channels of a regular or injected group have been
converted.
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
@returns bool. End of conversion flag.
*/
@@ -201,7 +201,7 @@ bool adc_eoc(u32 adc)
This flag is set after all channels of an injected group have been converted.
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
@returns bool. End of conversion flag.
*/
@@ -217,7 +217,7 @@ The result read back is 12 bits, right or left aligned within the first 16 bits.
For ADC1 only, the higher 16 bits will hold the result from ADC2 if
an appropriate dual mode has been set @see adc_set_dual_mode.
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
@returns Unsigned int32 conversion result.
*/
@@ -233,7 +233,7 @@ The result read back from the selected injected result register (one of four) is
12 bits, right or left aligned within the first 16 bits. The result can have a
negative value if the injected channel offset has been set @see adc_set_injected_offset.
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] 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.
*/
@@ -260,7 +260,7 @@ This value is subtracted from the injected channel results after conversion
is complete, and can result in negative results. A separate value can be specified
for each injected data register.
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
@param[in] reg Unsigned int8. Register number (1 ... 4).
@param[in] offset Unsigned int32.
*/
@@ -290,7 +290,7 @@ 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.
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_analog_watchdog_regular(u32 adc)
@@ -301,7 +301,7 @@ void adc_enable_analog_watchdog_regular(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable Analog Watchdog for Regular Conversions
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_analog_watchdog_regular(u32 adc)
@@ -316,7 +316,7 @@ 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.
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_analog_watchdog_injected(u32 adc)
@@ -327,7 +327,7 @@ void adc_enable_analog_watchdog_injected(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable Analog Watchdog for Injected Conversions
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_analog_watchdog_injected(u32 adc)
@@ -346,8 +346,8 @@ 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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
+@param[in] length Unsigned int8. Number of channels in the group @ref adc_cr1_discnum.
*/
void adc_enable_discontinuous_mode_regular(u32 adc, u8 length)
@@ -360,7 +360,7 @@ void adc_enable_discontinuous_mode_regular(u32 adc, u8 length)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable Discontinuous Mode for Regular Conversions
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_discontinuous_mode_regular(u32 adc)
@@ -375,7 +375,7 @@ 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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_discontinuous_mode_injected(u32 adc)
@@ -386,7 +386,7 @@ void adc_enable_discontinuous_mode_injected(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable Discontinuous Mode for Injected Conversions
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_discontinuous_mode_injected(u32 adc)
@@ -413,7 +413,7 @@ void adc_enable_automatic_injected_group_conversion(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable Automatic Injected Conversions
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_automatic_injected_group_conversion(u32 adc)
@@ -433,7 +433,7 @@ 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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_analog_watchdog_on_all_channels(u32 adc)
@@ -453,8 +453,8 @@ 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
+@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)
@@ -475,7 +475,7 @@ 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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_scan_mode(u32 adc)
@@ -497,7 +497,7 @@ void adc_disable_scan_mode(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Enable Injected End-Of-Conversion Interrupt
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_eoc_interrupt_injected(u32 adc)
@@ -508,7 +508,7 @@ void adc_enable_eoc_interrupt_injected(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable Injected End-Of-Conversion Interrupt
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_eoc_interrupt_injected(u32 adc)
@@ -519,7 +519,7 @@ void adc_disable_eoc_interrupt_injected(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Enable Analog Watchdog Interrupt
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_awd_interrupt(u32 adc)
@@ -530,7 +530,7 @@ void adc_enable_awd_interrupt(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable Analog Watchdog Interrupt
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_awd_interrupt(u32 adc)
@@ -541,7 +541,7 @@ void adc_disable_awd_interrupt(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Enable Regular End-Of-Conversion Interrupt
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_eoc_interrupt(u32 adc)
@@ -552,7 +552,7 @@ void adc_enable_eoc_interrupt(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable Regular End-Of-Conversion Interrupt
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_eoc_interrupt(u32 adc)
@@ -566,7 +566,7 @@ void adc_disable_eoc_interrupt(u32 adc)
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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_temperature_sensor(u32 adc)
@@ -580,7 +580,7 @@ void adc_enable_temperature_sensor(u32 adc)
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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_temperature_sensor(u32 adc)
@@ -599,7 +599,7 @@ 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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_start_conversion_regular(u32 adc)
@@ -622,7 +622,7 @@ 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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_start_conversion_injected(u32 adc)
@@ -659,9 +659,9 @@ For ADC3
@li Timer 5 CC3 event
@li Software Start
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@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
+for ADC1 and ADC2, or @ref adc_trigger_regular_3 for ADC3.
*/
void adc_enable_external_trigger_regular(u32 adc, u32 trigger)
@@ -677,7 +677,7 @@ void adc_enable_external_trigger_regular(u32 adc, u32 trigger)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable an External Trigger for Regular Channels
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_external_trigger_regular(u32 adc)
@@ -710,9 +710,9 @@ For ADC3
@li Timer 5 CC4 event
@li Software Start
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@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
+for ADC1 and ADC2, or @ref adc_trigger_injected_3 for ADC3.
*/
void adc_enable_external_trigger_injected(u32 adc, u32 trigger)
{
@@ -727,7 +727,7 @@ void adc_enable_external_trigger_injected(u32 adc, u32 trigger)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable an External Trigger for Injected Channels
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_external_trigger_injected(u32 adc)
@@ -738,7 +738,7 @@ void adc_disable_external_trigger_injected(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Set the Data as Left Aligned
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_set_left_aligned(u32 adc)
@@ -749,7 +749,7 @@ void adc_set_left_aligned(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Set the Data as Right Aligned
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_set_right_aligned(u32 adc)
@@ -764,7 +764,7 @@ 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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_enable_dma(u32 adc)
@@ -776,7 +776,7 @@ void adc_enable_dma(u32 adc)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Disable DMA Transfers
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_disable_dma(u32 adc)
@@ -791,7 +791,7 @@ void adc_disable_dma(u32 adc)
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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_reset_calibration(u32 adc)
@@ -810,7 +810,7 @@ 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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_calibration(u32 adc)
@@ -825,7 +825,7 @@ void adc_calibration(u32 adc)
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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_set_continuous_conversion_mode(u32 adc)
@@ -839,7 +839,7 @@ void adc_set_continuous_conversion_mode(u32 adc)
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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_set_single_conversion_mode(u32 adc)
@@ -856,7 +856,7 @@ If the ADC is already on this function call will initiate a conversion.
@deprecated to be removed in a later release
-@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_on(u32 adc)
@@ -869,7 +869,7 @@ void adc_on(u32 adc)
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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
*/
void adc_off(u32 adc)
@@ -882,9 +882,9 @@ void adc_off(u32 adc)
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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
+@param[in] channel Unsigned int8. ADC Channel integer 0..18 or from @ref adc_channel.
+@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg.
*/
void adc_set_sample_time(u32 adc, u8 channel, u8 time)
@@ -910,8 +910,8 @@ void adc_set_sample_time(u32 adc, u8 channel, u8 time)
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
+@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base.
+@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg.
*/
void adc_set_sample_time_on_all_channels(u32 adc, u8 time)
@@ -931,8 +931,8 @@ void adc_set_sample_time_on_all_channels(u32 adc, u8 time)
/*-----------------------------------------------------------------------------*/
/** @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
+@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)
@@ -947,8 +947,8 @@ void adc_set_watchdog_high_threshold(u32 adc, u16 threshold)
/*-----------------------------------------------------------------------------*/
/** @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
+@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)
@@ -967,7 +967,7 @@ 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] 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.
*/
@@ -1003,9 +1003,9 @@ Defines a sequence of channels to be converted as an injected group with a lengt
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] 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
+@param[in] channel Unsigned int8[]. Set of channels in sequence, integers 0..18.
*/
void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[])
diff --git a/lib/stm32/f1/dma.c b/lib/stm32/f1/dma.c
index 3dbb14f..1f06c11 100644
--- a/lib/stm32/f1/dma.c
+++ b/lib/stm32/f1/dma.c
@@ -80,7 +80,7 @@ The interrupt flag for the channel is cleared. More than one interrupt for the
same channel may be cleared by using the logical OR of the interrupt flags.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
-@param[in] channel unsigned int8. Channel number: @ref dma_st_number
+@param[in] channel unsigned int8. Channel number: @ref dma_ch
@param[in] interrupts unsigned int32. Logical OR of interrupt numbers: @ref dma_if_offset
*/
@@ -97,8 +97,8 @@ void dma_clear_interrupt_flags(u32 dma, u8 channel, u32 interrupts)
The interrupt flag for the channel is returned.
@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
-@param[in] channel unsigned int8. Channel number: @ref dma_st_number
-@param[in] interrupt unsigned int32. Interrupt number: @ref dma_st_number
+@param[in] channel unsigned int8. Channel number: @ref dma_ch
+@param[in] interrupt unsigned int32. Interrupt number: @ref dma_ch
@returns bool interrupt flag is set.
*/
diff --git a/lib/stm32/f1/gpio.c b/lib/stm32/f1/gpio.c
index e513d29..2b33cad 100644
--- a/lib/stm32/f1/gpio.c
+++ b/lib/stm32/f1/gpio.c
@@ -1,4 +1,4 @@
-/** @defgroup STM32F1xx_gpio_file GPIO
+/** @defgroup gpio_file GPIO
@ingroup STM32F1xx
@@ -11,9 +11,6 @@
@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
@@ -55,7 +52,7 @@ Example 1: Digital input on port C12
@endcode
LGPL License Terms @ref lgpl_license
- */
+*/
/*
* This file is part of the libopencm3 project.
*
@@ -75,25 +72,10 @@ LGPL License Terms @ref lgpl_license
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
- * Basic GPIO handling API.
- *
- * Examples:
- * gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
- * GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
- * gpio_set(GPIOB, GPIO4);
- * gpio_clear(GPIOG, GPIO2 | GPIO9);
- * gpio_get(GPIOC, GPIO1);
- * gpio_toggle(GPIOA, GPIO7 | GPIO8);
- * reg16 = gpio_port_read(GPIOD);
- * gpio_port_write(GPIOF, 0xc8fe);
- *
- * TODO:
- * - GPIO remapping support
- */
-/**@{*/
+#include <libopencm3/stm32/gpio.h>
+#include <libopencm3/stm32/common/gpio_common_all.h>
-#include <libopencm3/stm32/f1/gpio.h>
+/**@{*/
/*-----------------------------------------------------------------------------*/
/** @brief Set GPIO Pin Mode
@@ -146,116 +128,6 @@ void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios)
}
/*-----------------------------------------------------------------------------*/
-/** @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;
-}
-
-/*-----------------------------------------------------------------------------*/
-/** @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;
-}
-
-/*-----------------------------------------------------------------------------*/
-/** @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;
-}
-
-/*-----------------------------------------------------------------------------*/
-/** @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);
-}
-
-/*-----------------------------------------------------------------------------*/
-/** @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;
-
- /* Special "Lock Key Writing Sequence", see datasheet. */
- GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
- GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */
- GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
- reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */
- reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */
-
- /* Tell the compiler the variable is actually used. It will get optimized out anyways. */
- reg32 = reg32;
-
- /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */
-}
-
-/*-----------------------------------------------------------------------------*/
/** @brief Map the EVENTOUT signal
Enable the EVENTOUT signal and select the port and pin to be used.
diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile
index b64a033..b890fa4 100644
--- a/lib/stm32/f2/Makefile
+++ b/lib/stm32/f2/Makefile
@@ -28,9 +28,10 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-ffunction-sections -fdata-sections -MD -DSTM32F2
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = rcc.o gpio2.o usart.o spi.o flash.o \
- i2c.o exti2.o timer.o
+OBJS = rcc.o gpio.o usart.o spi.o flash.o \
+ i2c.o exti2.o timer.o \
+ gpio_common_all.o gpio_common_f24.o
-VPATH += ../../usb:../:../../cm3
+VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include
diff --git a/lib/stm32/f2/gpio.c b/lib/stm32/f2/gpio.c
new file mode 100644
index 0000000..a2dfc88
--- /dev/null
+++ b/lib/stm32/f2/gpio.c
@@ -0,0 +1,28 @@
+/** @defgroup gpio_file GPIO
+
+@ingroup STM32F2xx
+
+@brief <b>libopencm3 STM32F2xx General Purpose I/O</b>
+
+*/
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/gpio.h>
+#include <libopencm3/stm32/common/gpio_common_f24.h>
+
diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile
index 09fe573..c9ad847 100644
--- a/lib/stm32/f4/Makefile
+++ b/lib/stm32/f4/Makefile
@@ -29,11 +29,12 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-ffunction-sections -fdata-sections -MD -DSTM32F4
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = rcc.o gpio2.o usart.o spi.o flash.o \
+OBJS = rcc.o gpio.o usart.o spi.o flash.o \
i2c.o exti2.o pwr.o timer.o \
usb.o usb_standard.o usb_control.o usb_fx07_common.o usb_f107.o \
- usb_f207.o adc.o dma.o
+ usb_f207.o adc.o dma.o \
+ gpio_common_all.o gpio_common_f24.o
-VPATH += ../../usb:../:../../cm3
+VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include
diff --git a/lib/stm32/f4/gpio.c b/lib/stm32/f4/gpio.c
new file mode 100644
index 0000000..96a6f45
--- /dev/null
+++ b/lib/stm32/f4/gpio.c
@@ -0,0 +1,28 @@
+/** @defgroup gpio_file GPIO
+
+@ingroup STM32F4xx
+
+@brief <b>libopencm3 STM32F4xx General Purpose I/O</b>
+
+*/
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/gpio.h>
+#include <libopencm3/stm32/common/gpio_common_f24.h>
+
diff --git a/lib/stm32/gpio2.c b/lib/stm32/gpio2.c
deleted file mode 100644
index c185e98..0000000
--- a/lib/stm32/gpio2.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(STM32F2)
-#include <libopencm3/stm32/f2/gpio.h>
-#elif defined(STM32F4)
-#include <libopencm3/stm32/f4/gpio.h>
-#elif defined(STM32L1)
-#include <libopencm3/stm32/l1/gpio.h>
-#else
-#error "invalid/unknown stm32 family for this code"
-#endif
-
-void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios)
-{
- u16 i;
- u32 moder, pupd;
-
- /*
- * We want to set the config only for the pins mentioned in gpios,
- * but keeping the others, so read out the actual config first.
- */
- moder = GPIO_MODER(gpioport);
- pupd = GPIO_PUPDR(gpioport);
-
- for (i = 0; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
-
- moder &= ~GPIO_MODE_MASK(i);
- moder |= GPIO_MODE(i, mode);
- pupd &= ~GPIO_PUPD_MASK(i);
- pupd |= GPIO_PUPD(i, pull_up_down);
- }
-
- /* Set mode and pull up/down control registers. */
- GPIO_MODER(gpioport) = moder;
- GPIO_PUPDR(gpioport) = pupd;
-}
-
-void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios)
-{
- u16 i;
- u32 ospeedr;
-
- if (otype == 0x1)
- GPIO_OTYPER(gpioport) |= gpios;
- else
- GPIO_OTYPER(gpioport) &= ~gpios;
-
- ospeedr = GPIO_OSPEEDR(gpioport);
-
- for (i = 0; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
- ospeedr &= ~GPIO_OSPEED_MASK(i);
- ospeedr |= GPIO_OSPEED(i, speed);
- }
-
- GPIO_OSPEEDR(gpioport) = ospeedr;
-}
-
-void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios)
-{
- u16 i;
- u32 afrl, afrh;
-
- afrl = GPIO_AFRL(gpioport);
- afrh = GPIO_AFRH(gpioport);
-
- for (i = 0; i < 8; i++) {
- if (!((1 << i) & gpios))
- continue;
- afrl &= ~GPIO_AFR_MASK(i);
- afrl |= GPIO_AFR(i, alt_func_num);
- }
-
- for (i = 8; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
- afrh &= ~GPIO_AFR_MASK(i - 8);
- afrh |= GPIO_AFR(i - 8, alt_func_num);
- }
-
- GPIO_AFRL(gpioport) = afrl;
- GPIO_AFRH(gpioport) = afrh;
-}
-
-void gpio_set(u32 gpioport, u16 gpios)
-{
- GPIO_BSRR(gpioport) = gpios;
-}
-
-void gpio_clear(u32 gpioport, u16 gpios)
-{
- GPIO_BSRR(gpioport) = gpios << 16;
-}
-
-u16 gpio_get(u32 gpioport, u16 gpios)
-{
- return gpio_port_read(gpioport) & gpios;
-}
-
-void gpio_toggle(u32 gpioport, u16 gpios)
-{
- GPIO_ODR(gpioport) ^= gpios;
-}
-
-u16 gpio_port_read(u32 gpioport)
-{
- return (u16)GPIO_IDR(gpioport);
-}
-
-void gpio_port_write(u32 gpioport, u16 data)
-{
- GPIO_ODR(gpioport) = data;
-}
-
-void gpio_port_config_lock(u32 gpioport, u16 gpios)
-{
- u32 reg32;
-
- /* Special "Lock Key Writing Sequence", see datasheet. */
- GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
- GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */
- GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
- reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */
- reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */
-
- /* Tell the compiler the variable is actually used. It will get optimized out anyways. */
- reg32 = reg32;
-
- /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */
-}
diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile
index 9e07b2d..7f3e157 100644
--- a/lib/stm32/l1/Makefile
+++ b/lib/stm32/l1/Makefile
@@ -28,9 +28,10 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-ffunction-sections -fdata-sections -MD -DSTM32L1
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = rcc.o gpio2.o desig.o crc.o usart.o exti2.o
+OBJS = rcc.o gpio.o desig.o crc.o usart.o exti2.o \
+ gpio_common_all.o gpio_common_f24.o
-VPATH += ../../usb:../:../../cm3
+VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include
diff --git a/lib/stm32/l1/gpio.c b/lib/stm32/l1/gpio.c
new file mode 100644
index 0000000..7fc2012
--- /dev/null
+++ b/lib/stm32/l1/gpio.c
@@ -0,0 +1,28 @@
+/** @defgroup gpio_file GPIO
+
+@ingroup STM32L1xx
+
+@brief <b>libopencm3 STM32L1xx General Purpose I/O</b>
+
+*/
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/gpio.h>
+#include <libopencm3/stm32/common/gpio_common_all.h>
+