samples: usb: cdc_acm: Update CDC ACM echo sample
Update CDC ACM sample using ring buffer and fifo_fill / fifo_read functions. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This commit is contained in:
parent
2c672b92c8
commit
0e57e4fb78
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
* Copyright (c) 2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Sample app for CDC ACM class driver
|
||||
* @brief Sample echo app for CDC ACM class
|
||||
*
|
||||
* Sample app for USB CDC ACM class driver. The received data is echoed back
|
||||
* to the serial port.
|
||||
|
@ -17,108 +17,106 @@
|
|||
#include <device.h>
|
||||
#include <uart.h>
|
||||
#include <zephyr.h>
|
||||
#include <ring_buffer.h>
|
||||
|
||||
static const char *banner1 = "Send characters to the UART device\r\n";
|
||||
static const char *banner2 = "Characters read:\r\n";
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(cdc_acm_echo, LOG_LEVEL_DBG);
|
||||
|
||||
static volatile bool data_transmitted;
|
||||
static volatile bool data_arrived;
|
||||
static char data_buf[64];
|
||||
#define RING_BUF_SIZE 1024
|
||||
u8_t ring_buffer[RING_BUF_SIZE];
|
||||
|
||||
struct ring_buf ringbuf;
|
||||
|
||||
static void interrupt_handler(struct device *dev)
|
||||
{
|
||||
uart_irq_update(dev);
|
||||
while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
|
||||
if (uart_irq_rx_ready(dev)) {
|
||||
int recv_len, rb_len;
|
||||
u8_t buffer[64];
|
||||
size_t len = MIN(ring_buf_space_get(&ringbuf),
|
||||
sizeof(buffer));
|
||||
|
||||
if (uart_irq_tx_ready(dev)) {
|
||||
data_transmitted = true;
|
||||
}
|
||||
recv_len = uart_fifo_read(dev, buffer, len);
|
||||
|
||||
if (uart_irq_rx_ready(dev)) {
|
||||
data_arrived = true;
|
||||
}
|
||||
}
|
||||
rb_len = ring_buf_put(&ringbuf, buffer, recv_len);
|
||||
if (rb_len < recv_len) {
|
||||
LOG_ERR("Drop %u bytes", recv_len - rb_len);
|
||||
}
|
||||
|
||||
static void write_data(struct device *dev, const char *buf, int len)
|
||||
{
|
||||
uart_irq_tx_enable(dev);
|
||||
LOG_DBG("tty fifo -> ringbuf %d bytes", rb_len);
|
||||
|
||||
while (len) {
|
||||
int written;
|
||||
|
||||
data_transmitted = false;
|
||||
written = uart_fifo_fill(dev, (const u8_t *)buf, len);
|
||||
while (data_transmitted == false) {
|
||||
k_yield();
|
||||
uart_irq_tx_enable(dev);
|
||||
}
|
||||
|
||||
len -= written;
|
||||
buf += written;
|
||||
}
|
||||
if (uart_irq_tx_ready(dev)) {
|
||||
u8_t buffer[64];
|
||||
int rb_len, send_len;
|
||||
|
||||
uart_irq_tx_disable(dev);
|
||||
}
|
||||
rb_len = ring_buf_get(&ringbuf, buffer, sizeof(buffer));
|
||||
if (!rb_len) {
|
||||
LOG_DBG("Ring buffer empty, disable TX IRQ");
|
||||
uart_irq_tx_disable(dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
static void read_and_echo_data(struct device *dev, int *bytes_read)
|
||||
{
|
||||
while (data_arrived == false)
|
||||
;
|
||||
send_len = uart_fifo_fill(dev, buffer, rb_len);
|
||||
if (send_len < rb_len) {
|
||||
LOG_ERR("Drop %d bytes", rb_len - send_len);
|
||||
}
|
||||
|
||||
data_arrived = false;
|
||||
|
||||
/* Read all data and echo it back */
|
||||
while ((*bytes_read = uart_fifo_read(dev,
|
||||
(u8_t *)data_buf, sizeof(data_buf)))) {
|
||||
write_data(dev, data_buf, *bytes_read);
|
||||
LOG_DBG("ringbuf -> tty fifo %d bytes", send_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
struct device *dev;
|
||||
u32_t baudrate, bytes_read, dtr = 0U;
|
||||
u32_t baudrate, dtr = 0U;
|
||||
int ret;
|
||||
|
||||
dev = device_get_binding("CDC_ACM_0");
|
||||
if (!dev) {
|
||||
printf("CDC ACM device not found\n");
|
||||
LOG_ERR("CDC ACM device not found");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Wait for DTR\n");
|
||||
while (1) {
|
||||
ring_buf_init(&ringbuf, sizeof(ring_buffer), ring_buffer);
|
||||
|
||||
LOG_DBG("Wait for DTR");
|
||||
|
||||
while (true) {
|
||||
uart_line_ctrl_get(dev, LINE_CTRL_DTR, &dtr);
|
||||
if (dtr)
|
||||
if (dtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("DTR set, start test\n");
|
||||
|
||||
LOG_DBG("DTR set");
|
||||
|
||||
/* They are optional, we use them to test the interrupt endpoint */
|
||||
ret = uart_line_ctrl_set(dev, LINE_CTRL_DCD, 1);
|
||||
if (ret)
|
||||
printf("Failed to set DCD, ret code %d\n", ret);
|
||||
if (ret) {
|
||||
LOG_WRN("Failed to set DCD, ret code %d", ret);
|
||||
}
|
||||
|
||||
ret = uart_line_ctrl_set(dev, LINE_CTRL_DSR, 1);
|
||||
if (ret)
|
||||
printf("Failed to set DSR, ret code %d\n", ret);
|
||||
if (ret) {
|
||||
LOG_WRN("Failed to set DSR, ret code %d", ret);
|
||||
}
|
||||
|
||||
/* Wait 1 sec for the host to do all settings */
|
||||
k_busy_wait(1000000);
|
||||
|
||||
ret = uart_line_ctrl_get(dev, LINE_CTRL_BAUD_RATE, &baudrate);
|
||||
if (ret)
|
||||
printf("Failed to get baudrate, ret code %d\n", ret);
|
||||
else
|
||||
printf("Baudrate detected: %d\n", baudrate);
|
||||
if (ret) {
|
||||
LOG_WRN("Failed to get baudrate, ret code %d", ret);
|
||||
} else {
|
||||
LOG_INF("Baudrate detected: %d", baudrate);
|
||||
}
|
||||
|
||||
uart_irq_callback_set(dev, interrupt_handler);
|
||||
write_data(dev, banner1, strlen(banner1));
|
||||
write_data(dev, banner2, strlen(banner2));
|
||||
|
||||
/* Enable rx interrupts */
|
||||
uart_irq_rx_enable(dev);
|
||||
|
||||
/* Echo the received data */
|
||||
while (1) {
|
||||
read_and_echo_data(dev, (int *) &bytes_read);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue