diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c index 188740e5a..59e2cec4a 100644 --- a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c @@ -174,65 +174,6 @@ static void set_error(SerialDriver *sdp, uint16_t sr) { chnAddFlagsI(sdp, sts); } -/** - * @brief Common IRQ handler. - * - * @param[in] sdp communication channel associated to the USART - */ -static void serve_interrupt(SerialDriver *sdp) { - USART_TypeDef *u = sdp->usart; - uint16_t cr1 = u->CR1; - uint16_t sr = u->SR; - - /* Special case, LIN break detection.*/ - if (sr & USART_SR_LBD) { - osalSysLockFromISR(); - chnAddFlagsI(sdp, SD_BREAK_DETECTED); - u->SR = ~USART_SR_LBD; - osalSysUnlockFromISR(); - } - - /* Data available.*/ - osalSysLockFromISR(); - while (sr & (USART_SR_RXNE | USART_SR_ORE | USART_SR_NE | USART_SR_FE | - USART_SR_PE)) { - uint8_t b; - - /* Error condition detection.*/ - if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) - set_error(sdp, sr); - b = (uint8_t)u->DR & sdp->rxmask; - if (sr & USART_SR_RXNE) - sdIncomingDataI(sdp, b); - sr = u->SR; - } - osalSysUnlockFromISR(); - - /* Transmission buffer empty.*/ - if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) { - msg_t b; - osalSysLockFromISR(); - b = oqGetI(&sdp->oqueue); - if (b < MSG_OK) { - chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); - u->CR1 = cr1 & ~USART_CR1_TXEIE; - } - else - u->DR = b; - osalSysUnlockFromISR(); - } - - /* Physical transmission end.*/ - if ((cr1 & USART_CR1_TCIE) && (sr & USART_SR_TC)) { - osalSysLockFromISR(); - if (oqIsEmptyI(&sdp->oqueue)) { - chnAddFlagsI(sdp, CHN_TRANSMISSION_END); - u->CR1 = cr1 & ~USART_CR1_TCIE; - } - osalSysUnlockFromISR(); - } -} - #if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__) static void notify1(io_queue_t *qp) { @@ -302,6 +243,7 @@ static void notify8(io_queue_t *qp) { /*===========================================================================*/ #if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__) +#if !defined(STM32_USART1_SUPPRESS_ISR) #if !defined(STM32_USART1_HANDLER) #error "STM32_USART1_HANDLER not defined" #endif @@ -314,13 +256,15 @@ OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD1); + sd_lld_serve_interrupt(&SD1); OSAL_IRQ_EPILOGUE(); } #endif +#endif #if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__) +#if !defined(STM32_USART2_SUPPRESS_ISR) #if !defined(STM32_USART2_HANDLER) #error "STM32_USART2_HANDLER not defined" #endif @@ -333,13 +277,15 @@ OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD2); + sd_lld_serve_interrupt(&SD2); OSAL_IRQ_EPILOGUE(); } #endif +#endif #if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__) +#if !defined(STM32_USART3_SUPPRESS_ISR) #if !defined(STM32_USART3_HANDLER) #error "STM32_USART3_HANDLER not defined" #endif @@ -352,13 +298,15 @@ OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD3); + sd_lld_serve_interrupt(&SD3); OSAL_IRQ_EPILOGUE(); } #endif +#endif #if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__) +#if !defined(STM32_UART4_SUPPRESS_ISR) #if !defined(STM32_UART4_HANDLER) #error "STM32_UART4_HANDLER not defined" #endif @@ -371,13 +319,15 @@ OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD4); + sd_lld_serve_interrupt(&SD4); OSAL_IRQ_EPILOGUE(); } #endif +#endif #if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__) +#if !defined(STM32_UART5_SUPPRESS_ISR) #if !defined(STM32_UART5_HANDLER) #error "STM32_UART5_HANDLER not defined" #endif @@ -390,13 +340,15 @@ OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD5); + sd_lld_serve_interrupt(&SD5); OSAL_IRQ_EPILOGUE(); } #endif +#endif #if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__) +#if !defined(STM32_USART6_SUPPRESS_ISR) #if !defined(STM32_USART6_HANDLER) #error "STM32_USART6_HANDLER not defined" #endif @@ -409,13 +361,15 @@ OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD6); + sd_lld_serve_interrupt(&SD6); OSAL_IRQ_EPILOGUE(); } #endif +#endif #if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__) +#if !defined(STM32_UART8_SUPPRESS_ISR) #if !defined(STM32_UART7_HANDLER) #error "STM32_UART7_HANDLER not defined" #endif @@ -428,13 +382,15 @@ OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD7); + sd_lld_serve_interrupt(&SD7); OSAL_IRQ_EPILOGUE(); } #endif +#endif #if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__) +#if !defined(STM32_UART8_SUPPRESS_ISR) #if !defined(STM32_UART8_HANDLER) #error "STM32_UART8_HANDLER not defined" #endif @@ -447,11 +403,12 @@ OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD8); + sd_lld_serve_interrupt(&SD8); OSAL_IRQ_EPILOGUE(); } #endif +#endif /*===========================================================================*/ /* Driver exported functions. */ @@ -645,6 +602,65 @@ void sd_lld_stop(SerialDriver *sdp) { } } +/** + * @brief Common IRQ handler. + * + * @param[in] sdp communication channel associated to the USART + */ +void sd_lld_serve_interrupt(SerialDriver *sdp) { + USART_TypeDef *u = sdp->usart; + uint16_t cr1 = u->CR1; + uint16_t sr = u->SR; + + /* Special case, LIN break detection.*/ + if (sr & USART_SR_LBD) { + osalSysLockFromISR(); + chnAddFlagsI(sdp, SD_BREAK_DETECTED); + u->SR = ~USART_SR_LBD; + osalSysUnlockFromISR(); + } + + /* Data available.*/ + osalSysLockFromISR(); + while (sr & (USART_SR_RXNE | USART_SR_ORE | USART_SR_NE | USART_SR_FE | + USART_SR_PE)) { + uint8_t b; + + /* Error condition detection.*/ + if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) + set_error(sdp, sr); + b = (uint8_t)u->DR & sdp->rxmask; + if (sr & USART_SR_RXNE) + sdIncomingDataI(sdp, b); + sr = u->SR; + } + osalSysUnlockFromISR(); + + /* Transmission buffer empty.*/ + if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) { + msg_t b; + osalSysLockFromISR(); + b = oqGetI(&sdp->oqueue); + if (b < MSG_OK) { + chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); + u->CR1 = cr1 & ~USART_CR1_TXEIE; + } + else + u->DR = b; + osalSysUnlockFromISR(); + } + + /* Physical transmission end.*/ + if ((cr1 & USART_CR1_TCIE) && (sr & USART_SR_TC)) { + osalSysLockFromISR(); + if (oqIsEmptyI(&sdp->oqueue)) { + chnAddFlagsI(sdp, CHN_TRANSMISSION_END); + u->CR1 = cr1 & ~USART_CR1_TCIE; + } + osalSysUnlockFromISR(); + } +} + #endif /* HAL_USE_SERIAL */ /** @} */ diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h index de259a70d..6300972e6 100644 --- a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h +++ b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h @@ -351,6 +351,7 @@ extern "C" { void sd_lld_init(void); void sd_lld_start(SerialDriver *sdp, const SerialConfig *config); void sd_lld_stop(SerialDriver *sdp); + void sd_lld_serve_interrupt(SerialDriver *sdp); #ifdef __cplusplus } #endif diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c index d7da0467d..41ac325b8 100644 --- a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c @@ -321,45 +321,12 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { _uart_tx1_isr_code(uartp); } -/** - * @brief USART common service routine. - * - * @param[in] uartp pointer to the @p UARTDriver object - */ -static void serve_usart_irq(UARTDriver *uartp) { - uint16_t sr; - USART_TypeDef *u = uartp->usart; - uint32_t cr1 = u->CR1; - - sr = u->SR; /* SR reset step 1.*/ - (void)u->DR; /* SR reset step 2.*/ - - if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE | - USART_SR_FE | USART_SR_PE)) { - u->SR = ~USART_SR_LBD; - _uart_rx_error_isr_code(uartp, translate_errors(sr)); - } - - if ((sr & USART_SR_TC) && (cr1 & USART_CR1_TCIE)) { - /* TC interrupt cleared and disabled.*/ - u->SR = ~USART_SR_TC; - u->CR1 = cr1 & ~USART_CR1_TCIE; - - /* End of transmission, a callback is generated.*/ - _uart_tx2_isr_code(uartp); - } - - /* Timeout interrupt sources are only checked if enabled in CR1.*/ - if ((cr1 & USART_CR1_IDLEIE) && (sr & USART_SR_IDLE)) { - _uart_timeout_isr_code(uartp); - } -} - /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ #if STM32_UART_USE_USART1 || defined(__DOXYGEN__) +#if !defined(STM32_USART1_SUPPRESS_ISR) #if !defined(STM32_USART1_HANDLER) #error "STM32_USART1_HANDLER not defined" #endif @@ -372,13 +339,15 @@ OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_usart_irq(&UARTD1); + uart_lld_serve_interrupt(&UARTD1); OSAL_IRQ_EPILOGUE(); } +#endif #endif /* STM32_UART_USE_USART1 */ #if STM32_UART_USE_USART2 || defined(__DOXYGEN__) +#if !defined(STM32_USART2_SUPPRESS_ISR) #if !defined(STM32_USART2_HANDLER) #error "STM32_USART2_HANDLER not defined" #endif @@ -391,13 +360,15 @@ OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_usart_irq(&UARTD2); + uart_lld_serve_interrupt(&UARTD2); OSAL_IRQ_EPILOGUE(); } +#endif #endif /* STM32_UART_USE_USART2 */ #if STM32_UART_USE_USART3 || defined(__DOXYGEN__) +#if !defined(STM32_USART3_SUPPRESS_ISR) #if !defined(STM32_USART3_HANDLER) #error "STM32_USART3_HANDLER not defined" #endif @@ -410,13 +381,15 @@ OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_usart_irq(&UARTD3); + uart_lld_serve_interrupt(&UARTD3); OSAL_IRQ_EPILOGUE(); } +#endif #endif /* STM32_UART_USE_USART3 */ #if STM32_UART_USE_UART4 || defined(__DOXYGEN__) +#if !defined(STM32_UART4_SUPPRESS_ISR) #if !defined(STM32_UART4_HANDLER) #error "STM32_UART4_HANDLER not defined" #endif @@ -429,13 +402,15 @@ OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_usart_irq(&UARTD4); + uart_lld_serve_interrupt(&UARTD4); OSAL_IRQ_EPILOGUE(); } +#endif #endif /* STM32_UART_USE_UART4 */ #if STM32_UART_USE_UART5 || defined(__DOXYGEN__) +#if !defined(STM32_UART5_SUPPRESS_ISR) #if !defined(STM32_UART5_HANDLER) #error "STM32_UART5_HANDLER not defined" #endif @@ -448,13 +423,15 @@ OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_usart_irq(&UARTD5); + uart_lld_serve_interrupt(&UARTD5); OSAL_IRQ_EPILOGUE(); } +#endif #endif /* STM32_UART_USE_UART5 */ #if STM32_UART_USE_USART6 || defined(__DOXYGEN__) +#if !defined(STM32_USART6_SUPPRESS_ISR) #if !defined(STM32_USART6_HANDLER) #error "STM32_USART6_HANDLER not defined" #endif @@ -467,13 +444,15 @@ OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_usart_irq(&UARTD6); + uart_lld_serve_interrupt(&UARTD6); OSAL_IRQ_EPILOGUE(); } +#endif #endif /* STM32_UART_USE_USART6 */ #if STM32_UART_USE_UART7 || defined(__DOXYGEN__) +#if !defined(STM32_UART7_SUPPRESS_ISR) #if !defined(STM32_UART7_HANDLER) #error "STM32_UART7_HANDLER not defined" #endif @@ -486,13 +465,15 @@ OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_usart_irq(&UARTD7); + uart_lld_serve_interrupt(&UARTD7); OSAL_IRQ_EPILOGUE(); } +#endif #endif /* STM32_UART_USE_UART7 */ #if STM32_UART_USE_UART8 || defined(__DOXYGEN__) +#if !defined(STM32_UART8_SUPPRESS_ISR) #if !defined(STM32_UART8_HANDLER) #error "STM32_UART8_HANDLER not defined" #endif @@ -505,10 +486,11 @@ OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) { OSAL_IRQ_PROLOGUE(); - serve_usart_irq(&UARTD8); + uart_lld_serve_interrupt(&UARTD8); OSAL_IRQ_EPILOGUE(); } +#endif #endif /* STM32_UART_USE_UART8 */ /*===========================================================================*/ @@ -1003,6 +985,40 @@ size_t uart_lld_stop_receive(UARTDriver *uartp) { return n; } +/** + * @brief USART common service routine. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +void uart_lld_serve_interrupt(UARTDriver *uartp) { + uint16_t sr; + USART_TypeDef *u = uartp->usart; + uint32_t cr1 = u->CR1; + + sr = u->SR; /* SR reset step 1.*/ + (void)u->DR; /* SR reset step 2.*/ + + if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE | + USART_SR_FE | USART_SR_PE)) { + u->SR = ~USART_SR_LBD; + _uart_rx_error_isr_code(uartp, translate_errors(sr)); + } + + if ((sr & USART_SR_TC) && (cr1 & USART_CR1_TCIE)) { + /* TC interrupt cleared and disabled.*/ + u->SR = ~USART_SR_TC; + u->CR1 = cr1 & ~USART_CR1_TCIE; + + /* End of transmission, a callback is generated.*/ + _uart_tx2_isr_code(uartp); + } + + /* Timeout interrupt sources are only checked if enabled in CR1.*/ + if ((cr1 & USART_CR1_IDLEIE) && (sr & USART_SR_IDLE)) { + _uart_timeout_isr_code(uartp); + } +} + #endif /* HAL_USE_UART */ /** @} */ diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h index ae0f4d36d..99acfc611 100644 --- a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h +++ b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h @@ -747,6 +747,7 @@ extern "C" { size_t uart_lld_stop_send(UARTDriver *uartp); void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf); size_t uart_lld_stop_receive(UARTDriver *uartp); + void uart_lld_serve_interrupt(UARTDriver *uartp); #ifdef __cplusplus } #endif