From 6b5150a4dc54c4f5b2f8a98317ec963ea7fbc864 Mon Sep 17 00:00:00 2001 From: Cem Basoglu Date: Tue, 8 Mar 2016 02:39:21 +0100 Subject: [PATCH] stm32: usart-v2: Extended USART functions (data/pin inversion, half duplex) Includes receive timeout, all inversions and duplex and convenience functions. Applies for F0 and F3 so far. --- .../libopencm3/stm32/common/usart_common_v2.h | 73 ++++++ include/libopencm3/stm32/f0/usart.h | 13 +- include/libopencm3/stm32/f3/usart.h | 9 +- lib/stm32/common/usart_common_v2.c | 228 ++++++++++++++++++ lib/stm32/f0/Makefile | 1 + lib/stm32/f3/Makefile | 3 +- 6 files changed, 307 insertions(+), 20 deletions(-) create mode 100644 include/libopencm3/stm32/common/usart_common_v2.h create mode 100644 lib/stm32/common/usart_common_v2.c diff --git a/include/libopencm3/stm32/common/usart_common_v2.h b/include/libopencm3/stm32/common/usart_common_v2.h new file mode 100644 index 00000000..0df94be9 --- /dev/null +++ b/include/libopencm3/stm32/common/usart_common_v2.h @@ -0,0 +1,73 @@ +/** @addtogroup usart_defines + + @author @htmlonly © @endhtmlonly 2016 Cem Basoglu + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Cem Basoglu + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/** @cond */ +#if defined(LIBOPENCM3_USART_H) +/** @endcond */ +#ifndef LIBOPENCM3_USART_COMMON_V2_H +#define LIBOPENCM3_USART_COMMON_V2_H + +/*****************************************************************************/ +/* Register values */ +/*****************************************************************************/ + +/* --- USART_RTOR values --------------------------------------------------- */ + +/* BLEN[7:0]: Block Length */ +#define USART_RTOR_BLEN_SHIFT 24 +#define USART_RTOR_BLEN_MASK (0xFF << USART_RTOR_BLEN_SHIFT) +#define USART_RTOR_BLEN_VAL(x) ((x) << USART_RTOR_BLEN_SHIFT) + +/* RTO[23:0]: Receiver timeout value */ +#define USART_RTOR_RTO_SHIFT 0 +#define USART_RTOR_RTO_MASK (0xFFFFF << USART_RTOR_RTO_SHIFT) +#define USART_RTOR_RTO_VAL(x) ((x) << USART_RTOR_RTO_SHIFT) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void usart_enable_data_inversion(uint32_t usart); +void usart_disable_data_inversion(uint32_t usart); +void usart_enable_tx_inversion(uint32_t usart); +void usart_disable_tx_inversion(uint32_t usart); +void usart_enable_rx_inversion(uint32_t usart); +void usart_disable_rx_inversion(uint32_t usart); +void usart_enable_halfduplex(uint32_t usart); +void usart_disable_halfduplex(uint32_t usart); + +void usart_set_rx_timeout_value(uint32_t usart, uint32_t value); +void usart_enable_rx_timeout(uint32_t usart); +void usart_disable_rx_timeout(uint32_t usart); +void usart_enable_rx_timeout_interrupt(uint32_t usart); +void usart_disable_rx_timeout_interrupt(uint32_t usart); + +END_DECLS + +#endif +/** @cond */ +#else +#warning "usart_common_v2.h should not be included directly, only via usart.h" +#endif +/** @endcond */ diff --git a/include/libopencm3/stm32/f0/usart.h b/include/libopencm3/stm32/f0/usart.h index a8d38985..8812b939 100644 --- a/include/libopencm3/stm32/f0/usart.h +++ b/include/libopencm3/stm32/f0/usart.h @@ -31,6 +31,8 @@ #ifndef LIBOPENCM3_USART_H #define LIBOPENCM3_USART_H +#include + /*****************************************************************************/ /* Module definitions */ /*****************************************************************************/ @@ -224,17 +226,6 @@ #define USART_GTPR_PSC (0xFF << USART_GTPR_PSC_SHIFT) #define USART_GTPR_PSC_VAL(x) ((x) << USART_GTPR_PSC_SHIFT) - -/* USART_RTOR Values --------------------------------------------------------*/ - -#define USART_RTOR_BLEN_SHIFT 24 -#define USART_RTOR_BLEN (0xFF << USART_RTOR_BLEN_SHIFT) -#define USART_RTOR_BLEN_VAL(x) ((x) << USART_RTOR_BLEN_SHIFT) - -#define USART_RTOR_RTO_SHIFT 0 -#define USART_RTOR_RTO (0xFF << USART_RTOR_RTO_SHIFT) -#define USART_RTOR_RTO_VAL(x) ((x) << USART_RTOR_RTO_SHIFT) - /* USART_RQR Values ---------------------------------------------------------*/ #define USART_RQR_TXFRQ (1 << 4) diff --git a/include/libopencm3/stm32/f3/usart.h b/include/libopencm3/stm32/f3/usart.h index 86961d3a..61cbaca4 100644 --- a/include/libopencm3/stm32/f3/usart.h +++ b/include/libopencm3/stm32/f3/usart.h @@ -32,6 +32,7 @@ #define LIBOPENCM3_USART_H #include +#include /* --- USART registers ----------------------------------------------------- */ @@ -342,14 +343,6 @@ /* Note: N/A on UART4/5 */ #define USART_GTPR_PSC_MASK 0xFF -/* --- USART_RTOR values --------------------------------------------------- */ - -/* XXX: Preguntar */ -/* BLEN[7:0]: Block Length */ -#define USART_RTOR_BLEN1_MASK (0xFF << 24) - -/* RTO[23:0]: Receiver timeout value */ -#define USART_RTOR_BLEN2_MASK (0xFFFF << 0) /* --- USART_RQR values --------------------------------------------------- */ diff --git a/lib/stm32/common/usart_common_v2.c b/lib/stm32/common/usart_common_v2.c new file mode 100644 index 00000000..3e64c25a --- /dev/null +++ b/lib/stm32/common/usart_common_v2.c @@ -0,0 +1,228 @@ +/** @addtogroup usart_file + + @author @htmlonly © @endhtmlonly 2016 Cem Basoglu + + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Cem Basoglu + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public 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 USART enable data inversion + + Logical data from the data register are send/received in negative/inverse logic. + (1=L, 0=H). The parity bit is also inverted. + + @note This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_data_inversion(uint32_t usart) +{ + USART_CR2(usart) |= USART_CR2_DATAINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART disable data inversion + + Logical data from the data register are send/received in positive/direct logic. + (1=H, 0=L) + + @note This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_data_inversion(uint32_t usart) +{ + USART_CR2(usart) &= ~USART_CR2_DATAINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Enable TX pin active level inversion + + TX pin signal values are inverted. (VDD =0/mark, Gnd=1/idle). + + @note This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_tx_inversion(uint32_t usart) +{ + USART_CR2(usart) |= USART_CR2_TXINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Disable TX pin active level inversion + + TX pin signal works using the standard logic levels (VDD =1/idle, Gnd=0/mark) + + @note This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_tx_inversion(uint32_t usart) +{ + USART_CR2(usart) &= ~USART_CR2_TXINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Enable RX pin active level inversion + + RX pin signal values are inverted. (VDD =0/mark, Gnd=1/idle). + + @This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_rx_inversion(uint32_t usart) +{ + USART_CR2(usart) |= USART_CR2_RXINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Disable RX pin active level inversion + + RX pin signal works using the standard logic levels (VDD =1/idle, Gnd=0/mark) + + @This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_rx_inversion(uint32_t usart) +{ + + USART_CR2(usart) &= ~USART_CR2_RXINV; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Enable Half-duplex + + - The TX and RX lines are internally connected. + - The RX pin is no longer used + - The TX pin is always released when no data is transmitted. Thus, + it acts as a standard I/O in idle or in reception. It means + that the I/O must be configured so that TX is configured as + alternate function open-drain with an external pull-up. + + Apart from this, the communication protocol is similar to normal USART mode. + Any conflicts on the line must be managed by software + + @This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_halfduplex(uint32_t usart) +{ + USART_CR3(usart) |= USART_CR3_HDSEL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Disable Half-duplex + + @This bit field can only be written when the USART is disabled. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_halfduplex(uint32_t usart) +{ + USART_CR3(usart) &= ~USART_CR3_HDSEL; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART Set receiver timeout value + + Sets the receive timeout value in terms of number of bit duration. + The RTOF @ref usart_isr_rtof is set if, after the last received character, + no new start bit is detected for more than the receive timeout value. + + @note The timeout value can also be written when USART is enabled. + If the new value is lower/equals the internal hardware counter, + the RTOF flag will be set. + + @param[in] usart USART block register address base @ref usart_reg_base + @param[in] value The receive timeout value in terms of number of bit duration. + */ +void usart_set_rx_timeout_value(uint32_t usart, uint32_t value) +{ + uint32_t reg; + reg = USART_RTOR(usart) & ~USART_RTOR_RTO_MASK; + reg |= (USART_RTOR_RTO_VAL(value) & USART_RTOR_RTO_MASK); + USART_RTOR(usart) = reg; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART enable receive timeout function + + @note If the USART does not support the Receiver timeout feature, + this bit is reserved and forced by hardware to ‘0’. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_rx_timeout(uint32_t usart) +{ + USART_CR2(usart) |= USART_CR2_RTOEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART disable receive timeout function + + @note If the USART does not support the Receiver timeout feature, + this bit is reserved and forced by hardware to ‘0’. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_rx_timeout(uint32_t usart) +{ + USART_CR2(usart) &= ~USART_CR2_RTOEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART enable receive timeout interrupt + + An interrupt is generated when the RTOF Flag is set + in the ISR @ref usart_isr register. + + @note If the USART does not support the Receiver timeout feature, + this bit is reserved and forced by hardware to ‘0’. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_enable_rx_timeout_interrupt(uint32_t usart) +{ + USART_CR1(usart) |= USART_CR1_RTOIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief USART disable receive timeout interrupt + + @note If the USART does not support the Receiver timeout feature, + this bit is reserved and forced by hardware to ‘0’. + + @param[in] usart USART block register address base @ref usart_reg_base + */ +void usart_disable_rx_timeout_interrupt(uint32_t usart) +{ + USART_CR1(usart) &= ~USART_CR1_RTOIE; +} + +/**@}*/ diff --git a/lib/stm32/f0/Makefile b/lib/stm32/f0/Makefile index 843d66e9..4b2f8957 100644 --- a/lib/stm32/f0/Makefile +++ b/lib/stm32/f0/Makefile @@ -45,6 +45,7 @@ OBJS += gpio_common_all.o gpio_common_f0234.o crc_common_all.o \ timer_common_all.o rcc_common_all.o OBJS += adc_common_v2.o OBJS += crs_common_all.o +OBJS += usart_common_v2.o OBJS += usb.o usb_control.o usb_standard.o OBJS += st_usbfs_core.o st_usbfs_v2.o diff --git a/lib/stm32/f3/Makefile b/lib/stm32/f3/Makefile index 90c3c0bb..e2fc99fd 100644 --- a/lib/stm32/f3/Makefile +++ b/lib/stm32/f3/Makefile @@ -39,11 +39,12 @@ ARFLAGS = rcs OBJS = rcc.o adc.o i2c.o usart.o dma.o flash.o OBJS += gpio_common_all.o gpio_common_f0234.o \ - dac_common_all.o usart_common_all.o crc_common_all.o\ + dac_common_all.o crc_common_all.o \ iwdg_common_all.o spi_common_all.o dma_common_l1f013.o\ timer_common_all.o timer_common_f234.o flash_common_f234.o \ flash.o exti_common_all.o rcc_common_all.o spi_common_f03.o OBJS += adc_common_v2.o adc_common_v2_multi.o +OBJS += usart_common_v2.o usart_common_all.o OBJS += usb.o usb_control.o usb_standard.o OBJS += st_usbfs_core.o st_usbfs_v1.o