usart: New API for block send-recv.
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
2019-04-08 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* contrib/usart-stm32f103.c (usart_block_sendrecv): New.
|
||||||
|
(usart_init0): New.
|
||||||
|
|
||||||
2019-03-30 Niibe Yutaka <gniibe@fsij.org>
|
2019-03-30 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* contrib/usart-stm32f103.c (usart_config_brr): New.
|
* contrib/usart-stm32f103.c (usart_config_brr): New.
|
||||||
|
|||||||
@@ -120,10 +120,12 @@ void
|
|||||||
usart_config_brr (uint8_t dev_no, uint16_t brr_value)
|
usart_config_brr (uint8_t dev_no, uint16_t brr_value)
|
||||||
{
|
{
|
||||||
struct USART *USARTx = get_usart_dev (dev_no);
|
struct USART *USARTx = get_usart_dev (dev_no);
|
||||||
|
uint32_t save_bits;
|
||||||
|
|
||||||
|
save_bits = USARTx->CR1 & (USART_CR1_TE | USART_CR1_RE);
|
||||||
USARTx->CR1 &= ~(USART_CR1_TE | USART_CR1_RE);
|
USARTx->CR1 &= ~(USART_CR1_TE | USART_CR1_RE);
|
||||||
USARTx->BRR = brr_value;
|
USARTx->BRR = brr_value;
|
||||||
USARTx->CR1 |= (USART_CR1_TE | USART_CR1_RE);
|
USARTx->CR1 |= save_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -226,19 +228,33 @@ usart_config (uint8_t dev_no, uint32_t config_bits)
|
|||||||
|
|
||||||
static int (*ss_notify_callback) (uint8_t dev_no, uint16_t notify_bits);
|
static int (*ss_notify_callback) (uint8_t dev_no, uint16_t notify_bits);
|
||||||
|
|
||||||
|
#define INTR_REQ_USART2 38
|
||||||
|
#define INTR_REQ_USART3 39
|
||||||
|
|
||||||
|
static struct chx_intr usart2_intr;
|
||||||
|
static struct chx_intr usart3_intr;
|
||||||
|
|
||||||
void
|
void
|
||||||
usart_init (uint16_t prio, uintptr_t stack_addr, size_t stack_size,
|
usart_init0 (int (*cb) (uint8_t dev_no, uint16_t notify_bits))
|
||||||
int (*cb) (uint8_t dev_no, uint16_t notify_bits))
|
|
||||||
{
|
{
|
||||||
ss_notify_callback = cb;
|
ss_notify_callback = cb;
|
||||||
usart2_stat.dev_no = 2;
|
usart2_stat.dev_no = 2;
|
||||||
usart3_stat.dev_no = 3;
|
usart3_stat.dev_no = 3;
|
||||||
|
|
||||||
|
chopstx_claim_irq (&usart2_intr, INTR_REQ_USART2);
|
||||||
|
chopstx_claim_irq (&usart3_intr, INTR_REQ_USART3);
|
||||||
|
|
||||||
/* Enable USART2 and USART3 clocks, and strobe reset. */
|
/* Enable USART2 and USART3 clocks, and strobe reset. */
|
||||||
RCC->APB1ENR |= ((1 << 18) | (1 << 17));
|
RCC->APB1ENR |= ((1 << 18) | (1 << 17));
|
||||||
RCC->APB1RSTR = ((1 << 18) | (1 << 17));
|
RCC->APB1RSTR = ((1 << 18) | (1 << 17));
|
||||||
RCC->APB1RSTR = 0;
|
RCC->APB1RSTR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
usart_init (uint16_t prio, uintptr_t stack_addr, size_t stack_size,
|
||||||
|
int (*cb) (uint8_t dev_no, uint16_t notify_bits))
|
||||||
|
{
|
||||||
|
usart_init0 (cb);
|
||||||
chopstx_create (prio, stack_addr, stack_size, usart_main, NULL);
|
chopstx_create (prio, stack_addr, stack_size, usart_main, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,17 +458,11 @@ rb_get_prepare_poll (struct rb *rb, chopstx_poll_cond_t *poll_desc)
|
|||||||
poll_desc->arg = rb;
|
poll_desc->arg = rb;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INTR_REQ_USART2 38
|
|
||||||
#define INTR_REQ_USART3 39
|
|
||||||
|
|
||||||
static uint8_t buf_usart2_rb_a2h[256];
|
static uint8_t buf_usart2_rb_a2h[256];
|
||||||
static uint8_t buf_usart2_rb_h2a[512];
|
static uint8_t buf_usart2_rb_h2a[512];
|
||||||
static uint8_t buf_usart3_rb_a2h[256];
|
static uint8_t buf_usart3_rb_a2h[256];
|
||||||
static uint8_t buf_usart3_rb_h2a[512];
|
static uint8_t buf_usart3_rb_h2a[512];
|
||||||
|
|
||||||
static struct chx_intr usart2_intr;
|
|
||||||
static struct chx_intr usart3_intr;
|
|
||||||
|
|
||||||
static struct rb usart2_rb_a2h;
|
static struct rb usart2_rb_a2h;
|
||||||
static struct rb usart2_rb_h2a;
|
static struct rb usart2_rb_h2a;
|
||||||
static struct rb usart3_rb_a2h;
|
static struct rb usart3_rb_a2h;
|
||||||
@@ -598,9 +608,6 @@ usart_main (void *arg)
|
|||||||
usart2_tx_ready = 1;
|
usart2_tx_ready = 1;
|
||||||
usart3_tx_ready = 1;
|
usart3_tx_ready = 1;
|
||||||
|
|
||||||
chopstx_claim_irq (&usart2_intr, INTR_REQ_USART2);
|
|
||||||
chopstx_claim_irq (&usart3_intr, INTR_REQ_USART3);
|
|
||||||
|
|
||||||
rb_init (&usart2_rb_a2h, buf_usart2_rb_a2h, sizeof buf_usart2_rb_a2h);
|
rb_init (&usart2_rb_a2h, buf_usart2_rb_a2h, sizeof buf_usart2_rb_a2h);
|
||||||
rb_init (&usart2_rb_h2a, buf_usart2_rb_h2a, sizeof buf_usart2_rb_h2a);
|
rb_init (&usart2_rb_h2a, buf_usart2_rb_h2a, sizeof buf_usart2_rb_h2a);
|
||||||
rb_init (&usart3_rb_a2h, buf_usart3_rb_a2h, sizeof buf_usart3_rb_a2h);
|
rb_init (&usart3_rb_a2h, buf_usart3_rb_a2h, sizeof buf_usart3_rb_a2h);
|
||||||
@@ -779,3 +786,124 @@ usart_send_break (uint8_t dev_no)
|
|||||||
USARTx->CR1 |= 0x01;
|
USARTx->CR1 |= 0x01;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
|
||||||
|
char *r_buf, uint16_t r_buflen,
|
||||||
|
uint32_t *timeout_block_p, uint32_t timeout_char)
|
||||||
|
{
|
||||||
|
uint32_t timeout;
|
||||||
|
uint8_t *p;
|
||||||
|
int len;
|
||||||
|
uint32_t r;
|
||||||
|
uint32_t data;
|
||||||
|
struct USART *USARTx = get_usart_dev (dev_no);
|
||||||
|
int smartcard_mode = ((USARTx->CR3 & USART_CR3_SCEN) != 0);
|
||||||
|
struct chx_intr *usartx_intr;
|
||||||
|
struct chx_poll_head *ph[1];
|
||||||
|
|
||||||
|
if (dev_no == 2)
|
||||||
|
usartx_intr = &usart2_intr;
|
||||||
|
else
|
||||||
|
usartx_intr = &usart3_intr;
|
||||||
|
ph[0] = (struct chx_poll_head *)usartx_intr;
|
||||||
|
|
||||||
|
p = (uint8_t *)s_buf;
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
if (smartcard_mode)
|
||||||
|
usart_config_recv_enable (USARTx, 0);
|
||||||
|
|
||||||
|
if (smartcard_mode)
|
||||||
|
USARTx->CR1 |= USART_CR1_TCIE;
|
||||||
|
else
|
||||||
|
USARTx->CR1 |= USART_CR1_TXEIE;
|
||||||
|
|
||||||
|
/* Sending part */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
chopstx_poll (NULL, 1, ph);
|
||||||
|
|
||||||
|
r = USARTx->SR;
|
||||||
|
|
||||||
|
/* Here, ignore recv error(s). */
|
||||||
|
if ((r & USART_SR_RXNE) || (r & USART_SR_ORE))
|
||||||
|
{
|
||||||
|
data = USARTx->DR;
|
||||||
|
asm volatile ("" : : "r" (data) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not ready? Then, poll again. */
|
||||||
|
if (!(smartcard_mode && (r & USART_SR_TC))
|
||||||
|
&& !(!smartcard_mode && (r & USART_SR_TXE)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (s_buflen == 0)
|
||||||
|
{
|
||||||
|
if (smartcard_mode)
|
||||||
|
USARTx->CR1 &= ~USART_CR1_TCIE;
|
||||||
|
else
|
||||||
|
USARTx->CR1 &= ~USART_CR1_TXEIE;
|
||||||
|
chopstx_intr_done (usartx_intr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chopstx_intr_done (usartx_intr);
|
||||||
|
/* Keep TCIE or TXEIE bit */
|
||||||
|
USARTx->DR = *p++;
|
||||||
|
s_buflen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smartcard_mode)
|
||||||
|
usart_config_recv_enable (USARTx, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (uint8_t *)r_buf;
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
/* Receiving part */
|
||||||
|
r = chopstx_poll (timeout_block_p, 1, ph);
|
||||||
|
if (r == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
r = USARTx->SR;
|
||||||
|
|
||||||
|
data = USARTx->DR;
|
||||||
|
asm volatile ("" : : "r" (data) : "memory");
|
||||||
|
|
||||||
|
if ((r & USART_SR_RXNE))
|
||||||
|
{
|
||||||
|
if ((r & USART_SR_NE) || (r & USART_SR_FE) || (r & USART_SR_PE))
|
||||||
|
/* ignore error, for now. XXX: ss_notify */
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p++ = (data & 0xff);
|
||||||
|
len++;
|
||||||
|
r_buflen--;
|
||||||
|
if (r_buflen == 0)
|
||||||
|
{
|
||||||
|
chopstx_intr_done (usartx_intr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((r & USART_SR_ORE))
|
||||||
|
{
|
||||||
|
data = USARTx->DR;
|
||||||
|
asm volatile ("" : : "r" (data) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
chopstx_intr_done (usartx_intr);
|
||||||
|
timeout = timeout_char;
|
||||||
|
r = chopstx_poll (&timeout, 1, ph);
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,3 +77,8 @@ void usart_config_brr (uint8_t dev_no, uint16_t brr_value);
|
|||||||
|
|
||||||
void usart_read_prepare_poll (uint8_t dev_no, chopstx_poll_cond_t *poll_desc);
|
void usart_read_prepare_poll (uint8_t dev_no, chopstx_poll_cond_t *poll_desc);
|
||||||
int usart_read_ext (uint8_t dev_no, char *buf, uint16_t buflen, uint32_t *timeout_p);
|
int usart_read_ext (uint8_t dev_no, char *buf, uint16_t buflen, uint32_t *timeout_p);
|
||||||
|
|
||||||
|
void usart_init0 (int (*cb) (uint8_t dev_no, uint16_t notify_bits));
|
||||||
|
int usart_block_sendrecv (uint8_t dev_no, const char *s_buf, uint16_t s_buflen,
|
||||||
|
char *r_buf, uint16_t r_buflen,
|
||||||
|
uint32_t *timeout_block_p, uint32_t timeout_char);
|
||||||
|
|||||||
Reference in New Issue
Block a user