123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- /** @file
- * @brief Pipe UART driver
- *
- * A pipe UART driver allowing application to handle all aspects of received
- * protocol data.
- */
- /*
- * Copyright (c) 2015 Intel Corporation
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <logging/log.h>
- LOG_MODULE_REGISTER(uart_pipe, CONFIG_UART_CONSOLE_LOG_LEVEL);
- #include <kernel.h>
- #include <drivers/uart.h>
- #include <drivers/console/uart_pipe.h>
- #include <sys/printk.h>
- static const struct device *uart_pipe_dev;
- static uint8_t *recv_buf;
- static size_t recv_buf_len;
- static uart_pipe_recv_cb app_cb;
- static size_t recv_off;
- static void uart_pipe_rx(const struct device *dev)
- {
- /* 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;
- got = uart_fifo_read(uart_pipe_dev, recv_buf + recv_off, avail);
- if (got <= 0) {
- break;
- }
- LOG_HEXDUMP_DBG(recv_buf + recv_off, got, "RX");
- /*
- * Call application callback with received data. Application
- * may provide new buffer or alter data offset.
- */
- recv_off += got;
- recv_buf = app_cb(recv_buf, &recv_off);
- }
- }
- static void uart_pipe_isr(const struct device *dev, void *user_data)
- {
- ARG_UNUSED(user_data);
- 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 uint8_t *data, int len)
- {
- LOG_HEXDUMP_DBG(data, len, "TX");
- while (len--) {
- uart_poll_out(uart_pipe_dev, *data++);
- }
- return 0;
- }
- static void uart_pipe_setup(const struct device *uart)
- {
- uint8_t c;
- uart_irq_rx_disable(uart);
- uart_irq_tx_disable(uart);
- /* Drain the fifo */
- while (uart_fifo_read(uart, &c, 1)) {
- continue;
- }
- uart_irq_callback_set(uart, uart_pipe_isr);
- uart_irq_rx_enable(uart);
- }
- void uart_pipe_register(uint8_t *buf, size_t len, uart_pipe_recv_cb cb)
- {
- recv_buf = buf;
- recv_buf_len = len;
- app_cb = cb;
- uart_pipe_dev = device_get_binding(CONFIG_UART_PIPE_ON_DEV_NAME);
- if (uart_pipe_dev != NULL) {
- uart_pipe_setup(uart_pipe_dev);
- }
- }
|