aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/include/uart.h
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/include/uart.h')
-rw-r--r--os/hal/include/uart.h223
1 files changed, 223 insertions, 0 deletions
diff --git a/os/hal/include/uart.h b/os/hal/include/uart.h
index 75a9e2b58..f619599d9 100644
--- a/os/hal/include/uart.h
+++ b/os/hal/include/uart.h
@@ -47,6 +47,27 @@
/* Driver pre-compile time settings. */
/*===========================================================================*/
+/**
+ * @name UART configuration options
+ * @{
+ */
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
+#define UART_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define UART_USE_MUTUAL_EXCLUSION TRUE
+#endif
+/** @} */
+
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
@@ -88,6 +109,196 @@ typedef enum {
/* Driver macros. */
/*===========================================================================*/
+/**
+ * @name Low level driver helper macros
+ * @{
+ */
+#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Wakes up the waiting thread in case of early TX complete.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_wakeup_tx1_isr(uartp) { \
+ if ((uartp)->early == true) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(uartp)->threadtx, MSG_OK); \
+ osalSysUnlockFromISR(); \
+ } \
+}
+#else /* !UART_USE_WAIT */
+#define _uart_wakeup_tx1_isr(uartp)
+#endif /* !UART_USE_WAIT */
+
+#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Wakes up the waiting thread in case of late TX complete.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_wakeup_tx2_isr(uartp) { \
+ if ((uartp)->early == false) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(uartp)->threadtx, MSG_OK); \
+ osalSysUnlockFromISR(); \
+ } \
+}
+#else /* !UART_USE_WAIT */
+#define _uart_wakeup_tx2_isr(uartp)
+#endif /* !UART_USE_WAIT */
+
+#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Wakes up the waiting thread in case of RX complete.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_wakeup_rx_complete_isr(uartp) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(uartp)->threadrx, MSG_OK); \
+ osalSysUnlockFromISR(); \
+}
+#else /* !UART_USE_WAIT */
+#define _uart_wakeup_rx_complete_isr(uartp)
+#endif /* !UART_USE_WAIT */
+
+#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Wakes up the waiting thread in case of RX error.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_wakeup_rx_error_isr(uartp) { \
+ osalSysLockFromISR(); \
+ osalThreadResumeI(&(uartp)->threadrx, MSG_RESET); \
+ osalSysUnlockFromISR(); \
+}
+#else /* !UART_USE_WAIT */
+#define _uart_wakeup_rx_error_isr(uartp)
+#endif /* !UART_USE_WAIT */
+
+/**
+ * @brief Common ISR code for early TX.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_tx1_isr_code(uartp) { \
+ (uartp)->txstate = UART_TX_COMPLETE; \
+ if ((uartp)->config->txend1_cb != NULL) { \
+ (uartp)->config->txend1_cb(uartp); \
+ } \
+ if ((uartp)->txstate == UART_TX_COMPLETE) { \
+ (uartp)->txstate = UART_TX_IDLE; \
+ } \
+ _uart_wakeup_tx1_isr(uartp); \
+}
+
+/**
+ * @brief Common ISR code for late TX.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_tx2_isr_code(uartp) { \
+ if ((uartp)->config->txend2_cb != NULL) { \
+ (uartp)->config->txend2_cb(uartp); \
+ } \
+ _uart_wakeup_tx2_isr(uartp); \
+}
+
+/**
+ * @brief Common ISR code for RX complete.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_rx_complete_isr_code(uartp) { \
+ (uartp)->rxstate = UART_RX_COMPLETE; \
+ if ((uartp)->config->rxend_cb != NULL) { \
+ (uartp)->config->rxend_cb(uartp); \
+ } \
+ if ((uartp)->rxstate == UART_RX_COMPLETE) { \
+ (uartp)->rxstate = UART_RX_IDLE; \
+ uart_enter_rx_idle_loop(uartp); \
+ } \
+ _uart_wakeup_rx_complete_isr(uartp); \
+}
+
+/**
+ * @brief Common ISR code for RX error.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_rx_error_isr_code(uartp, errors) { \
+ if ((uartp)->config->rxerr_cb != NULL) { \
+ (uartp)->config->rxerr_cb(uartp, errors); \
+ } \
+ _uart_wakeup_rx_error_isr(uartp); \
+}
+
+
+/**
+ * @brief Common ISR code for RX on idle.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+#define _uart_rx_idle_code(uartp) { \
+ if ((uartp)->config->rxchar_cb != NULL) \
+ (uartp)->config->rxchar_cb(uartp, (uartp)->rxbuf); \
+}
+/** @} */
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -107,6 +318,18 @@ extern "C" {
void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf);
size_t uartStopReceive(UARTDriver *uartp);
size_t uartStopReceiveI(UARTDriver *uartp);
+#if UART_USE_WAIT == TRUE
+ msg_t uartSendTimeout(UARTDriver *uartp, size_t *np,
+ const void *txbuf, systime_t time);
+ msg_t uartSendFullTimeout(UARTDriver *uartp, size_t *np,
+ const void *txbuf, systime_t time);
+ msg_t uartReceiveTimeout(UARTDriver *uartp, size_t *np,
+ void *rxbuf, systime_t time);
+#endif
+#if UART_USE_MUTUAL_EXCLUSION == TRUE
+ void uartAcquireBus(UARTDriver *uartp);
+ void uartReleaseBus(UARTDriver *uartp);
+#endif
#ifdef __cplusplus
}
#endif