uart_pipe: re-work the RX function to match the API and work with USB.
include/uart.h says that an interrupt may be an edge or a level. Re-work the uart_pipe interrupt handler to support both. This makes uart_pipe work with the USB CDC ACM driver. Signed-off-by: Michael Hope <mlhx@google.com>
This commit is contained in:
parent
e618608fca
commit
8f7e5bd0a5
1 changed files with 22 additions and 15 deletions
|
@ -26,33 +26,40 @@ static size_t recv_buf_len;
|
||||||
static uart_pipe_recv_cb app_cb;
|
static uart_pipe_recv_cb app_cb;
|
||||||
static size_t recv_off;
|
static size_t recv_off;
|
||||||
|
|
||||||
static void uart_pipe_isr(struct device *unused)
|
static void uart_pipe_rx(struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(unused);
|
/* As per the API, the interrupt may be an edge so keep
|
||||||
|
* reading from the FIFO until it's empty.
|
||||||
|
*/
|
||||||
|
for (;;) {
|
||||||
|
int avail = recv_buf_len - recv_off;
|
||||||
|
int got;
|
||||||
|
|
||||||
while (uart_irq_update(uart_pipe_dev)
|
got = uart_fifo_read(uart_pipe_dev, recv_buf + recv_off, avail);
|
||||||
&& uart_irq_is_pending(uart_pipe_dev)) {
|
if (got <= 0) {
|
||||||
int rx;
|
break;
|
||||||
|
|
||||||
if (!uart_irq_rx_ready(uart_pipe_dev)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rx = uart_fifo_read(uart_pipe_dev, recv_buf + recv_off,
|
|
||||||
recv_buf_len - recv_off);
|
|
||||||
if (!rx) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call application callback with received data. Application
|
* Call application callback with received data. Application
|
||||||
* may provide new buffer or alter data offset.
|
* may provide new buffer or alter data offset.
|
||||||
*/
|
*/
|
||||||
recv_off += rx;
|
recv_off += got;
|
||||||
recv_buf = app_cb(recv_buf, &recv_off);
|
recv_buf = app_cb(recv_buf, &recv_off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void uart_pipe_isr(struct device *dev)
|
||||||
|
{
|
||||||
|
uart_irq_update(dev);
|
||||||
|
|
||||||
|
if (uart_irq_is_pending(dev)) {
|
||||||
|
if (uart_irq_rx_ready(dev)) {
|
||||||
|
uart_pipe_rx(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int uart_pipe_send(const u8_t *data, int len)
|
int uart_pipe_send(const u8_t *data, int len)
|
||||||
{
|
{
|
||||||
while (len--) {
|
while (len--) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue