static int h5_unslip_byte(uint8_t *byte) { int count; if (*byte != SLIP_ESC) { return 0; } do { count = uart_fifo_read(h5_dev, byte, sizeof(*byte)); } while (!count); switch (*byte) { case SLIP_ESC_DELIM: *byte = SLIP_DELIMITER; break; case SLIP_ESC_ESC: *byte = SLIP_ESC; break; default: BT_ERR("Invalid escape byte %x\n", *byte); return -EIO; } return 0; }
static void uart_pipe_isr(struct device *unused) { ARG_UNUSED(unused); 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; } /* * Call application callback with received data. Application * may provide new buffer or alter data offset. */ recv_off += rx; recv_buf = app_cb(recv_buf, &recv_off); } }
static uint8_t avr_uart_read(struct avr_t * avr, avr_io_addr_t addr, void * param) { avr_uart_t * p = (avr_uart_t *)param; // clear the rxc bit in case the code is using polling avr_regbit_clear(avr, p->rxc.raised); if (!avr_regbit_get(avr, p->rxen)) { avr->data[addr] = 0; // made to trigger potential watchpoints avr_core_watch_read(avr, addr); return 0; } uint8_t v = uart_fifo_read(&p->input); // TRACE(printf("UART read %02x %s\n", v, uart_fifo_isempty(&p->input) ? "EMPTY!" : "");) avr->data[addr] = v; // made to trigger potential watchpoints v = avr_core_watch_read(avr, addr); // trigger timer if more characters are pending if (!uart_fifo_isempty(&p->input)) avr_cycle_timer_register_usec(avr, p->usec_per_byte, avr_uart_rxc_raise, p); return v; }
static int h4_read(struct device *uart, uint8_t *buf, size_t len, size_t min) { int total = 0; while (len) { int rx; rx = uart_fifo_read(uart, buf, len); if (rx == 0) { BT_DBG("Got zero bytes from UART"); if (total < min) { continue; } break; } BT_DBG("read %d remaining %d", rx, len - rx); len -= rx; total += rx; buf += rx; } return total; }
static void interrupt_handler(struct device *unused) { while (uart_irq_update(uart_dev) && uart_irq_is_pending(uart_dev)) { if (uart_irq_tx_ready(uart_dev)) data_transmitted = true; if (uart_irq_rx_ready(uart_dev)) { int len = uart_fifo_read(uart_dev, rx_buffer, sizeof(rx_buffer)); if (len == 0) { printf("RX data ZERO\n"); continue; } else { uart_buf_t *rx_buf = &buf_pool[pool_index]; memcpy(rx_buf->data, rx_buffer, len); rx_buf->len = len; printf("FIFO put (%d): %d bytes\n", pool_index, len); k_fifo_put(&rx_fifo, rx_buf); pool_index++; if (pool_index == BUF_COUNT) pool_index = 0; } } else { printf("ISR: spurious\n"); //break; } } }
static inline void get_evt_hdr(void) { struct bt_hci_evt_hdr *hdr = &rx.evt; int to_read = rx.hdr_len - rx.remaining; rx.remaining -= uart_fifo_read(h4_dev, (u8_t *)hdr + to_read, rx.remaining); if (rx.hdr_len == sizeof(*hdr) && rx.remaining < sizeof(*hdr)) { switch (rx.evt.evt) { case BT_HCI_EVT_LE_META_EVENT: rx.remaining++; rx.hdr_len++; break; #if defined(CONFIG_BLUETOOTH_BREDR) case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: rx.discardable = true; break; #endif } } if (!rx.remaining) { if (rx.evt.evt == BT_HCI_EVT_LE_META_EVENT && rx.hdr[sizeof(*hdr)] == BT_HCI_EVT_LE_ADVERTISING_REPORT) { BT_DBG("Marking adv report as discardable"); rx.discardable = true; } rx.remaining = hdr->len - (rx.hdr_len - sizeof(*hdr)); BT_DBG("Got event header. Payload %u bytes", hdr->len); rx.have_hdr = true; } }
/** * Reads a chunk of received data from the UART. */ static int uart_mcumgr_read_chunk(void *buf, int capacity) { if (!uart_irq_rx_ready(uart_mcumgr_dev)) { return 0; } return uart_fifo_read(uart_mcumgr_dev, buf, capacity); }
static size_t bt_uart_discard(int uart, size_t len) { uint8_t buf[33]; if (len > sizeof(buf)) { len = sizeof(buf); } return uart_fifo_read(uart, buf, len); }
static void interrupt_handler(struct device *dev) { uart_irq_update(dev); if (uart_irq_tx_ready(dev)) { data_transmitted = true; } if (uart_irq_rx_ready(dev)) { uart_fifo_read(dev, &new_data, 1); data_arrived = true; } }
static inline void get_acl_hdr(void) { struct bt_hci_acl_hdr *hdr = &rx.acl; int to_read = sizeof(*hdr) - rx.remaining; rx.remaining -= uart_fifo_read(h4_dev, (u8_t *)hdr + to_read, rx.remaining); if (!rx.remaining) { rx.remaining = sys_le16_to_cpu(hdr->len); BT_DBG("Got ACL header. Payload %u bytes", rx.remaining); rx.have_hdr = true; } }
static int read_uart(struct device *uart, uint8_t *buf, unsigned int size) { int rx; rx = uart_fifo_read(uart, buf, size); if (rx < 0) { /* Overrun issue. Stop the UART */ uart_irq_rx_disable(uart); return -EIO; } return rx; }
static void uart_pipe_setup(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); }
static void console_input_init(void) { uint8_t c; uart_irq_rx_disable(uart_console_dev); uart_irq_tx_disable(uart_console_dev); uart_irq_callback_set(uart_console_dev, uart_console_isr); /* Drain the fifo */ while (uart_irq_rx_ready(uart_console_dev)) { uart_fifo_read(uart_console_dev, &c, 1); } uart_irq_rx_enable(uart_console_dev); }
static void uart_simple_setup(int uart, struct uart_init_info *info) { uart_init(uart, info); uart_irq_rx_disable(uart); uart_irq_tx_disable(uart); IRQ_CONFIG(uart_simple, uart_irq_get(uart)); irq_enable(uart_irq_get(uart)); /* Drain the fifo */ while (uart_irq_rx_ready(uart)) { unsigned char c; uart_fifo_read(uart, &c, 1); } uart_irq_rx_enable(uart); }
static void bt_uart_setup(int uart, struct uart_init_info *info) { BT_DBG("\n"); uart_init(uart, info); uart_irq_rx_disable(uart); uart_irq_tx_disable(uart); IRQ_CONFIG(bluetooth, uart_irq_get(uart)); irq_enable(uart_irq_get(uart)); /* Drain the fifo */ while (uart_irq_rx_ready(uart)) { unsigned char c; uart_fifo_read(uart, &c, 1); } uart_irq_rx_enable(uart); }
static void interrupt_handler(struct device *dev) { while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { #ifdef VERBOSE_DEBUG SYS_LOG_DBG(""); #endif if (uart_irq_tx_ready(dev)) { #ifdef VERBOSE_DEBUG SYS_LOG_DBG("TX ready interrupt"); #endif k_sem_give(&tx_sem); } if (uart_irq_rx_ready(dev)) { unsigned char byte; #ifdef VERBOSE_DEBUG SYS_LOG_DBG("RX ready interrupt"); #endif while (uart_fifo_read(dev, &byte, sizeof(byte))) { if (slip_process_byte(byte)) { /** * slip_process_byte() returns 1 on * SLIP_END, even after receiving full * packet */ if (!pkt_curr) { SYS_LOG_DBG("Skip SLIP_END"); continue; } SYS_LOG_DBG("Full packet %p", pkt_curr); k_fifo_put(&rx_queue, pkt_curr); pkt_curr = NULL; } } } } }
static int h4_open(void) { BT_DBG(""); uart_irq_rx_disable(h4_dev); uart_irq_tx_disable(h4_dev); /* Drain the fifo */ while (uart_irq_rx_ready(h4_dev)) { unsigned char c; uart_fifo_read(h4_dev, &c, 1); } uart_irq_callback_set(h4_dev, bt_uart_isr); uart_irq_rx_enable(h4_dev); return 0; }
static int h4_open(void) { BT_DBG(""); uart_irq_rx_disable(h4_dev); uart_irq_tx_disable(h4_dev); IRQ_CONNECT(CONFIG_BLUETOOTH_UART_IRQ, CONFIG_BLUETOOTH_UART_IRQ_PRI, bt_uart_isr, 0, UART_IRQ_FLAGS); irq_enable(CONFIG_BLUETOOTH_UART_IRQ); /* Drain the fifo */ while (uart_irq_rx_ready(h4_dev)) { unsigned char c; uart_fifo_read(h4_dev, &c, 1); } uart_irq_rx_enable(h4_dev); return 0; }
static inline void h4_get_type(void) { /* Get packet type */ if (uart_fifo_read(h4_dev, &rx.type, 1) != 1) { BT_WARN("Unable to read H:4 packet type"); rx.type = H4_NONE; return; } switch (rx.type) { case H4_EVT: rx.remaining = sizeof(rx.evt); rx.hdr_len = rx.remaining; break; case H4_ACL: rx.remaining = sizeof(rx.acl); rx.hdr_len = rx.remaining; break; default: BT_ERR("Unknown H:4 type 0x%02x", rx.type); rx.type = H4_NONE; } }
int main(int argc, char const *argv[]) { int ret; printf("start buffers: %d, size=%d total size=%d\n", sizeof(buf_pool)/sizeof(uart_buf_t), sizeof(uart_buf_t), sizeof(buf_pool)); uart_dev = device_get_binding(CONFIG_CDC_ACM_PORT_NAME); if (uart_dev == NULL) { printf("%s: error\n", __FUNCTION__); return 0; } ret = uart_line_ctrl_set(uart_dev, LINE_CTRL_BAUD_RATE, 115200); if (ret) printf("Baudrate set failed %d\n", ret); k_sleep(1000); uart_irq_rx_disable(uart_dev); uart_irq_tx_disable(uart_dev); /* drain the fifo */ uint8_t c; while(uart_fifo_read(uart_dev, &c, 1)) { continue; } uart_irq_callback_set(uart_dev, interrupt_handler); uart_irq_rx_enable(uart_dev); read_and_echo_data(uart_dev); return 0; }
void uart_simple_isr(void *unused) { ARG_UNUSED(unused); while (uart_irq_update(UART) && uart_irq_is_pending(UART)) { int rx; if (!uart_irq_rx_ready(UART)) { continue; } rx = uart_fifo_read(UART, recv_buf + recv_off, recv_buf_len - recv_off); if (!rx) { continue; } /* Call application callback with received data. Application * may provide new buffer or alter data offset. */ recv_off += rx; recv_buf = app_cb(recv_buf, &recv_off); } }
void UARTClass::init(const uint32_t dwBaudRate, const uint8_t modeReg) { uint8_t c; // Make sure both ring buffers are initialized back to empty. _rx_buffer->_iHead = _rx_buffer->_iTail = 0; _tx_buffer->_iHead = _tx_buffer->_iTail = 0; SET_PIN_MODE(17, UART_MUX_MODE); // Rdx SOC PIN (Arduino header pin 0) SET_PIN_MODE(16, UART_MUX_MODE); // Txd SOC PIN (Arduino header pin 1) info->options = 0; info->sys_clk_freq = SYSCLK_DEFAULT_IOSC_HZ; info->baud_rate = dwBaudRate; info->regs = CONFIG_UART_CONSOLE_REGS; info->irq = CONFIG_UART_CONSOLE_IRQ; info->int_pri = CONFIG_UART_CONSOLE_INT_PRI; info->async_format = modeReg; uart_init(CONFIG_UART_CONSOLE_INDEX, info); uart_irq_rx_disable(CONFIG_UART_CONSOLE_INDEX); uart_irq_tx_disable(CONFIG_UART_CONSOLE_INDEX); uart_int_connect(CONFIG_UART_CONSOLE_INDEX, /* UART to which to connect */ UART_Handler, /* interrupt handler */ NULL, /* argument to pass to handler */ NULL /* ptr to interrupt stub code */ ); while (uart_irq_rx_ready(CONFIG_UART_CONSOLE_INDEX)) uart_fifo_read(CONFIG_UART_CONSOLE_INDEX, &c, 1); uart_irq_rx_enable(CONFIG_UART_CONSOLE_INDEX); }
static void bt_uart_isr(struct device *unused) { static int remaining; uint8_t byte; int ret; static uint8_t hdr[4]; ARG_UNUSED(unused); while (uart_irq_update(h5_dev) && uart_irq_is_pending(h5_dev)) { if (!uart_irq_rx_ready(h5_dev)) { if (uart_irq_tx_ready(h5_dev)) { BT_DBG("transmit ready"); } else { BT_DBG("spurious interrupt"); } continue; } ret = uart_fifo_read(h5_dev, &byte, sizeof(byte)); if (!ret) { continue; } switch (h5.rx_state) { case START: if (byte == SLIP_DELIMITER) { h5.rx_state = HEADER; remaining = sizeof(hdr); } break; case HEADER: /* In a case we confuse ending slip delimeter * with starting one. */ if (byte == SLIP_DELIMITER) { remaining = sizeof(hdr); continue; } if (h5_unslip_byte(&byte) < 0) { h5_reset_rx(); continue; } memcpy(&hdr[sizeof(hdr) - remaining], &byte, 1); remaining--; if (remaining) { break; } remaining = H5_HDR_LEN(hdr); switch (H5_HDR_PKT_TYPE(hdr)) { case HCI_EVENT_PKT: h5.rx_buf = bt_buf_get_evt(); if (!h5.rx_buf) { BT_WARN("No available event buffers"); h5_reset_rx(); continue; } h5.rx_state = PAYLOAD; break; case HCI_ACLDATA_PKT: h5.rx_buf = bt_buf_get_acl(); if (!h5.rx_buf) { BT_WARN("No available data buffers"); h5_reset_rx(); continue; } h5.rx_state = PAYLOAD; break; case HCI_3WIRE_LINK_PKT: case HCI_3WIRE_ACK_PKT: h5.rx_buf = net_buf_get(&h5_sig, 0); if (!h5.rx_buf) { BT_WARN("No available signal buffers"); h5_reset_rx(); continue; } h5.rx_state = PAYLOAD; break; default: BT_ERR("Wrong packet type %u", H5_HDR_PKT_TYPE(hdr)); h5.rx_state = END; break; } break; case PAYLOAD: if (h5_unslip_byte(&byte) < 0) { h5_reset_rx(); continue; } memcpy(net_buf_add(h5.rx_buf, sizeof(byte)), &byte, sizeof(byte)); remaining--; if (!remaining) { h5.rx_state = END; } break; case END: if (byte != SLIP_DELIMITER) { BT_ERR("Missing ending SLIP_DELIMITER"); h5_reset_rx(); break; } BT_DBG("Received full packet: type %u", H5_HDR_PKT_TYPE(hdr)); /* Check when full packet is received, it can be done * when parsing packet header but we need to receive * full packet anyway to clear UART. */ if (H5_HDR_RELIABLE(hdr) && H5_HDR_SEQ(hdr) != h5.tx_ack) { BT_ERR("Seq expected %u got %u. Drop packet", h5.tx_ack, H5_HDR_SEQ(hdr)); h5_reset_rx(); break; } h5_process_complete_packet(hdr); h5.rx_state = START; break; } } }
static inline void read_payload(void) { struct net_buf *buf; bool prio; int read; if (!rx.buf) { rx.buf = get_rx(K_NO_WAIT); if (!rx.buf) { if (rx.discardable) { BT_WARN("Discarding event 0x%02x", rx.evt.evt); rx.discard = rx.remaining; reset_rx(); return; } BT_WARN("Failed to allocate, deferring to rx_thread"); uart_irq_rx_disable(h4_dev); return; } BT_DBG("Allocated rx.buf %p", rx.buf); if (rx.remaining > net_buf_tailroom(rx.buf)) { BT_ERR("Not enough space in buffer"); rx.discard = rx.remaining; reset_rx(); return; } copy_hdr(rx.buf); } read = uart_fifo_read(h4_dev, net_buf_tail(rx.buf), rx.remaining); net_buf_add(rx.buf, read); rx.remaining -= read; BT_DBG("got %d bytes, remaining %u", read, rx.remaining); BT_DBG("Payload (len %u): %s", rx.buf->len, bt_hex(rx.buf->data, rx.buf->len)); if (rx.remaining) { return; } prio = (rx.type == H4_EVT && bt_hci_evt_is_prio(rx.evt.evt)); buf = rx.buf; rx.buf = NULL; if (rx.type == H4_EVT) { bt_buf_set_type(buf, BT_BUF_EVT); } else { bt_buf_set_type(buf, BT_BUF_ACL_IN); } reset_rx(); if (prio) { BT_DBG("Calling bt_recv_prio(%p)", buf); bt_recv_prio(buf); } else { BT_DBG("Putting buf %p to rx fifo", buf); net_buf_put(&rx.fifo, buf); } }
static size_t h4_discard(struct device *uart, size_t len) { uint8_t buf[33]; return uart_fifo_read(uart, buf, min(len, sizeof(buf))); }