From 8e7bdc79b559bb3936ffcdc0a34d20fbcdb20cc9 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 31 Aug 2022 12:29:47 +0000 Subject: [PATCH] More SIO-related changes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15746 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/include/hal_sio.h | 47 ++++++++++++------ os/hal/ports/RP/LLD/UARTv1/hal_sio_lld.c | 8 +-- os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.c | 52 +++++++++++++++++--- os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.h | 1 + os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.c | 52 +++++++++++++++++--- os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.h | 1 + 6 files changed, 125 insertions(+), 36 deletions(-) diff --git a/os/hal/include/hal_sio.h b/os/hal/include/hal_sio.h index d3e66618f..3b7c0788a 100644 --- a/os/hal/include/hal_sio.h +++ b/os/hal/include/hal_sio.h @@ -32,14 +32,19 @@ /*===========================================================================*/ /** - * @name Events enable flags offsets + * @name SIO masks offsets * @{ */ -#define SIO_FL_RXNOTEMPY_POS 1 -#define SIO_FL_TXNOTFULL_POS 2 -#define SIO_FL_RXIDLE_POS 3 -#define SIO_FL_TXDONE_POS 4 -#define SIO_FL_ALL_ERRORS_POS 5 +#define SIO_MSK_RXNOTEMPY_POS 2 /* CHN_INPUT_AVAILABLE */ +#define SIO_MSK_TXNOTFULL_POS 3 /* CHN_OUTPUT_EMPTY */ +#define SIO_MSK_TXDONE_POS 4 /* CHN_TRANSMISSION_END */ +#define SIO_MSK_ALL_ERRORS_POS 5 /* CHN all errors */ +#define SIO_MSK_PARITY_ERR_POS 5 /* CHN_PARITY_ERROR */ +#define SIO_MSK_FRAMING_ERR_POS 6 /* CHN_FRAMING_ERROR */ +#define SIO_MSK_OVERRUN_ERR_POS 7 /* CHN_OVERRUN_ERROR */ +#define SIO_MSK_NOISE_ERR_POS 8 /* CHN_NOISE_ERROR */ +#define SIO_MSK_BREAK_POS 9 /* CHN_BREAK_DETECTED */ +#define SIO_MSK_RXIDLE_POS 11 /* CHN does not define it */ /** @} */ /** @@ -53,11 +58,11 @@ /** * @brief RX buffer not empty event. */ -#define SIO_FL_RXNOTEMPY (1U << SIO_FL_RXNOTEMPY_POS) +#define SIO_FL_RXNOTEMPY (1U << SIO_MSK_RXNOTEMPY_POS) /** * @brief TX buffer not full event. */ -#define SIO_FL_TXNOTFULL (1U << SIO_FL_TXNOTFULL_POS) +#define SIO_FL_TXNOTFULL (1U << SIO_MSK_TXNOTFULL_POS) /** * @brief All data-related events. */ @@ -66,11 +71,11 @@ /** * @brief RX line idling event. */ -#define SIO_FL_RXIDLE (1U << SIO_FL_RXIDLE_POS) +#define SIO_FL_RXIDLE (1U << SIO_MSK_RXIDLE_POS) /** * @brief TX complete event. */ -#define SIO_FL_TXDONE (1U << SIO_FL_TXDONE_POS) +#define SIO_FL_TXDONE (1U << SIO_MSK_TXDONE_POS) /** * @brief All protocol-related events. */ @@ -79,7 +84,7 @@ /** * @brief All RX error events. */ -#define SIO_FL_ALL_ERRORS (1U << SIO_FL_ALL_ERRORS_POS) +#define SIO_FL_ALL_ERRORS (1U << SIO_MSK_ALL_ERRORS_POS) /** * @brief All events. */ @@ -92,9 +97,9 @@ * @name Event flags offsets * @{ */ -#define SIO_EV_RXNOTEMPY_POS 2 /* CHN_INPUT_AVAILABLE */ -#define SIO_EV_TXNOTFULL_POS 3 /* CHN_OUTPUT_EMPTY */ -#define SIO_EV_TXDONE_POS 4 /* CHN_TRANSMISSION_END */ +#define SIO_EV_RXNOTEMPY_POS 2 +#define SIO_EV_TXNOTFULL_POS 3 +#define SIO_EV_TXDONE_POS 4 #define SIO_EV_PARITY_ERR_POS 5 /* CHN_PARITY_ERROR */ #define SIO_EV_FRAMING_ERR_POS 6 /* CHN_FRAMING_ERROR */ #define SIO_EV_OVERRUN_ERR_POS 7 /* CHN_OVERRUN_ERROR */ @@ -177,7 +182,7 @@ /** * @brief Type of events enable flags. */ -typedef uint_least8_t sioflags_t; +typedef eventflags_t sioflags_t; /** * @brief Type of event flags. @@ -440,6 +445,16 @@ struct hal_sio_driver { */ #define sioGetAndClearEventsI(siop) sio_lld_get_and_clear_events(siop) +/** + * @brief Returns the pending SIO event flags. + * + * @param[in] siop pointer to the @p SIODriver object + * @return The pending event flags. + * + * @iclass + */ +#define sioGetEventsI(siop) sio_lld_get_events(siop) + /** * @brief Returns one frame from the RX FIFO. * @note If the FIFO is empty then the returned value is unpredictable. @@ -535,7 +550,7 @@ struct hal_sio_driver { * * @notapi */ -#define __sio_wakeup_events(siop) do { \ +#define __sio_wakeup_errors(siop) do { \ osalSysLockFromISR(); \ osalThreadResumeI(&(siop)->sync_rx, SIO_MSG_ERRORS); \ osalThreadResumeI(&(siop)->sync_rxidle, SIO_MSG_ERRORS); \ diff --git a/os/hal/ports/RP/LLD/UARTv1/hal_sio_lld.c b/os/hal/ports/RP/LLD/UARTv1/hal_sio_lld.c index 48754df8b..3ed9d0b74 100644 --- a/os/hal/ports/RP/LLD/UARTv1/hal_sio_lld.c +++ b/os/hal/ports/RP/LLD/UARTv1/hal_sio_lld.c @@ -256,9 +256,9 @@ void sio_lld_update_enable_flags(SIODriver *siop) { UART_UARTIMSC_PEIM | UART_UARTIMSC_FEIM; } - imsc |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_FL_RXNOTEMPY_POS, UART_UARTIMSC_RXIM_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_FL_TXNOTFULL_POS, UART_UARTIMSC_TXIM_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_FL_RXIDLE_POS, UART_UARTIMSC_RTIM_Pos); + imsc |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_MSK_RXNOTEMPY_POS, UART_UARTIMSC_RXIM_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_MSK_TXNOTFULL_POS, UART_UARTIMSC_TXIM_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_MSK_RXIDLE_POS, UART_UARTIMSC_RTIM_Pos); /* Setting up the operation.*/ siop->uart->UARTIMSC |= imsc; @@ -509,7 +509,7 @@ void sio_lld_serve_interrupt(SIODriver *siop) { UART_UARTIMSC_PEIM | UART_UARTIMSC_FEIM); /* Waiting thread woken, if any.*/ - __sio_wakeup_events(siop); + __sio_wakeup_errors(siop); } /* Idle RX event.*/ diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.c b/os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.c index a4afb1043..ceb9d2b2a 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.c @@ -458,13 +458,13 @@ void sio_lld_update_enable_flags(SIODriver *siop) { cr2irq = siop->usart->CR2 & ~(USART_CR2_LBDIE); cr3irq = siop->usart->CR3 & ~(USART_CR3_EIE); - cr1irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_FL_RXNOTEMPY_POS, USART_CR1_RXNEIE_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_FL_TXNOTFULL_POS, USART_CR1_TXEIE_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_FL_RXIDLE_POS, USART_CR1_IDLEIE_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_TXDONE, SIO_FL_TXDONE_POS, USART_CR1_TCIE_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR1_PEIE_Pos); - cr2irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR2_LBDIE_Pos); - cr3irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR3_EIE_Pos); + cr1irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_MSK_RXNOTEMPY_POS, USART_CR1_RXNEIE_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_MSK_TXNOTFULL_POS, USART_CR1_TXEIE_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_MSK_RXIDLE_POS, USART_CR1_IDLEIE_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_TXDONE, SIO_MSK_TXDONE_POS, USART_CR1_TCIE_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR1_PEIE_Pos); + cr2irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR2_LBDIE_Pos); + cr3irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR3_EIE_Pos); /* Setting up the operation.*/ siop->usart->CR1 = cr1irq; @@ -551,6 +551,42 @@ sioevents_t sio_lld_get_and_clear_events(SIODriver *siop) { return events; } +/** + * @brief Returns the pending SIO event flags. + * + * @param[in] siop pointer to the @p SIODriver object + * @return The pending event flags. + * + * @notapi + */ +sioevents_t sio_lld_get_events(SIODriver *siop) { + uint32_t isr; + sioevents_t events; + + /* Getting all ISR flags. + NOTE: Do not trust the position of other bits in ISR/ICR because + some scientist decided to use different positions for some + of them.*/ + isr = siop->usart->ISR & (SIO_LLD_ISR_RX_ERRORS | + USART_ISR_RXNE | + USART_ISR_IDLE | + USART_ISR_TXE | + USART_ISR_TC); + + /* Translating the status flags in SIO events.*/ + events = __sio_reloc_field(isr, USART_ISR_RXNE_Msk, USART_ISR_RXNE_Pos, SIO_EV_RXNOTEMPY_POS) | + __sio_reloc_field(isr, USART_ISR_TXE_Msk, USART_ISR_TXE_Pos, SIO_EV_TXNOTFULL_POS) | + __sio_reloc_field(isr, USART_ISR_IDLE_Msk, USART_ISR_IDLE_Pos, SIO_EV_RXIDLE_POS) | + __sio_reloc_field(isr, USART_ISR_TC_Msk, USART_ISR_TC_Pos, SIO_EV_TXDONE_POS) | + __sio_reloc_field(isr, USART_ISR_LBDF_Msk, USART_ISR_LBDF_Pos, SIO_EV_BREAK_POS) | + __sio_reloc_field(isr, USART_ISR_PE_Msk, USART_ISR_PE_Pos, SIO_EV_PARITY_ERR_POS) | + __sio_reloc_field(isr, USART_ISR_FE_Msk, USART_ISR_FE_Pos, SIO_EV_FRAMING_ERR_POS) | + __sio_reloc_field(isr, USART_ISR_NE_Msk, USART_ISR_NE_Pos, SIO_EV_NOISE_ERR_POS) | + __sio_reloc_field(isr, USART_ISR_ORE_Msk, USART_ISR_ORE_Pos, SIO_EV_OVERRUN_ERR_POS); + + return events; +} + /** * @brief Reads data from the RX FIFO. * @details The function is not blocking, it writes frames until there @@ -746,7 +782,7 @@ void sio_lld_serve_interrupt(SIODriver *siop) { cr1 &= ~USART_CR1_PEIE; /* Waiting thread woken, if any.*/ - __sio_wakeup_events(siop); + __sio_wakeup_errors(siop); } /* Idle RX event.*/ diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.h b/os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.h index b7fe1bdb0..b3bed961c 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.h +++ b/os/hal/ports/STM32/LLD/USARTv2/hal_sio_lld.h @@ -399,6 +399,7 @@ extern "C" { void sio_lld_update_enable_flags(SIODriver *siop); sioevents_t sio_lld_get_and_clear_errors(SIODriver *siop); sioevents_t sio_lld_get_and_clear_events(SIODriver *siop); + sioevents_t sio_lld_get_events(SIODriver *siop); size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n); size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n); msg_t sio_lld_get(SIODriver *siop); diff --git a/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.c b/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.c index 7778d8d26..864abf55e 100644 --- a/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.c @@ -510,13 +510,13 @@ void sio_lld_update_enable_flags(SIODriver *siop) { cr2irq = siop->usart->CR2 & ~(USART_CR2_LBDIE); cr3irq = siop->usart->CR3 & ~(USART_CR3_RXFTIE | USART_CR3_TXFTIE | USART_CR3_EIE); - cr1irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_FL_RXIDLE_POS, USART_CR1_IDLEIE_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_TXDONE, SIO_FL_TXDONE_POS, USART_CR1_TCIE_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR1_PEIE_Pos); - cr2irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR2_LBDIE_Pos); - cr3irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_FL_RXNOTEMPY_POS, USART_CR3_RXFTIE_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_FL_TXNOTFULL_POS, USART_CR3_TXFTIE_Pos) | - __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR3_EIE_Pos); + cr1irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_MSK_RXIDLE_POS, USART_CR1_IDLEIE_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_TXDONE, SIO_MSK_TXDONE_POS, USART_CR1_TCIE_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR1_PEIE_Pos); + cr2irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR2_LBDIE_Pos); + cr3irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_MSK_RXNOTEMPY_POS, USART_CR3_RXFTIE_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_MSK_TXNOTFULL_POS, USART_CR3_TXFTIE_Pos) | + __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR3_EIE_Pos); /* Setting up the operation.*/ siop->usart->CR1 = cr1irq; @@ -603,6 +603,42 @@ sioevents_t sio_lld_get_and_clear_events(SIODriver *siop) { return events; } +/** + * @brief Returns the pending SIO event flags. + * + * @param[in] siop pointer to the @p SIODriver object + * @return The pending event flags. + * + * @notapi + */ +sioevents_t sio_lld_get_events(SIODriver *siop) { + uint32_t isr; + sioevents_t events; + + /* Getting all ISR flags. + NOTE: Do not trust the position of other bits in ISR/ICR because + some scientist decided to use different positions for some + of them.*/ + isr = siop->usart->ISR & (SIO_LLD_ISR_RX_ERRORS | + USART_ISR_RXNE_RXFNE | + USART_ISR_IDLE | + USART_ISR_TXE_TXFNF | + USART_ISR_TC); + + /* Translating the status flags in SIO events.*/ + events = __sio_reloc_field(isr, USART_ISR_RXNE_RXFNE_Msk, USART_ISR_RXNE_RXFNE_Pos, SIO_EV_RXNOTEMPY_POS) | + __sio_reloc_field(isr, USART_ISR_TXE_TXFNF_Msk, USART_ISR_TXE_TXFNF_Pos, SIO_EV_TXNOTFULL_POS) | + __sio_reloc_field(isr, USART_ISR_IDLE_Msk, USART_ISR_IDLE_Pos, SIO_EV_RXIDLE_POS) | + __sio_reloc_field(isr, USART_ISR_TC_Msk, USART_ISR_TC_Pos, SIO_EV_TXDONE_POS) | + __sio_reloc_field(isr, USART_ISR_LBDF_Msk, USART_ISR_LBDF_Pos, SIO_EV_BREAK_POS) | + __sio_reloc_field(isr, USART_ISR_PE_Msk, USART_ISR_PE_Pos, SIO_EV_PARITY_ERR_POS) | + __sio_reloc_field(isr, USART_ISR_FE_Msk, USART_ISR_FE_Pos, SIO_EV_FRAMING_ERR_POS) | + __sio_reloc_field(isr, USART_ISR_NE_Msk, USART_ISR_NE_Pos, SIO_EV_NOISE_ERR_POS) | + __sio_reloc_field(isr, USART_ISR_ORE_Msk, USART_ISR_ORE_Pos, SIO_EV_OVERRUN_ERR_POS); + + return events; +} + /** * @brief Reads data from the RX FIFO. * @details The function is not blocking, it writes frames until there @@ -798,7 +834,7 @@ void sio_lld_serve_interrupt(SIODriver *siop) { cr1 &= ~USART_CR1_PEIE; /* Waiting thread woken, if any.*/ - __sio_wakeup_events(siop); + __sio_wakeup_errors(siop); } /* Idle RX event.*/ diff --git a/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.h b/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.h index a2fd7837c..b08245701 100644 --- a/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.h +++ b/os/hal/ports/STM32/LLD/USARTv3/hal_sio_lld.h @@ -454,6 +454,7 @@ extern "C" { void sio_lld_update_enable_flags(SIODriver *siop); sioevents_t sio_lld_get_and_clear_errors(SIODriver *siop); sioevents_t sio_lld_get_and_clear_events(SIODriver *siop); + sioevents_t sio_lld_get_events(SIODriver *siop); size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n); size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n); msg_t sio_lld_get(SIODriver *siop);