Tentative fixes to STM32 SIO drivers.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15394 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
a5f5513642
commit
60647952ea
|
@ -713,7 +713,7 @@ msg_t sio_lld_control(SIODriver *siop, unsigned int operation, void *arg) {
|
||||||
*/
|
*/
|
||||||
void sio_lld_serve_interrupt(SIODriver *siop) {
|
void sio_lld_serve_interrupt(SIODriver *siop) {
|
||||||
USART_TypeDef *u = siop->usart;
|
USART_TypeDef *u = siop->usart;
|
||||||
uint32_t isr, cr1, cr3, evtmask;
|
uint32_t isr, cr1, cr2, cr3, evtmask, irqmask;
|
||||||
|
|
||||||
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
|
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
|
||||||
|
|
||||||
|
@ -721,18 +721,25 @@ void sio_lld_serve_interrupt(SIODriver *siop) {
|
||||||
disabled instead.*/
|
disabled instead.*/
|
||||||
isr = u->ISR;
|
isr = u->ISR;
|
||||||
|
|
||||||
/* One read on control registers.*/
|
/* Read on control registers.*/
|
||||||
cr1 = u->CR1;
|
cr1 = u->CR1;
|
||||||
|
cr2 = u->CR2;
|
||||||
cr3 = u->CR3;
|
cr3 = u->CR3;
|
||||||
|
|
||||||
/* Enabled errors/events handling.*/
|
/* Enabled errors/events handling.*/
|
||||||
evtmask = isr & (USART_ISR_PE | USART_ISR_LBDF | USART_ISR_FE |
|
irqmask = ((cr1 & USART_CR1_PEIE) != 0U ? USART_ISR_PE : 0U) |
|
||||||
USART_ISR_ORE | USART_ISR_NE);
|
((cr2 & USART_CR2_LBDIE) != 0U ? USART_ISR_LBDF : 0U) |
|
||||||
|
((cr3 & USART_CR3_EIE) != 0U ? USART_ISR_FE |
|
||||||
|
USART_ISR_ORE |
|
||||||
|
USART_ISR_NE : 0U);
|
||||||
|
evtmask = isr & irqmask;
|
||||||
if (evtmask != 0U) {
|
if (evtmask != 0U) {
|
||||||
uint32_t cr2;
|
|
||||||
|
|
||||||
/* One read on control registers.*/
|
/* Disabling event sources until errors are recognized by the
|
||||||
cr2 = u->CR2;
|
application.*/
|
||||||
|
u->CR1 = cr1 & ~USART_CR1_PEIE;
|
||||||
|
u->CR2 = cr2 & ~USART_CR2_LBDIE;
|
||||||
|
u->CR3 = cr3 & ~USART_CR3_EIE;
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
/* The callback is invoked if defined.*/
|
||||||
__sio_callback_rx_evt(siop);
|
__sio_callback_rx_evt(siop);
|
||||||
|
@ -740,75 +747,74 @@ void sio_lld_serve_interrupt(SIODriver *siop) {
|
||||||
/* Waiting thread woken, if any.*/
|
/* Waiting thread woken, if any.*/
|
||||||
__sio_wakeup_rx(siop, SIO_MSG_ERRORS);
|
__sio_wakeup_rx(siop, SIO_MSG_ERRORS);
|
||||||
|
|
||||||
/* Disabling event sources until errors are recognized by the
|
/* Values could have been changed by the callback, CR2-CR3 no more needed.*/
|
||||||
application.*/
|
cr1 = u->CR1;
|
||||||
cr1 &= ~USART_CR1_PEIE;
|
|
||||||
cr2 &= ~USART_CR2_LBDIE;
|
|
||||||
cr3 &= ~USART_CR3_EIE;
|
|
||||||
|
|
||||||
/* One write on control registers.*/
|
|
||||||
u->CR2 = cr2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RX FIFO is non-empty.*/
|
/* RX FIFO is non-empty.*/
|
||||||
if (((cr1 & USART_CR1_RXNEIE) != 0U) &&
|
if (((cr1 & USART_CR1_RXNEIE) != 0U) &&
|
||||||
(isr & USART_ISR_RXNE) != 0U) {
|
(isr & USART_ISR_RXNE) != 0U) {
|
||||||
|
|
||||||
|
/* Called once then the interrupt source is disabled.*/
|
||||||
|
u->CR1 = cr1 & ~USART_CR1_RXNEIE;
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
/* The callback is invoked if defined.*/
|
||||||
__sio_callback_rx(siop);
|
__sio_callback_rx(siop);
|
||||||
|
|
||||||
/* Waiting thread woken, if any.*/
|
/* Waiting thread woken, if any.*/
|
||||||
__sio_wakeup_rx(siop, MSG_OK);
|
__sio_wakeup_rx(siop, MSG_OK);
|
||||||
|
|
||||||
/* Called once then the interrupt source is disabled.*/
|
/* Values could have been changed by the callback, CR2-CR3 no more needed.*/
|
||||||
cr1 &= ~USART_CR1_RXNEIE;
|
cr1 = u->CR1;
|
||||||
}
|
|
||||||
|
|
||||||
/* RX idle condition.*/
|
|
||||||
if (((cr1 & USART_CR1_IDLEIE) != 0U) &&
|
|
||||||
(isr & USART_ISR_IDLE) != 0U) {
|
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
|
||||||
__sio_callback_rx_idle(siop);
|
|
||||||
|
|
||||||
/* Waiting thread woken, if any.*/
|
|
||||||
__sio_wakeup_rx(siop, SIO_MSG_IDLE);
|
|
||||||
|
|
||||||
/* The idle flag requires clearing, it stays enabled.*/
|
|
||||||
u->ICR = USART_ISR_IDLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TX FIFO is non-full.*/
|
/* TX FIFO is non-full.*/
|
||||||
if (((cr1 & USART_CR1_TXEIE) != 0U) &&
|
if (((cr1 & USART_CR1_TXEIE) != 0U) &&
|
||||||
(isr & USART_ISR_TXE) != 0U) {
|
(isr & USART_ISR_TXE) != 0U) {
|
||||||
|
|
||||||
|
/* Called once then the interrupt is disabled.*/
|
||||||
|
u->CR1 = cr1 & ~USART_CR1_TXEIE;
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
/* The callback is invoked if defined.*/
|
||||||
__sio_callback_tx(siop);
|
__sio_callback_tx(siop);
|
||||||
|
|
||||||
/* Waiting thread woken, if any.*/
|
/* Waiting thread woken, if any.*/
|
||||||
__sio_wakeup_tx(siop, MSG_OK);
|
__sio_wakeup_tx(siop, MSG_OK);
|
||||||
|
|
||||||
/* Called once then the interrupt is disabled.*/
|
/* Values could have been changed by the callback, CR2-CR3 no more needed.*/
|
||||||
cr1 &= ~USART_CR1_TXEIE;
|
cr1 = u->CR1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RX idle condition.*/
|
||||||
|
if (((cr1 & USART_CR1_IDLEIE) != 0U) &&
|
||||||
|
(isr & USART_ISR_IDLE) != 0U) {
|
||||||
|
|
||||||
|
/* The idle flag requires clearing, it stays enabled.*/
|
||||||
|
u->ICR = USART_ISR_IDLE;
|
||||||
|
|
||||||
|
/* The callback is invoked if defined.*/
|
||||||
|
__sio_callback_rx_idle(siop);
|
||||||
|
|
||||||
|
/* Waiting thread woken, if any.*/
|
||||||
|
__sio_wakeup_rx(siop, SIO_MSG_IDLE);
|
||||||
|
|
||||||
|
/* Values could have been changed by the callback, CR2-CR3 no more needed.*/
|
||||||
|
cr1 = u->CR1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Physical transmission end.*/
|
/* Physical transmission end.*/
|
||||||
if (((cr1 & USART_CR1_TCIE) != 0U) &&
|
if (((cr1 & USART_CR1_TCIE) != 0U) &&
|
||||||
(isr & USART_ISR_TC) != 0U) {
|
(isr & USART_ISR_TC) != 0U) {
|
||||||
|
|
||||||
|
/* Called once then the interrupt is disabled.*/
|
||||||
|
u->CR1 = cr1 & ~USART_CR1_TCIE;
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
/* The callback is invoked if defined.*/
|
||||||
__sio_callback_tx_end(siop);
|
__sio_callback_tx_end(siop);
|
||||||
|
|
||||||
/* Waiting thread woken, if any.*/
|
/* Waiting thread woken, if any.*/
|
||||||
__sio_wakeup_txend(siop, MSG_OK);
|
__sio_wakeup_txend(siop, MSG_OK);
|
||||||
|
|
||||||
/* Called once then the interrupt is disabled.*/
|
|
||||||
cr1 &= ~USART_CR1_TCIE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* One write on control registers.*/
|
|
||||||
u->CR1 = cr1;
|
|
||||||
u->CR3 = cr3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAL_USE_SIO == TRUE */
|
#endif /* HAL_USE_SIO == TRUE */
|
||||||
|
|
|
@ -720,7 +720,7 @@ msg_t sio_lld_control(SIODriver *siop, unsigned int operation, void *arg) {
|
||||||
*/
|
*/
|
||||||
void sio_lld_serve_interrupt(SIODriver *siop) {
|
void sio_lld_serve_interrupt(SIODriver *siop) {
|
||||||
USART_TypeDef *u = siop->usart;
|
USART_TypeDef *u = siop->usart;
|
||||||
uint32_t isr, cr1, cr3, evtmask;
|
uint32_t isr, cr1, cr2, cr3, evtmask, irqmask;
|
||||||
|
|
||||||
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
|
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
|
||||||
|
|
||||||
|
@ -728,18 +728,25 @@ void sio_lld_serve_interrupt(SIODriver *siop) {
|
||||||
disabled instead.*/
|
disabled instead.*/
|
||||||
isr = u->ISR;
|
isr = u->ISR;
|
||||||
|
|
||||||
/* One read on control registers.*/
|
/* Read on control registers.*/
|
||||||
cr1 = u->CR1;
|
cr1 = u->CR1;
|
||||||
|
cr2 = u->CR2;
|
||||||
cr3 = u->CR3;
|
cr3 = u->CR3;
|
||||||
|
|
||||||
/* Enabled errors/events handling.*/
|
/* Enabled errors/events handling.*/
|
||||||
evtmask = isr & (USART_ISR_PE | USART_ISR_LBDF | USART_ISR_FE |
|
irqmask = ((cr1 & USART_CR1_PEIE) != 0U ? USART_ISR_PE : 0U) |
|
||||||
USART_ISR_ORE | USART_ISR_NE);
|
((cr2 & USART_CR2_LBDIE) != 0U ? USART_ISR_LBDF : 0U) |
|
||||||
|
((cr3 & USART_CR3_EIE) != 0U ? USART_ISR_FE |
|
||||||
|
USART_ISR_ORE |
|
||||||
|
USART_ISR_NE : 0U);
|
||||||
|
evtmask = isr & irqmask;
|
||||||
if (evtmask != 0U) {
|
if (evtmask != 0U) {
|
||||||
uint32_t cr2;
|
|
||||||
|
|
||||||
/* One read on control registers.*/
|
/* Disabling event sources until errors are recognized by the
|
||||||
cr2 = u->CR2;
|
application.*/
|
||||||
|
u->CR1 = cr1 & ~USART_CR1_PEIE;
|
||||||
|
u->CR2 = cr2 & ~USART_CR2_LBDIE;
|
||||||
|
u->CR3 = cr3 & ~USART_CR3_EIE;
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
/* The callback is invoked if defined.*/
|
||||||
__sio_callback_rx_evt(siop);
|
__sio_callback_rx_evt(siop);
|
||||||
|
@ -747,75 +754,76 @@ void sio_lld_serve_interrupt(SIODriver *siop) {
|
||||||
/* Waiting thread woken, if any.*/
|
/* Waiting thread woken, if any.*/
|
||||||
__sio_wakeup_rx(siop, SIO_MSG_ERRORS);
|
__sio_wakeup_rx(siop, SIO_MSG_ERRORS);
|
||||||
|
|
||||||
/* Disabling event sources until errors are recognized by the
|
/* Values could have been changed by the callback, CR2 no more needed.*/
|
||||||
application.*/
|
cr1 = u->CR1;
|
||||||
cr1 &= ~USART_CR1_PEIE;
|
cr3 = u->CR3;
|
||||||
cr2 &= ~USART_CR2_LBDIE;
|
|
||||||
cr3 &= ~USART_CR3_EIE;
|
|
||||||
|
|
||||||
/* One write on control registers.*/
|
|
||||||
u->CR2 = cr2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RX FIFO is non-empty.*/
|
/* RX FIFO is non-empty.*/
|
||||||
if (((cr3 & USART_CR3_RXFTIE) != 0U) &&
|
if (((cr3 & USART_CR3_RXFTIE) != 0U) &&
|
||||||
(isr & USART_ISR_RXFT) != 0U) {
|
(isr & USART_ISR_RXFT) != 0U) {
|
||||||
|
|
||||||
|
/* Called once then the interrupt source is disabled.*/
|
||||||
|
u->CR3 = cr3 & ~USART_CR3_RXFTIE;
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
/* The callback is invoked if defined.*/
|
||||||
__sio_callback_rx(siop);
|
__sio_callback_rx(siop);
|
||||||
|
|
||||||
/* Waiting thread woken, if any.*/
|
/* Waiting thread woken, if any.*/
|
||||||
__sio_wakeup_rx(siop, MSG_OK);
|
__sio_wakeup_rx(siop, MSG_OK);
|
||||||
|
|
||||||
/* Called once then the interrupt source is disabled.*/
|
/* Values could have been changed by the callback, CR2 no more needed.*/
|
||||||
cr3 &= ~USART_CR3_RXFTIE;
|
cr1 = u->CR1;
|
||||||
}
|
cr3 = u->CR3;
|
||||||
|
|
||||||
/* RX idle condition.*/
|
|
||||||
if (((cr1 & USART_CR1_IDLEIE) != 0U) &&
|
|
||||||
(isr & USART_ISR_IDLE) != 0U) {
|
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
|
||||||
__sio_callback_rx_idle(siop);
|
|
||||||
|
|
||||||
/* Waiting thread woken, if any.*/
|
|
||||||
__sio_wakeup_rx(siop, SIO_MSG_IDLE);
|
|
||||||
|
|
||||||
/* The idle flag requires clearing, it stays enabled.*/
|
|
||||||
u->ICR = USART_ISR_IDLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TX FIFO is non-full.*/
|
/* TX FIFO is non-full.*/
|
||||||
if (((cr3 & USART_CR3_TXFTIE) != 0U) &&
|
if (((cr3 & USART_CR3_TXFTIE) != 0U) &&
|
||||||
(isr & USART_ISR_TXFT) != 0U) {
|
(isr & USART_ISR_TXFT) != 0U) {
|
||||||
|
|
||||||
|
/* Called once then the interrupt is disabled.*/
|
||||||
|
u->CR3 = cr3 & ~USART_CR3_TXFTIE;
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
/* The callback is invoked if defined.*/
|
||||||
__sio_callback_tx(siop);
|
__sio_callback_tx(siop);
|
||||||
|
|
||||||
/* Waiting thread woken, if any.*/
|
/* Waiting thread woken, if any.*/
|
||||||
__sio_wakeup_tx(siop, MSG_OK);
|
__sio_wakeup_tx(siop, MSG_OK);
|
||||||
|
|
||||||
/* Called once then the interrupt is disabled.*/
|
/* Values could have been changed by the callback, CR2-CR3 no more needed.*/
|
||||||
cr3 &= ~USART_CR3_TXFTIE;
|
cr1 = u->CR1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RX idle condition.*/
|
||||||
|
if (((cr1 & USART_CR1_IDLEIE) != 0U) &&
|
||||||
|
(isr & USART_ISR_IDLE) != 0U) {
|
||||||
|
|
||||||
|
/* The idle flag requires clearing, it stays enabled.*/
|
||||||
|
u->ICR = USART_ISR_IDLE;
|
||||||
|
|
||||||
|
/* The callback is invoked if defined.*/
|
||||||
|
__sio_callback_rx_idle(siop);
|
||||||
|
|
||||||
|
/* Waiting thread woken, if any.*/
|
||||||
|
__sio_wakeup_rx(siop, SIO_MSG_IDLE);
|
||||||
|
|
||||||
|
/* Values could have been changed by the callback, CR2-CR3 no more needed.*/
|
||||||
|
cr1 = u->CR1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Physical transmission end.*/
|
/* Physical transmission end.*/
|
||||||
if (((cr1 & USART_CR1_TCIE) != 0U) &&
|
if (((cr1 & USART_CR1_TCIE) != 0U) &&
|
||||||
(isr & USART_ISR_TC) != 0U) {
|
(isr & USART_ISR_TC) != 0U) {
|
||||||
|
|
||||||
|
/* Called once then the interrupt is disabled.*/
|
||||||
|
u->CR1 = cr1 & ~USART_CR1_TCIE;
|
||||||
|
|
||||||
/* The callback is invoked if defined.*/
|
/* The callback is invoked if defined.*/
|
||||||
__sio_callback_tx_end(siop);
|
__sio_callback_tx_end(siop);
|
||||||
|
|
||||||
/* Waiting thread woken, if any.*/
|
/* Waiting thread woken, if any.*/
|
||||||
__sio_wakeup_txend(siop, MSG_OK);
|
__sio_wakeup_txend(siop, MSG_OK);
|
||||||
|
|
||||||
/* Called once then the interrupt is disabled.*/
|
|
||||||
cr1 &= ~USART_CR1_TCIE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* One write on control registers.*/
|
|
||||||
u->CR1 = cr1;
|
|
||||||
u->CR3 = cr3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAL_USE_SIO == TRUE */
|
#endif /* HAL_USE_SIO == TRUE */
|
||||||
|
|
Loading…
Reference in New Issue