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:
Michael Hope 2018-02-25 15:39:16 +01:00 committed by Anas Nashif
commit 8f7e5bd0a5

View file

@ -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--) {