Fix USART driver.

This commit is contained in:
NIIBE Yutaka
2019-04-24 20:22:57 +09:00
parent c818ec89a4
commit d22ffb2d07
4 changed files with 53 additions and 22 deletions

View File

@@ -35,7 +35,7 @@
* MODER: 00 10 - 10 10 - 10 11 - 10 10 11 11 - 11 01 - 01 10 - 01 00 * MODER: 00 10 - 10 10 - 10 11 - 10 10 11 11 - 11 01 - 01 10 - 01 00
* *
* PA0 - Input with pull-up: Card insertion detect: 0 when detected * PA0 - Input with pull-up: Card insertion detect: 0 when detected
* PA1 - Output push-pull default 0 : Card RST * PA1 - Output push-pull default 0: Card RST
* PA2 - USART2-TX (AF7): output push-pull * PA2 - USART2-TX (AF7): output push-pull
* PA3 - Output push-pull default 0: Card Vcc * PA3 - Output push-pull default 0: Card Vcc
* PA4 - Output push-pull default 0: Card Vpp * PA4 - Output push-pull default 0: Card Vpp

View File

@@ -488,13 +488,14 @@ usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
USARTx->CR1 &= ~USART_CR1_TXEIE; USARTx->CR1 &= ~USART_CR1_TXEIE;
if (smartcard_mode) if (smartcard_mode)
{ {
if ((*timeout_block_p)) if (timeout_block_p && (*timeout_block_p))
do do
r = USARTx->SR; r = USARTx->SR;
while (((r & USART_SR_TC) == 0)); while (((r & USART_SR_TC) == 0));
usart_config_recv_enable (USARTx, 1); usart_config_recv_enable (USARTx, 1);
if (*timeout_block_p == 0) if (timeout_block_p && *timeout_block_p == 0)
{ {
/* Ignoring the echo back. */ /* Ignoring the echo back. */
do do
@@ -514,6 +515,9 @@ usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
chopstx_intr_done (usartx_intr); chopstx_intr_done (usartx_intr);
} }
if (r_buf == NULL)
return 0;
/* Receiving part */ /* Receiving part */
r = chopstx_poll (timeout_block_p, 1, ph); r = chopstx_poll (timeout_block_p, 1, ph);
if (r == 0) if (r == 0)

View File

@@ -130,7 +130,7 @@ static const struct brr_setting brr_table[] = {
{ B230400, 174 }, { B230400, 174 },
{ B460800, 87 }, { B460800, 87 },
{ B921600, 43 }, { B921600, 43 },
{ BSCARD, 4167 }, { BSCARD, 3719 },
}; };
void void
@@ -150,7 +150,12 @@ static void
usart_config_recv_enable (struct USART *USARTx, int on) usart_config_recv_enable (struct USART *USARTx, int on)
{ {
if (on) if (on)
USARTx->CR1 |= USART_CR1_RE; {
USARTx->CR1 |= USART_CR1_RE;
/* Wait for REACK bit. */
while ((USARTx->ISR & (1 << 22)) == 0)
;
}
else else
USARTx->CR1 &= ~USART_CR1_RE; USARTx->CR1 &= ~USART_CR1_RE;
} }
@@ -173,8 +178,7 @@ usart_config (uint8_t dev_no, uint32_t config_bits)
struct USART *USARTx = get_usart_dev (dev_no); struct USART *USARTx = get_usart_dev (dev_no);
uint8_t baud_spec = (config_bits & MASK_BAUD); uint8_t baud_spec = (config_bits & MASK_BAUD);
int i; int i;
uint32_t cr1_config = (USART_CR1_UE | USART_CR1_RXNEIE uint32_t cr1_config = (USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE);
| USART_CR1_TE | USART_CR1_RE);
/* TXEIE/TCIE will be enabled when /* TXEIE/TCIE will be enabled when
putting char */ putting char */
/* No CTSIE, PEIE, IDLEIE, LBDIE */ /* No CTSIE, PEIE, IDLEIE, LBDIE */
@@ -235,9 +239,15 @@ usart_config (uint8_t dev_no, uint32_t config_bits)
else if ((config_bits & MASK_MODE) == MODE_IRDA_LP) else if ((config_bits & MASK_MODE) == MODE_IRDA_LP)
USARTx->CR3 |= (1 << 2) | (1 << 1); USARTx->CR3 |= (1 << 2) | (1 << 1);
} }
else
cr1_config |= USART_CR1_RE;
USARTx->CR1 = cr1_config; USARTx->CR1 = cr1_config;
/* Wait for TEACK bit. */
while ((USARTx->ISR & (1 << 21)) == 0)
;
return 0; return 0;
} }
@@ -304,22 +314,25 @@ handle_intr (struct USART *USARTx, struct rb *rb2a, struct usart_stat *stat)
{ {
uint32_t data = USARTx->RDR; uint32_t data = USARTx->RDR;
/* RDR register should be accessed even if data is not used. /* RDR register should be accessed even if data is not used. */
* Its read-access has side effect of clearing error flags.
*/
asm volatile ("" : : "r" (data) : "memory"); asm volatile ("" : : "r" (data) : "memory");
if ((r & USART_ISR_NE)) if ((r & USART_ISR_NE))
stat->err_rx_noise++; {
USARTx->ICR |= (1 << 2);
stat->err_rx_noise++;
}
else if ((r & USART_ISR_FE)) else if ((r & USART_ISR_FE))
{ {
/* NOTE: Noway to distinguish framing error and break */ /* NOTE: Noway to distinguish framing error and break */
USARTx->ICR |= (1 << 1);
stat->rx_break++; stat->rx_break++;
notify_bits |= UART_STATE_BITMAP_BREAK; notify_bits |= UART_STATE_BITMAP_BREAK;
} }
else if ((r & USART_ISR_PE)) else if ((r & USART_ISR_PE))
{ {
USARTx->ICR |= (1 << 0);
stat->err_rx_parity++; stat->err_rx_parity++;
notify_bits |= UART_STATE_BITMAP_PARITY; notify_bits |= UART_STATE_BITMAP_PARITY;
} }
@@ -327,6 +340,7 @@ handle_intr (struct USART *USARTx, struct rb *rb2a, struct usart_stat *stat)
{ {
if ((r & USART_ISR_ORE)) if ((r & USART_ISR_ORE))
{ {
USARTx->ICR |= (1 << 3);
stat->err_rx_overrun++; stat->err_rx_overrun++;
notify_bits |= UART_STATE_BITMAP_OVERRUN; notify_bits |= UART_STATE_BITMAP_OVERRUN;
} }
@@ -340,8 +354,7 @@ handle_intr (struct USART *USARTx, struct rb *rb2a, struct usart_stat *stat)
} }
else if ((r & USART_ISR_ORE)) else if ((r & USART_ISR_ORE))
{ /* Clear ORE */ { /* Clear ORE */
uint32_t data = USARTx->RDR; USARTx->ICR |= (1 << 3);
asm volatile ("" : : "r" (data) : "memory");
stat->err_rx_overrun++; stat->err_rx_overrun++;
notify_bits |= UART_STATE_BITMAP_OVERRUN; notify_bits |= UART_STATE_BITMAP_OVERRUN;
} }
@@ -442,10 +455,16 @@ usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
r = USARTx->ISR; r = USARTx->ISR;
/* Here, ignore recv error(s). */ /* Here, ignore recv error(s). */
if ((r & USART_ISR_RXNE) || (r & USART_ISR_ORE)) if ((r & USART_ISR_RXNE))
{ {
data = USARTx->RDR; data = USARTx->RDR;
asm volatile ("" : : "r" (data) : "memory"); asm volatile ("" : : "r" (data) : "memory");
USARTx->ICR |= ((1 << 2) | (1 << 1) | (1 << 0));
}
else if ((r & USART_ISR_ORE))
{
USARTx->ICR |= (1 << 3);
} }
if ((r & USART_ISR_TXE)) if ((r & USART_ISR_TXE))
@@ -466,13 +485,14 @@ usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
USARTx->CR1 &= ~USART_CR1_TXEIE; USARTx->CR1 &= ~USART_CR1_TXEIE;
if (smartcard_mode) if (smartcard_mode)
{ {
if ((*timeout_block_p)) if (timeout_block_p && (*timeout_block_p))
do do
r = USARTx->ISR; r = USARTx->ISR;
while (((r & USART_ISR_TC) == 0)); while (((r & USART_ISR_TC) == 0));
usart_config_recv_enable (USARTx, 1); usart_config_recv_enable (USARTx, 1);
if (*timeout_block_p == 0) if (timeout_block_p && *timeout_block_p == 0)
{ {
/* Ignoring the echo back. */ /* Ignoring the echo back. */
do do
@@ -492,6 +512,9 @@ usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
chopstx_intr_done (usartx_intr); chopstx_intr_done (usartx_intr);
} }
if (r_buf == NULL)
return 0;
/* Receiving part */ /* Receiving part */
r = chopstx_poll (timeout_block_p, 1, ph); r = chopstx_poll (timeout_block_p, 1, ph);
if (r == 0) if (r == 0)
@@ -510,8 +533,11 @@ usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
if ((r & USART_ISR_RXNE)) if ((r & USART_ISR_RXNE))
{ {
if ((r & USART_ISR_NE) || (r & USART_ISR_FE) || (r & USART_ISR_PE)) if ((r & USART_ISR_NE) || (r & USART_ISR_FE) || (r & USART_ISR_PE))
/* ignore error, for now. XXX: ss_notify */ {
; /* ignore error, for now. XXX: ss_notify */
/* Clear the error flag(s) */
USARTx->ICR |= ((1 << 2) | (1 << 1) | (1 << 0));
}
else else
{ {
*p++ = (data & 0xff); *p++ = (data & 0xff);
@@ -526,8 +552,9 @@ usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
} }
else if ((r & USART_ISR_ORE)) else if ((r & USART_ISR_ORE))
{ {
data = USARTx->RDR; /* ignore error, for now. XXX: ss_notify */
asm volatile ("" : : "r" (data) : "memory"); /* Clear the error flag */
USARTx->ICR |= (1 << 3);
} }
chopstx_intr_done (usartx_intr); chopstx_intr_done (usartx_intr);

View File

@@ -48,8 +48,8 @@ clock_init (void)
while ((FLASH->ACR & 0x07) != (STM32_FLASHBITS & 0x07)) while ((FLASH->ACR & 0x07) != (STM32_FLASHBITS & 0x07))
; ;
/* Configure bus clocks: AHB: 80MHz, APB1: 40MHz, APB2: 80MHz */ /* Configure bus clocks: AHB: 80MHz, APB1: 40MHz, APB2: 40MHz */
RCC->CFGR = (0x04 << 8); RCC->CFGR = ((0x04 << 11) | (0x04 << 8));
/* Switch SYSCLOCK using PLL */ /* Switch SYSCLOCK using PLL */
RCC->CFGR |= 0x03; RCC->CFGR |= 0x03;