Added ISR suppression macros, preparation for new IRQ handling.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13841 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2020-09-07 06:50:10 +00:00
parent 8d97d5f7ef
commit b18ce2f1ca
4 changed files with 143 additions and 109 deletions

View File

@ -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 */
/** @} */

View File

@ -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

View File

@ -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 */
/** @} */

View File

@ -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