Fixed bug #584.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7905 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
e2dbf2c514
commit
d52ee81b3a
|
@ -222,11 +222,10 @@ static void usart_start(UARTDriver *uartp) {
|
||||||
u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
|
u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
|
||||||
u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
|
u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
|
||||||
USART_CR3_EIE;
|
USART_CR3_EIE;
|
||||||
if (uartp->config->txend2_cb == NULL)
|
|
||||||
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
|
/* Mustn't ever set TCIE here - if done, it causes an immediate
|
||||||
else
|
interrupt.*/
|
||||||
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE |
|
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
|
||||||
USART_CR1_TCIE;
|
|
||||||
u->CR1 = uartp->config->cr1 | cr1;
|
u->CR1 = uartp->config->cr1 | cr1;
|
||||||
|
|
||||||
/* Starting the receiver idle loop.*/
|
/* Starting the receiver idle loop.*/
|
||||||
|
@ -292,6 +291,12 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
||||||
|
|
||||||
dmaStreamDisable(uartp->dmatx);
|
dmaStreamDisable(uartp->dmatx);
|
||||||
|
|
||||||
|
/* Only enable TC interrupt if there's a callback attached to it.
|
||||||
|
We have to do it here, rather than earlier, because TC flag is set
|
||||||
|
until transmission starts.*/
|
||||||
|
if (uartp->config->txend2_cb != NULL)
|
||||||
|
uartp->usart->CR1 |= USART_CR1_TCIE;
|
||||||
|
|
||||||
/* A callback is generated, if enabled, after a completed transfer.*/
|
/* A callback is generated, if enabled, after a completed transfer.*/
|
||||||
uartp->txstate = UART_TX_COMPLETE;
|
uartp->txstate = UART_TX_COMPLETE;
|
||||||
if (uartp->config->txend1_cb != NULL)
|
if (uartp->config->txend1_cb != NULL)
|
||||||
|
@ -311,17 +316,22 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
||||||
static void serve_usart_irq(UARTDriver *uartp) {
|
static void serve_usart_irq(UARTDriver *uartp) {
|
||||||
uint16_t sr;
|
uint16_t sr;
|
||||||
USART_TypeDef *u = uartp->usart;
|
USART_TypeDef *u = uartp->usart;
|
||||||
|
uint32_t cr1 = u->CR1;
|
||||||
|
|
||||||
sr = u->SR; /* SR reset step 1.*/
|
sr = u->SR; /* SR reset step 1.*/
|
||||||
(void)u->DR; /* SR reset step 2.*/
|
(void)u->DR; /* SR reset step 2.*/
|
||||||
|
|
||||||
if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE |
|
if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE |
|
||||||
USART_SR_FE | USART_SR_PE)) {
|
USART_SR_FE | USART_SR_PE)) {
|
||||||
u->SR = ~USART_SR_LBD;
|
u->SR = ~USART_SR_LBD;
|
||||||
if (uartp->config->rxerr_cb != NULL)
|
if (uartp->config->rxerr_cb != NULL)
|
||||||
uartp->config->rxerr_cb(uartp, translate_errors(sr));
|
uartp->config->rxerr_cb(uartp, translate_errors(sr));
|
||||||
}
|
}
|
||||||
if (sr & USART_SR_TC) {
|
|
||||||
|
if ((sr & USART_SR_TC) && (cr1 & USART_CR1_TCIE)) {
|
||||||
|
/* TC interrupt cleared and disabled.*/
|
||||||
u->SR = ~USART_SR_TC;
|
u->SR = ~USART_SR_TC;
|
||||||
|
u->CR1 = cr1 & ~USART_CR1_TCIE;
|
||||||
|
|
||||||
/* End of transmission, a callback is generated.*/
|
/* End of transmission, a callback is generated.*/
|
||||||
if (uartp->config->txend2_cb != NULL)
|
if (uartp->config->txend2_cb != NULL)
|
||||||
|
|
|
@ -176,11 +176,10 @@ static void usart_start(UARTDriver *uartp) {
|
||||||
u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
|
u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
|
||||||
u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
|
u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
|
||||||
USART_CR3_EIE;
|
USART_CR3_EIE;
|
||||||
if (uartp->config->txend2_cb == NULL)
|
|
||||||
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
|
/* Mustn't ever set TCIE here - if done, it causes an immediate
|
||||||
else
|
interrupt.*/
|
||||||
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE |
|
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
|
||||||
USART_CR1_TCIE;
|
|
||||||
u->CR1 = uartp->config->cr1 | cr1;
|
u->CR1 = uartp->config->cr1 | cr1;
|
||||||
|
|
||||||
/* Starting the receiver idle loop.*/
|
/* Starting the receiver idle loop.*/
|
||||||
|
@ -246,6 +245,12 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
||||||
|
|
||||||
dmaStreamDisable(uartp->dmatx);
|
dmaStreamDisable(uartp->dmatx);
|
||||||
|
|
||||||
|
/* Only enable TC interrupt if there's a callback attached to it.
|
||||||
|
We have to do it here, rather than earlier, because TC flag is set
|
||||||
|
until transmission starts.*/
|
||||||
|
if (uartp->config->txend2_cb != NULL)
|
||||||
|
uartp->usart->CR1 |= USART_CR1_TCIE;
|
||||||
|
|
||||||
/* A callback is generated, if enabled, after a completed transfer.*/
|
/* A callback is generated, if enabled, after a completed transfer.*/
|
||||||
uartp->txstate = UART_TX_COMPLETE;
|
uartp->txstate = UART_TX_COMPLETE;
|
||||||
if (uartp->config->txend1_cb != NULL)
|
if (uartp->config->txend1_cb != NULL)
|
||||||
|
@ -265,6 +270,7 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
||||||
static void serve_usart_irq(UARTDriver *uartp) {
|
static void serve_usart_irq(UARTDriver *uartp) {
|
||||||
uint32_t isr;
|
uint32_t isr;
|
||||||
USART_TypeDef *u = uartp->usart;
|
USART_TypeDef *u = uartp->usart;
|
||||||
|
uint32_t cr1 = u->CR1;
|
||||||
|
|
||||||
/* Reading and clearing status.*/
|
/* Reading and clearing status.*/
|
||||||
isr = u->ISR;
|
isr = u->ISR;
|
||||||
|
@ -275,7 +281,11 @@ static void serve_usart_irq(UARTDriver *uartp) {
|
||||||
if (uartp->config->rxerr_cb != NULL)
|
if (uartp->config->rxerr_cb != NULL)
|
||||||
uartp->config->rxerr_cb(uartp, translate_errors(isr));
|
uartp->config->rxerr_cb(uartp, translate_errors(isr));
|
||||||
}
|
}
|
||||||
if (isr & USART_ISR_TC) {
|
|
||||||
|
if ((isr & USART_ISR_TC) && (cr1 & USART_CR1_TCIE)) {
|
||||||
|
/* TC interrupt disabled.*/
|
||||||
|
u->CR1 = cr1 & ~USART_CR1_TCIE;
|
||||||
|
|
||||||
/* End of transmission, a callback is generated.*/
|
/* End of transmission, a callback is generated.*/
|
||||||
if (uartp->config->txend2_cb != NULL)
|
if (uartp->config->txend2_cb != NULL)
|
||||||
uartp->config->txend2_cb(uartp);
|
uartp->config->txend2_cb(uartp);
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** 3.0.0p4 ***
|
*** 3.0.0p4 ***
|
||||||
|
- HAL: Fixed spurious TC interrupt in STM32 UART (v1 and v2) driver (bug #584).
|
||||||
- HAL: Fixed invalid checks on STM32L1xx LSI and LSE clocks (bug #583).
|
- HAL: Fixed invalid checks on STM32L1xx LSI and LSE clocks (bug #583).
|
||||||
- HAL: Fixed RCC CAN2 macros missing in STM32F1xx platform (bug #582).
|
- HAL: Fixed RCC CAN2 macros missing in STM32F1xx platform (bug #582).
|
||||||
- HAL: Fixed STM32 I2Cv2 driver issue (bug 581).
|
- HAL: Fixed STM32 I2Cv2 driver issue (bug 581).
|
||||||
|
|
Loading…
Reference in New Issue