Skip to content
Permalink
Browse files

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>
  • Loading branch information...
finikorg authored and nashif committed Apr 24, 2019
1 parent 2c672b9 commit 0e57e4fb78e0830e522eb4b78b646bf1470cb091
Showing with 59 additions and 61 deletions.
  1. +59 −61 samples/subsys/usb/cdc_acm/src/main.c
@@ -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);

if (uart_irq_tx_ready(dev)) {
data_transmitted = true;
}
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_rx_ready(dev)) {
data_arrived = true;
}
}
recv_len = uart_fifo_read(dev, buffer, len);

static void write_data(struct device *dev, const char *buf, int len)
{
uart_irq_tx_enable(dev);
rb_len = ring_buf_put(&ringbuf, buffer, recv_len);
if (rb_len < recv_len) {
LOG_ERR("Drop %u bytes", recv_len - rb_len);
}

while (len) {
int written;
LOG_DBG("tty fifo -> ringbuf %d bytes", rb_len);

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);
}

static void read_and_echo_data(struct device *dev, int *bytes_read)
{
while (data_arrived == false)
;
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;
}

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);
}

/* 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);
}
}

0 comments on commit 0e57e4f

Please sign in to comment.
You can’t perform that action at this time.