aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/hal.mk1
-rw-r--r--os/hal/include/hal.h2
-rw-r--r--os/hal/include/uart.h122
-rw-r--r--os/hal/platforms/STM32/USARTv2/uart_lld.c40
-rw-r--r--os/hal/src/uart.c338
5 files changed, 480 insertions, 23 deletions
diff --git a/os/hal/hal.mk b/os/hal/hal.mk
index ce6ae5e0c..2323b9dcb 100644
--- a/os/hal/hal.mk
+++ b/os/hal/hal.mk
@@ -14,6 +14,7 @@ HALSRC = ${CHIBIOS}/os/hal/src/hal.c \
${CHIBIOS}/os/hal/src/serial.c \
${CHIBIOS}/os/hal/src/spi.c \
${CHIBIOS}/os/hal/src/st.c \
+ ${CHIBIOS}/os/hal/src/uart.c \
# Required include directories
HALINC = ${CHIBIOS}/os/hal/include
diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h
index 0ab5ee37b..453addd1a 100644
--- a/os/hal/include/hal.h
+++ b/os/hal/include/hal.h
@@ -59,7 +59,7 @@
//#include "sdc.h"
#include "spi.h"
#include "st.h"
-//#include "uart.h"
+#include "uart.h"
//#include "usb.h"
/* Complex drivers.*/
diff --git a/os/hal/include/uart.h b/os/hal/include/uart.h
new file mode 100644
index 000000000..74b77e161
--- /dev/null
+++ b/os/hal/include/uart.h
@@ -0,0 +1,122 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file uart.h
+ * @brief UART Driver macros and structures.
+ *
+ * @addtogroup UART
+ * @{
+ */
+
+#ifndef _UART_H_
+#define _UART_H_
+
+#if HAL_USE_UART || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name UART status flags
+ * @{
+ */
+#define UART_NO_ERROR 0 /**< @brief No pending conditions. */
+#define UART_PARITY_ERROR 4 /**< @brief Parity error happened. */
+#define UART_FRAMING_ERROR 8 /**< @brief Framing error happened. */
+#define UART_OVERRUN_ERROR 16 /**< @brief Overflow happened. */
+#define UART_NOISE_ERROR 32 /**< @brief Noise on the line. */
+#define UART_BREAK_DETECTED 64 /**< @brief Break detected. */
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Driver state machine possible states.
+ */
+typedef enum {
+ UART_UNINIT = 0, /**< Not initialized. */
+ UART_STOP = 1, /**< Stopped. */
+ UART_READY = 2 /**< Ready. */
+} uartstate_t;
+
+/**
+ * @brief Transmitter state machine states.
+ */
+typedef enum {
+ UART_TX_IDLE = 0, /**< Not transmitting. */
+ UART_TX_ACTIVE = 1, /**< Transmitting. */
+ UART_TX_COMPLETE = 2 /**< Buffer complete. */
+} uarttxstate_t;
+
+/**
+ * @brief Receiver state machine states.
+ */
+typedef enum {
+ UART_RX_IDLE = 0, /**< Not receiving. */
+ UART_RX_ACTIVE = 1, /**< Receiving. */
+ UART_RX_COMPLETE = 2 /**< Buffer complete. */
+} uartrxstate_t;
+
+#include "uart_lld.h"
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void uartInit(void);
+ void uartObjectInit(UARTDriver *uartp);
+ void uartStart(UARTDriver *uartp, const UARTConfig *config);
+ void uartStop(UARTDriver *uartp);
+ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf);
+ void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf);
+ size_t uartStopSend(UARTDriver *uartp);
+ size_t uartStopSendI(UARTDriver *uartp);
+ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf);
+ void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf);
+ size_t uartStopReceive(UARTDriver *uartp);
+ size_t uartStopReceiveI(UARTDriver *uartp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_UART */
+
+#endif /* _UART_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/STM32/USARTv2/uart_lld.c b/os/hal/platforms/STM32/USARTv2/uart_lld.c
index 740c2fd98..0b85a294c 100644
--- a/os/hal/platforms/STM32/USARTv2/uart_lld.c
+++ b/os/hal/platforms/STM32/USARTv2/uart_lld.c
@@ -22,7 +22,6 @@
* @{
*/
-#include "ch.h"
#include "hal.h"
#if HAL_USE_UART || defined(__DOXYGEN__)
@@ -296,13 +295,13 @@ static void serve_usart_irq(UARTDriver *uartp) {
*
* @isr
*/
-CH_IRQ_HANDLER(STM32_USART1_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
- CH_IRQ_PROLOGUE();
+ OSAL_IRQ_PROLOGUE();
serve_usart_irq(&UARTD1);
- CH_IRQ_EPILOGUE();
+ OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_UART_USE_USART1 */
@@ -315,13 +314,13 @@ CH_IRQ_HANDLER(STM32_USART1_HANDLER) {
*
* @isr
*/
-CH_IRQ_HANDLER(STM32_USART2_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
- CH_IRQ_PROLOGUE();
+ OSAL_IRQ_PROLOGUE();
serve_usart_irq(&UARTD2);
- CH_IRQ_EPILOGUE();
+ OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_UART_USE_USART2 */
@@ -334,13 +333,13 @@ CH_IRQ_HANDLER(STM32_USART2_HANDLER) {
*
* @isr
*/
-CH_IRQ_HANDLER(STM32_USART3_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
- CH_IRQ_PROLOGUE();
+ OSAL_IRQ_PROLOGUE();
serve_usart_irq(&UARTD3);
- CH_IRQ_EPILOGUE();
+ OSAL_IRQ_EPILOGUE();
}
#endif /* STM32_UART_USE_USART3 */
@@ -397,15 +396,14 @@ void uart_lld_start(UARTDriver *uartp) {
STM32_UART_USART1_IRQ_PRIORITY,
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
- chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated");
+ osalDbgAssert(!b, "stream already allocated");
b = dmaStreamAllocate(uartp->dmatx,
STM32_UART_USART1_IRQ_PRIORITY,
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
- chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated");
+ osalDbgAssert(!b, "stream already allocated");
rccEnableUSART1(FALSE);
- nvicEnableVector(STM32_USART1_NUMBER,
- CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
+ nvicEnableVector(STM32_USART1_NUMBER, STM32_UART_USART1_IRQ_PRIORITY);
uartp->dmamode |= STM32_DMA_CR_CHSEL(USART1_RX_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
}
@@ -418,15 +416,14 @@ void uart_lld_start(UARTDriver *uartp) {
STM32_UART_USART2_IRQ_PRIORITY,
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
- chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated");
+ osalDbgAssert(!b, "stream already allocated");
b = dmaStreamAllocate(uartp->dmatx,
STM32_UART_USART2_IRQ_PRIORITY,
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
- chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated");
+ osalDbgAssert(!b, "stream already allocated");
rccEnableUSART2(FALSE);
- nvicEnableVector(STM32_USART2_NUMBER,
- CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
+ nvicEnableVector(STM32_USART2_NUMBER, STM32_UART_USART2_IRQ_PRIORITY);
uartp->dmamode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
}
@@ -439,15 +436,14 @@ void uart_lld_start(UARTDriver *uartp) {
STM32_UART_USART3_IRQ_PRIORITY,
(stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
- chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated");
+ osalDbgAssert(!b, "stream already allocated");
b = dmaStreamAllocate(uartp->dmatx,
STM32_UART_USART3_IRQ_PRIORITY,
(stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
- chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated");
+ osalDbgAssert(!b, "stream already allocated");
rccEnableUSART3(FALSE);
- nvicEnableVector(STM32_USART3_NUMBER,
- CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY));
+ nvicEnableVector(STM32_USART3_NUMBER, STM32_UART_USART3_IRQ_PRIORITY);
uartp->dmamode |= STM32_DMA_CR_CHSEL(USART3_RX_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
}
diff --git a/os/hal/src/uart.c b/os/hal/src/uart.c
new file mode 100644
index 000000000..a25b594aa
--- /dev/null
+++ b/os/hal/src/uart.c
@@ -0,0 +1,338 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file uart.c
+ * @brief UART Driver code.
+ *
+ * @addtogroup UART
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_UART || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief UART Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void uartInit(void) {
+
+ uart_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p UARTDriver structure.
+ *
+ * @param[out] uartp pointer to the @p UARTDriver object
+ *
+ * @init
+ */
+void uartObjectInit(UARTDriver *uartp) {
+
+ uartp->state = UART_STOP;
+ uartp->txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->config = NULL;
+ /* Optional, user-defined initializer.*/
+#if defined(UART_DRIVER_EXT_INIT_HOOK)
+ UART_DRIVER_EXT_INIT_HOOK(uartp);
+#endif
+}
+
+/**
+ * @brief Configures and activates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] config pointer to the @p UARTConfig object
+ *
+ * @api
+ */
+void uartStart(UARTDriver *uartp, const UARTConfig *config) {
+
+ osalDbgCheck((uartp != NULL) && (config != NULL));
+
+ osalSysLock();
+ osalDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY),
+ "invalid state");
+
+ uartp->config = config;
+ uart_lld_start(uartp);
+ uartp->state = UART_READY;
+ osalSysUnlock();
+}
+
+/**
+ * @brief Deactivates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @api
+ */
+void uartStop(UARTDriver *uartp) {
+
+ osalDbgCheck(uartp != NULL);
+
+ osalSysLock();
+ osalDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY),
+ "invalid state");
+
+ uart_lld_stop(uartp);
+ uartp->state = UART_STOP;
+ uartp->txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
+ osalSysUnlock();
+}
+
+/**
+ * @brief Starts a transmission on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @api
+ */
+void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) {
+
+ osalDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL));
+
+ osalSysLock();
+ osalDbgAssert(uartp->state == UART_READY, "is active");
+ osalDbgAssert(uartp->txstate != UART_TX_ACTIVE, "tx active");
+
+ uart_lld_start_send(uartp, n, txbuf);
+ uartp->txstate = UART_TX_ACTIVE;
+ osalSysUnlock();
+}
+
+/**
+ * @brief Starts a transmission on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ * @note This function has to be invoked from a lock zone.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @iclass
+ */
+void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) {
+
+ osalDbgCheckClassI();
+ osalDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL));
+ osalDbgAssert(uartp->state == UART_READY, "is active");
+ osalDbgAssert(uartp->txstate != UART_TX_ACTIVE, "tx active");
+
+ uart_lld_start_send(uartp, n, txbuf);
+ uartp->txstate = UART_TX_ACTIVE;
+}
+
+/**
+ * @brief Stops any ongoing transmission.
+ * @note Stopping a transmission also suppresses the transmission callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not transmitted by the
+ * stopped transmit operation.
+ * @retval 0 There was no transmit operation in progress.
+ *
+ * @api
+ */
+size_t uartStopSend(UARTDriver *uartp) {
+ size_t n;
+
+ osalDbgCheck(uartp != NULL);
+
+ osalSysLock();
+ osalDbgAssert(uartp->state == UART_READY, "not active");
+
+ if (uartp->txstate == UART_TX_ACTIVE) {
+ n = uart_lld_stop_send(uartp);
+ uartp->txstate = UART_TX_IDLE;
+ }
+ else
+ n = 0;
+ osalSysUnlock();
+ return n;
+}
+
+/**
+ * @brief Stops any ongoing transmission.
+ * @note Stopping a transmission also suppresses the transmission callbacks.
+ * @note This function has to be invoked from a lock zone.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not transmitted by the
+ * stopped transmit operation.
+ * @retval 0 There was no transmit operation in progress.
+ *
+ * @iclass
+ */
+size_t uartStopSendI(UARTDriver *uartp) {
+
+ osalDbgCheckClassI();
+ osalDbgCheck(uartp != NULL);
+ osalDbgAssert(uartp->state == UART_READY, "not active");
+
+ if (uartp->txstate == UART_TX_ACTIVE) {
+ size_t n = uart_lld_stop_send(uartp);
+ uartp->txstate = UART_TX_IDLE;
+ return n;
+ }
+ return 0;
+}
+
+/**
+ * @brief Starts a receive operation on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[in] rxbuf the pointer to the receive buffer
+ *
+ * @api
+ */
+void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) {
+
+ osalDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL));
+
+ osalSysLock();
+ osalDbgAssert(uartp->state == UART_READY, "is active");
+ osalDbgAssert(uartp->rxstate != UART_RX_ACTIVE, "rx active");
+
+ uart_lld_start_receive(uartp, n, rxbuf);
+ uartp->rxstate = UART_RX_ACTIVE;
+ osalSysUnlock();
+}
+
+/**
+ * @brief Starts a receive operation on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ * @note This function has to be invoked from a lock zone.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @iclass
+ */
+void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) {
+
+ osalDbgCheckClassI();
+ osalDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL));
+ osalDbgAssert(uartp->state == UART_READY, "is active");
+ osalDbgAssert(uartp->rxstate != UART_RX_ACTIVE, "rx active");
+
+ uart_lld_start_receive(uartp, n, rxbuf);
+ uartp->rxstate = UART_RX_ACTIVE;
+}
+
+/**
+ * @brief Stops any ongoing receive operation.
+ * @note Stopping a receive operation also suppresses the receive callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not received by the
+ * stopped receive operation.
+ * @retval 0 There was no receive operation in progress.
+ *
+ * @api
+ */
+size_t uartStopReceive(UARTDriver *uartp) {
+ size_t n;
+
+ osalDbgCheck(uartp != NULL);
+
+ osalSysLock();
+ osalDbgAssert(uartp->state == UART_READY, "not active");
+
+ if (uartp->rxstate == UART_RX_ACTIVE) {
+ n = uart_lld_stop_receive(uartp);
+ uartp->rxstate = UART_RX_IDLE;
+ }
+ else
+ n = 0;
+ osalSysUnlock();
+ return n;
+}
+
+/**
+ * @brief Stops any ongoing receive operation.
+ * @note Stopping a receive operation also suppresses the receive callbacks.
+ * @note This function has to be invoked from a lock zone.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not received by the
+ * stopped receive operation.
+ * @retval 0 There was no receive operation in progress.
+ *
+ * @iclass
+ */
+size_t uartStopReceiveI(UARTDriver *uartp) {
+
+ osalDbgCheckClassI();
+ osalDbgCheck(uartp != NULL);
+ osalDbgAssert(uartp->state == UART_READY, "not active");
+
+ if (uartp->rxstate == UART_RX_ACTIVE) {
+ size_t n = uart_lld_stop_receive(uartp);
+ uartp->rxstate = UART_RX_IDLE;
+ return n;
+ }
+ return 0;
+}
+
+#endif /* HAL_USE_UART */
+
+/** @} */