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 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)
|
||||
&& uart_irq_is_pending(uart_pipe_dev)) {
|
||||
int rx;
|
||||
|
||||
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;
|
||||
got = uart_fifo_read(uart_pipe_dev, recv_buf + recv_off, avail);
|
||||
if (got <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call application callback with received data. Application
|
||||
* may provide new buffer or alter data offset.
|
||||
*/
|
||||
recv_off += rx;
|
||||
recv_off += got;
|
||||
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)
|
||||
{
|
||||
while (len--) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue