Skip to content

Commit cd95560

Browse files
finikorgcarlescufi
authored andcommitted
usb: cdc_acm: Use ringbuf for RX path
Use ringbuf library for handling RX CDC ACM path. Remove old code artifacts handling specific hardware. Fixes #14288 Signed-off-by: Andrei Emeltchenko <[email protected]>
1 parent 57b92e9 commit cd95560

File tree

2 files changed

+17
-50
lines changed

2 files changed

+17
-50
lines changed

subsys/usb/class/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ config USB_CDC_ACM
1010
bool "USB CDC ACM Device Class Driver"
1111
select SERIAL_HAS_DRIVER
1212
select SERIAL_SUPPORT_INTERRUPT
13+
select RING_BUFFER
1314
help
1415
USB CDC ACM device class driver
1516

subsys/usb/class/cdc_acm.c

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <init.h>
4242
#include <uart.h>
4343
#include <string.h>
44+
#include <ring_buffer.h>
4445
#include <misc/byteorder.h>
4546
#include <usb/class/usb_cdc.h>
4647
#include <usb/usb_device.h>
@@ -190,8 +191,7 @@ struct cdc_acm_dev_data_t {
190191
bool tx_irq_ena; /* Tx interrupt enable status */
191192
bool rx_irq_ena; /* Rx interrupt enable status */
192193
u8_t rx_buf[CDC_ACM_BUFFER_SIZE];/* Internal Rx buffer */
193-
u32_t rx_buf_head; /* Head of the internal Rx buffer */
194-
u32_t rx_buf_tail; /* Tail of the internal Rx buffer */
194+
struct ring_buf *rx_ringbuf;
195195
/* Interface data buffer */
196196
#ifndef CONFIG_USB_COMPOSITE_DEVICE
197197
u8_t interface_data[CDC_CLASS_REQ_MAX_DATA_SIZE];
@@ -314,9 +314,8 @@ static void cdc_acm_bulk_in(u8_t ep, enum usb_dc_ep_cb_status_code ep_status)
314314
static void cdc_acm_bulk_out(u8_t ep, enum usb_dc_ep_cb_status_code ep_status)
315315
{
316316
struct cdc_acm_dev_data_t *dev_data;
317-
u32_t bytes_to_read, i, j, buf_head;
318317
struct usb_dev_data *common;
319-
u8_t tmp_buf[4];
318+
u32_t bytes_to_read, read;
320319

321320
ARG_UNUSED(ep_status);
322321

@@ -329,35 +328,16 @@ static void cdc_acm_bulk_out(u8_t ep, enum usb_dc_ep_cb_status_code ep_status)
329328
dev_data = CONTAINER_OF(common, struct cdc_acm_dev_data_t, common);
330329

331330
/* Check how many bytes were received */
332-
usb_read(ep, NULL, 0, &bytes_to_read);
331+
usb_read(ep, NULL, 0, &read);
333332

334-
buf_head = dev_data->rx_buf_head;
333+
bytes_to_read = MIN(read, sizeof(dev_data->rx_buf));
335334

336-
/*
337-
* Quark SE USB controller is always storing data
338-
* in the FIFOs per 32-bit words.
339-
*/
340-
for (i = 0U; i < bytes_to_read; i += 4) {
341-
usb_read(ep, tmp_buf, 4, NULL);
342-
343-
for (j = 0U; j < 4; j++) {
344-
if (i + j == bytes_to_read) {
345-
/* We read all the data */
346-
break;
347-
}
348-
349-
if (((buf_head + 1) % CDC_ACM_BUFFER_SIZE) ==
350-
dev_data->rx_buf_tail) {
351-
/* FIFO full, discard data */
352-
LOG_ERR("CDC buffer full!");
353-
} else {
354-
dev_data->rx_buf[buf_head] = tmp_buf[j];
355-
buf_head = (buf_head + 1) % CDC_ACM_BUFFER_SIZE;
356-
}
357-
}
335+
usb_read(ep, dev_data->rx_buf, bytes_to_read, &read);
336+
337+
if (!ring_buf_put(dev_data->rx_ringbuf, dev_data->rx_buf, read)) {
338+
LOG_ERR("Ring buffer full");
358339
}
359340

360-
dev_data->rx_buf_head = buf_head;
361341
dev_data->rx_ready = true;
362342

363343
/* Call callback only if rx irq ena */
@@ -627,34 +607,18 @@ static int cdc_acm_fifo_fill(struct device *dev,
627607
*
628608
* @return Number of bytes read.
629609
*/
630-
static int cdc_acm_fifo_read(struct device *dev, u8_t *rx_data,
631-
const int size)
610+
static int cdc_acm_fifo_read(struct device *dev, u8_t *rx_data, const int size)
632611
{
633-
u32_t avail_data, bytes_read, i;
634612
struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
613+
u32_t len;
635614

636-
avail_data = (CDC_ACM_BUFFER_SIZE + dev_data->rx_buf_head -
637-
dev_data->rx_buf_tail) % CDC_ACM_BUFFER_SIZE;
638-
if (avail_data > size) {
639-
bytes_read = size;
640-
} else {
641-
bytes_read = avail_data;
642-
}
643-
644-
for (i = 0U; i < bytes_read; i++) {
645-
rx_data[i] = dev_data->rx_buf[(dev_data->rx_buf_tail + i) %
646-
CDC_ACM_BUFFER_SIZE];
647-
}
648-
649-
dev_data->rx_buf_tail = (dev_data->rx_buf_tail + bytes_read) %
650-
CDC_ACM_BUFFER_SIZE;
615+
len = ring_buf_get(dev_data->rx_ringbuf, rx_data, size);
651616

652-
if (dev_data->rx_buf_tail == dev_data->rx_buf_head) {
653-
/* Buffer empty */
617+
if (ring_buf_is_empty(dev_data->rx_ringbuf)) {
654618
dev_data->rx_ready = false;
655619
}
656620

657-
return bytes_read;
621+
return len;
658622
}
659623

660624
/**
@@ -1079,9 +1043,11 @@ static const struct uart_driver_api cdc_acm_driver_api = {
10791043
#endif /* CONFIG_USB_COMPOSITE_DEVICE */
10801044

10811045
#define DEFINE_CDC_ACM_DEV_DATA(x) \
1046+
RING_BUF_DECLARE(rx_ringbuf_##x, 512); \
10821047
static struct cdc_acm_dev_data_t cdc_acm_dev_data_##x = { \
10831048
.usb_status = USB_DC_UNKNOWN, \
10841049
.line_coding = CDC_ACM_DEFAUL_BAUDRATE, \
1050+
.rx_ringbuf = &rx_ringbuf_##x, \
10851051
}
10861052

10871053
#define DEFINE_CDC_ACM_DEVICE(x) \

0 commit comments

Comments
 (0)