1 /*******************************************************************************
2 *
3 * Copyright(c) 2015-2019 Intel Corporation.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Intel Corporation nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 ******************************************************************************/
32
33 /**
34 * @file
35 * @brief CDC ACM device class driver
36 *
37 * Driver for USB CDC ACM device class driver
38 */
39
40 #include <zephyr/kernel.h>
41 #include <zephyr/init.h>
42 #include <zephyr/drivers/uart/cdc_acm.h>
43 #include <zephyr/drivers/uart.h>
44 #include <string.h>
45 #include <zephyr/sys/ring_buffer.h>
46 #include <zephyr/sys/byteorder.h>
47 #include <zephyr/usb/class/usb_cdc.h>
48 #include <zephyr/usb/usb_device.h>
49 #include <usb_descriptor.h>
50 #include <usb_work_q.h>
51
52 #ifndef CONFIG_UART_INTERRUPT_DRIVEN
53 #error "CONFIG_UART_INTERRUPT_DRIVEN must be set for CDC ACM driver"
54 #endif
55
56 /* definitions */
57
58 #include <zephyr/logging/log.h>
59 /* Prevent endless recursive logging loop and warn user about it */
60 #if defined(CONFIG_USB_CDC_ACM_LOG_LEVEL) && CONFIG_USB_CDC_ACM_LOG_LEVEL != LOG_LEVEL_NONE
61 #define CHOSEN_CONSOLE DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console), zephyr_cdc_acm_uart)
62 #define CHOSEN_SHELL DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_shell_uart), zephyr_cdc_acm_uart)
63 #if (CHOSEN_CONSOLE && defined(CONFIG_LOG_BACKEND_UART)) || \
64 (CHOSEN_SHELL && defined(CONFIG_SHELL_LOG_BACKEND))
65 #warning "USB_CDC_ACM_LOG_LEVEL forced to LOG_LEVEL_NONE"
66 #undef CONFIG_USB_CDC_ACM_LOG_LEVEL
67 #define CONFIG_USB_CDC_ACM_LOG_LEVEL LOG_LEVEL_NONE
68 #endif
69 #endif
70 LOG_MODULE_REGISTER(usb_cdc_acm, CONFIG_USB_CDC_ACM_LOG_LEVEL);
71
72 /* 115200bps, no parity, 1 stop bit, 8bit char */
73 #define CDC_ACM_DEFAULT_BAUDRATE {sys_cpu_to_le32(115200), 0, 0, 8}
74
75 /* Size of the internal buffer used for storing received data */
76 #define CDC_ACM_BUFFER_SIZE (CONFIG_CDC_ACM_BULK_EP_MPS)
77
78 /* Serial state notification timeout */
79 #define CDC_CONTROL_SERIAL_STATE_TIMEOUT_US 100000
80
81 #define ACM_INT_EP_IDX 0
82 #define ACM_OUT_EP_IDX 1
83 #define ACM_IN_EP_IDX 2
84
85 struct usb_cdc_acm_config {
86 struct usb_association_descriptor iad_cdc;
87 struct usb_if_descriptor if0;
88 struct cdc_header_descriptor if0_header;
89 struct cdc_cm_descriptor if0_cm;
90 struct cdc_acm_descriptor if0_acm;
91 struct cdc_union_descriptor if0_union;
92 struct usb_ep_descriptor if0_int_ep;
93
94 struct usb_if_descriptor if1;
95 struct usb_ep_descriptor if1_in_ep;
96 struct usb_ep_descriptor if1_out_ep;
97 } __packed;
98
99 /* Device data structure */
100 struct cdc_acm_dev_data_t {
101 /* Callback function pointer/arg */
102 uart_irq_callback_user_data_t cb;
103 void *cb_data;
104 struct k_work cb_work;
105 #if defined(CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT)
106 cdc_dte_rate_callback_t rate_cb;
107 #endif
108 struct k_work_delayable tx_work;
109 /* Tx ready status. Signals when */
110 bool tx_ready;
111 bool rx_ready; /* Rx ready status */
112 bool tx_irq_ena; /* Tx interrupt enable status */
113 bool rx_irq_ena; /* Rx interrupt enable status */
114 uint8_t rx_buf[CDC_ACM_BUFFER_SIZE]; /* Internal RX buffer */
115 struct ring_buf *rx_ringbuf;
116 struct ring_buf *tx_ringbuf;
117 /* Interface data buffer */
118 /* CDC ACM line coding properties. LE order */
119 struct cdc_acm_line_coding line_coding;
120 /* CDC ACM line state bitmap, DTE side */
121 uint8_t line_state;
122 /* CDC ACM serial state bitmap, DCE side */
123 uint8_t serial_state;
124 /* CDC ACM notification sent status */
125 uint8_t notification_sent;
126 /* CDC ACM configured flag */
127 bool configured;
128 /* CDC ACM suspended flag */
129 bool suspended;
130 /* CDC ACM paused flag */
131 bool rx_paused;
132 /* When flow_ctrl is set, poll out is blocked when the buffer is full,
133 * roughly emulating flow control.
134 */
135 bool flow_ctrl;
136
137 struct usb_dev_data common;
138 };
139
140 static sys_slist_t cdc_acm_data_devlist;
141 static DEVICE_API(uart, cdc_acm_driver_api);
142
143 /**
144 * @brief Handler called for Class requests not handled by the USB stack.
145 *
146 * @param setup Information about the request to execute.
147 * @param len Size of the buffer.
148 * @param data Buffer containing the request result.
149 *
150 * @return 0 on success, negative errno code on fail.
151 */
cdc_acm_class_handle_req(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data)152 int cdc_acm_class_handle_req(struct usb_setup_packet *setup,
153 int32_t *len, uint8_t **data)
154 {
155 struct cdc_acm_dev_data_t *dev_data;
156 struct usb_dev_data *common;
157 uint32_t rate;
158 uint32_t new_rate;
159
160 common = usb_get_dev_data_by_iface(&cdc_acm_data_devlist,
161 (uint8_t)setup->wIndex);
162 if (common == NULL) {
163 LOG_WRN("Device data not found for interface %u",
164 setup->wIndex);
165 return -ENODEV;
166 }
167
168 dev_data = CONTAINER_OF(common, struct cdc_acm_dev_data_t, common);
169
170 if (usb_reqtype_is_to_device(setup)) {
171 switch (setup->bRequest) {
172 case SET_LINE_CODING:
173 rate = sys_le32_to_cpu(dev_data->line_coding.dwDTERate);
174 memcpy(&dev_data->line_coding, *data,
175 sizeof(dev_data->line_coding));
176 new_rate = sys_le32_to_cpu(dev_data->line_coding.dwDTERate);
177 LOG_DBG("CDC_SET_LINE_CODING %d %d %d %d",
178 new_rate,
179 dev_data->line_coding.bCharFormat,
180 dev_data->line_coding.bParityType,
181 dev_data->line_coding.bDataBits);
182 #if defined(CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT)
183 if (rate != new_rate && dev_data->rate_cb != NULL) {
184 dev_data->rate_cb(common->dev, new_rate);
185 }
186 #endif
187 return 0;
188
189 case SET_CONTROL_LINE_STATE:
190 dev_data->line_state = (uint8_t)setup->wValue;
191 LOG_DBG("CDC_SET_CONTROL_LINE_STATE 0x%x",
192 dev_data->line_state);
193 return 0;
194
195 default:
196 break;
197 }
198 } else {
199 if (setup->bRequest == GET_LINE_CODING) {
200 *data = (uint8_t *)(&dev_data->line_coding);
201 *len = sizeof(dev_data->line_coding);
202 LOG_DBG("CDC_GET_LINE_CODING %d %d %d %d",
203 sys_le32_to_cpu(dev_data->line_coding.dwDTERate),
204 dev_data->line_coding.bCharFormat,
205 dev_data->line_coding.bParityType,
206 dev_data->line_coding.bDataBits);
207 return 0;
208 }
209 }
210
211 LOG_DBG("CDC ACM bmRequestType 0x%02x bRequest 0x%02x unsupported",
212 setup->bmRequestType, setup->bRequest);
213 return -ENOTSUP;
214 }
215
cdc_acm_write_cb(uint8_t ep,int size,void * priv)216 static void cdc_acm_write_cb(uint8_t ep, int size, void *priv)
217 {
218 struct cdc_acm_dev_data_t *dev_data = priv;
219
220 LOG_DBG("ep %x: written %d bytes dev_data %p", ep, size, dev_data);
221
222 dev_data->tx_ready = true;
223
224 /* Call callback only if tx irq ena */
225 if (dev_data->cb && dev_data->tx_irq_ena) {
226 k_work_submit_to_queue(&USB_WORK_Q, &dev_data->cb_work);
227 }
228
229 /* If size is 0, we want to schedule tx work even if ringbuf is empty to
230 * ensure that actual payload will not be sent before initialization
231 * timeout passes.
232 */
233 if (ring_buf_is_empty(dev_data->tx_ringbuf) && size) {
234 LOG_DBG("tx_ringbuf is empty");
235 return;
236 }
237
238 /* If size is 0, it means that host started polling IN data because it
239 * has read the ZLP we armed when interface was configured. This ZLP is
240 * probably the best indication that host has started to read the data.
241 * Wait initialization timeout before sending actual payload to make it
242 * possible for application to disable ECHO. The echo is long known
243 * problem related to the fact that POSIX defaults to ECHO ON and thus
244 * every application that opens tty device (on Linux) will have ECHO
245 * enabled in the short window between open() and ioctl() that disables
246 * the echo (if application wishes to disable the echo).
247 */
248 k_work_schedule_for_queue(&USB_WORK_Q, &dev_data->tx_work, size ?
249 K_NO_WAIT : K_MSEC(CONFIG_CDC_ACM_TX_DELAY_MS));
250 }
251
tx_work_handler(struct k_work * work)252 static void tx_work_handler(struct k_work *work)
253 {
254 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
255 struct cdc_acm_dev_data_t *dev_data =
256 CONTAINER_OF(dwork, struct cdc_acm_dev_data_t, tx_work);
257 const struct device *dev = dev_data->common.dev;
258 struct usb_cfg_data *cfg = (void *)dev->config;
259 uint8_t ep = cfg->endpoint[ACM_IN_EP_IDX].ep_addr;
260 uint8_t *data;
261 size_t len;
262
263 if (usb_transfer_is_busy(ep)) {
264 LOG_DBG("Transfer is ongoing");
265 return;
266 }
267
268 if (!dev_data->configured) {
269 return;
270 }
271
272 len = ring_buf_get_claim(dev_data->tx_ringbuf, &data,
273 CONFIG_USB_CDC_ACM_RINGBUF_SIZE);
274
275 if (!len) {
276 LOG_DBG("Nothing to send");
277 return;
278 }
279
280 dev_data->tx_ready = false;
281
282 /*
283 * Transfer less data to avoid zero-length packet. The application
284 * running on the host may conclude that there is no more data to be
285 * received (i.e. the transaction has completed), hence not triggering
286 * another I/O Request Packet (IRP).
287 */
288 if (!(len % CONFIG_CDC_ACM_BULK_EP_MPS)) {
289 len -= 1;
290 }
291
292 LOG_DBG("Got %zd bytes from ringbuffer send to ep %x", len, ep);
293
294 usb_transfer(ep, data, len, USB_TRANS_WRITE,
295 cdc_acm_write_cb, dev_data);
296
297 ring_buf_get_finish(dev_data->tx_ringbuf, len);
298 }
299
cdc_acm_read_cb(uint8_t ep,int size,void * priv)300 static void cdc_acm_read_cb(uint8_t ep, int size, void *priv)
301 {
302 struct cdc_acm_dev_data_t *dev_data = priv;
303 size_t wrote;
304
305 LOG_DBG("ep %x size %d dev_data %p rx_ringbuf space %u",
306 ep, size, dev_data, ring_buf_space_get(dev_data->rx_ringbuf));
307
308 if (size <= 0) {
309 goto done;
310 }
311
312 wrote = ring_buf_put(dev_data->rx_ringbuf, dev_data->rx_buf, size);
313 if (wrote < size) {
314 LOG_ERR("Ring buffer full, drop %zd bytes", size - wrote);
315 }
316
317 dev_data->rx_ready = true;
318
319 /* Call callback only if rx irq ena */
320 if (dev_data->cb && dev_data->rx_irq_ena) {
321 k_work_submit_to_queue(&USB_WORK_Q, &dev_data->cb_work);
322 }
323
324 if (ring_buf_space_get(dev_data->rx_ringbuf) < sizeof(dev_data->rx_buf)) {
325 dev_data->rx_paused = true;
326 return;
327 }
328
329 done:
330 if (dev_data->configured) {
331 usb_transfer(ep, dev_data->rx_buf, sizeof(dev_data->rx_buf),
332 USB_TRANS_READ, cdc_acm_read_cb, dev_data);
333 }
334 }
335
336 /**
337 * @brief EP Interrupt handler
338 *
339 * @param ep Endpoint address.
340 * @param ep_status Endpoint status code.
341 */
cdc_acm_int_in(uint8_t ep,enum usb_dc_ep_cb_status_code ep_status)342 static void cdc_acm_int_in(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
343 {
344 struct cdc_acm_dev_data_t *dev_data;
345 struct usb_dev_data *common;
346
347 ARG_UNUSED(ep_status);
348
349 common = usb_get_dev_data_by_ep(&cdc_acm_data_devlist, ep);
350 if (common == NULL) {
351 LOG_WRN("Device data not found for endpoint %u", ep);
352 return;
353 }
354
355 dev_data = CONTAINER_OF(common, struct cdc_acm_dev_data_t, common);
356
357 dev_data->notification_sent = 1U;
358 LOG_DBG("CDC_IntIN EP[%x]\r", ep);
359 }
360
cdc_acm_reset_port(struct cdc_acm_dev_data_t * dev_data)361 static void cdc_acm_reset_port(struct cdc_acm_dev_data_t *dev_data)
362 {
363 dev_data->configured = false;
364 dev_data->suspended = false;
365 dev_data->rx_ready = false;
366 dev_data->tx_ready = false;
367 dev_data->line_coding = (struct cdc_acm_line_coding)
368 CDC_ACM_DEFAULT_BAUDRATE;
369 dev_data->serial_state = 0;
370 dev_data->line_state = 0;
371 dev_data->rx_paused = false;
372 memset(&dev_data->rx_buf, 0, CDC_ACM_BUFFER_SIZE);
373 }
374
cdc_acm_do_cb(struct cdc_acm_dev_data_t * dev_data,enum usb_dc_status_code status,const uint8_t * param)375 static void cdc_acm_do_cb(struct cdc_acm_dev_data_t *dev_data,
376 enum usb_dc_status_code status,
377 const uint8_t *param)
378 {
379 const struct device *dev = dev_data->common.dev;
380 struct usb_cfg_data *cfg = (void *)dev->config;
381
382 /* Check the USB status and do needed action if required */
383 switch (status) {
384 case USB_DC_ERROR:
385 LOG_DBG("Device error");
386 break;
387 case USB_DC_RESET:
388 LOG_DBG("Device reset detected");
389 cdc_acm_reset_port(dev_data);
390 break;
391 case USB_DC_CONNECTED:
392 LOG_DBG("Device connected");
393 break;
394 case USB_DC_CONFIGURED:
395 LOG_INF("Device configured");
396 if (!dev_data->configured) {
397 dev_data->configured = true;
398 cdc_acm_read_cb(cfg->endpoint[ACM_OUT_EP_IDX].ep_addr, 0,
399 dev_data);
400 /* Queue ZLP on IN endpoint so we know when host starts polling */
401 if (!dev_data->tx_ready) {
402 usb_transfer(cfg->endpoint[ACM_IN_EP_IDX].ep_addr, NULL, 0,
403 USB_TRANS_WRITE, cdc_acm_write_cb, dev_data);
404 }
405 }
406 break;
407 case USB_DC_DISCONNECTED:
408 LOG_INF("Device disconnected");
409 cdc_acm_reset_port(dev_data);
410 break;
411 case USB_DC_SUSPEND:
412 LOG_INF("Device suspended");
413 dev_data->suspended = true;
414 break;
415 case USB_DC_RESUME:
416 LOG_INF("Device resumed");
417 if (dev_data->suspended) {
418 LOG_INF("from suspend");
419 dev_data->suspended = false;
420 } else {
421 LOG_DBG("Spurious resume event");
422 }
423 break;
424 case USB_DC_SOF:
425 case USB_DC_INTERFACE:
426 break;
427 case USB_DC_UNKNOWN:
428 default:
429 LOG_DBG("Unknown event");
430 break;
431 }
432 }
433
cdc_acm_dev_status_cb(struct usb_cfg_data * cfg,enum usb_dc_status_code status,const uint8_t * param)434 static void cdc_acm_dev_status_cb(struct usb_cfg_data *cfg,
435 enum usb_dc_status_code status,
436 const uint8_t *param)
437 {
438 struct cdc_acm_dev_data_t *dev_data;
439 struct usb_dev_data *common;
440
441 LOG_DBG("cfg %p status %d", cfg, status);
442
443 common = usb_get_dev_data_by_cfg(&cdc_acm_data_devlist, cfg);
444 if (common == NULL) {
445 LOG_WRN("Device data not found for cfg %p", cfg);
446 return;
447 }
448
449 dev_data = CONTAINER_OF(common, struct cdc_acm_dev_data_t, common);
450
451 cdc_acm_do_cb(dev_data, status, param);
452 }
453
cdc_interface_config(struct usb_desc_header * head,uint8_t bInterfaceNumber)454 static void cdc_interface_config(struct usb_desc_header *head,
455 uint8_t bInterfaceNumber)
456 {
457 struct usb_if_descriptor *if_desc = (struct usb_if_descriptor *) head;
458 struct usb_cdc_acm_config *desc =
459 CONTAINER_OF(if_desc, struct usb_cdc_acm_config, if0);
460
461 desc->if0.bInterfaceNumber = bInterfaceNumber;
462 desc->if0_union.bControlInterface = bInterfaceNumber;
463 desc->if1.bInterfaceNumber = bInterfaceNumber + 1;
464 desc->if0_union.bSubordinateInterface0 = bInterfaceNumber + 1;
465 desc->iad_cdc.bFirstInterface = bInterfaceNumber;
466 }
467
468 /**
469 * @brief Call the IRQ function callback.
470 *
471 * This routine is called from the system work queue to signal an UART
472 * IRQ.
473 *
474 * @param work Address of work item.
475 */
cdc_acm_irq_callback_work_handler(struct k_work * work)476 static void cdc_acm_irq_callback_work_handler(struct k_work *work)
477 {
478 struct cdc_acm_dev_data_t *dev_data;
479
480 dev_data = CONTAINER_OF(work, struct cdc_acm_dev_data_t, cb_work);
481
482 dev_data->cb(dev_data->common.dev, dev_data->cb_data);
483 }
484
485 /**
486 * @brief Initialize UART channel
487 *
488 * This routine is called to reset the chip in a quiescent state.
489 * It is assumed that this function is called only once per UART.
490 *
491 * @param dev CDC ACM device struct.
492 *
493 * @return 0 always.
494 */
cdc_acm_init(const struct device * dev)495 static int cdc_acm_init(const struct device *dev)
496 {
497 struct cdc_acm_dev_data_t * const dev_data = dev->data;
498 int ret = 0;
499
500 dev_data->common.dev = dev;
501 sys_slist_append(&cdc_acm_data_devlist, &dev_data->common.node);
502
503 LOG_DBG("Device dev %p dev_data %p cfg %p added to devlist %p",
504 dev, dev_data, dev->config, &cdc_acm_data_devlist);
505
506 k_work_init(&dev_data->cb_work, cdc_acm_irq_callback_work_handler);
507 k_work_init_delayable(&dev_data->tx_work, tx_work_handler);
508
509 return ret;
510 }
511
512 /**
513 * @brief Fill FIFO with data
514 *
515 * @param dev CDC ACM device struct.
516 * @param tx_data Data to transmit.
517 * @param len Number of bytes to send.
518 *
519 * @return Number of bytes sent.
520 */
cdc_acm_fifo_fill(const struct device * dev,const uint8_t * tx_data,int len)521 static int cdc_acm_fifo_fill(const struct device *dev,
522 const uint8_t *tx_data, int len)
523 {
524 struct cdc_acm_dev_data_t * const dev_data = dev->data;
525 unsigned int lock;
526 size_t wrote;
527
528 LOG_DBG("dev_data %p len %d tx_ringbuf space %u",
529 dev_data, len, ring_buf_space_get(dev_data->tx_ringbuf));
530
531 lock = irq_lock();
532 wrote = ring_buf_put(dev_data->tx_ringbuf, tx_data, len);
533 irq_unlock(lock);
534 LOG_DBG("Wrote %zu of %d bytes to TX ringbuffer", wrote, len);
535
536 if (wrote) {
537 k_work_schedule_for_queue(&USB_WORK_Q, &dev_data->tx_work, K_NO_WAIT);
538 }
539
540 /* Return written to ringbuf data len */
541 return wrote;
542 }
543
544 /**
545 * @brief Read data from FIFO
546 *
547 * @param dev CDC ACM device struct.
548 * @param rx_data Pointer to data container.
549 * @param size Container size.
550 *
551 * @return Number of bytes read.
552 */
cdc_acm_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)553 static int cdc_acm_fifo_read(const struct device *dev, uint8_t *rx_data,
554 const int size)
555 {
556 struct cdc_acm_dev_data_t * const dev_data = dev->data;
557 uint32_t len;
558
559 LOG_DBG("dev %p size %d rx_ringbuf space %u",
560 dev, size, ring_buf_space_get(dev_data->rx_ringbuf));
561
562 len = ring_buf_get(dev_data->rx_ringbuf, rx_data, size);
563
564 if (dev_data->rx_paused == true) {
565 if (ring_buf_space_get(dev_data->rx_ringbuf) >= CDC_ACM_BUFFER_SIZE) {
566 struct usb_cfg_data *cfg = (void *)dev->config;
567
568 if (dev_data->configured) {
569 cdc_acm_read_cb(cfg->endpoint[ACM_OUT_EP_IDX].ep_addr, 0, dev_data);
570 }
571 dev_data->rx_paused = false;
572 }
573 }
574
575 return len;
576 }
577
578 /**
579 * @brief Enable TX interrupt
580 *
581 * @param dev CDC ACM device struct.
582 */
cdc_acm_irq_tx_enable(const struct device * dev)583 static void cdc_acm_irq_tx_enable(const struct device *dev)
584 {
585 struct cdc_acm_dev_data_t * const dev_data = dev->data;
586
587 dev_data->tx_irq_ena = true;
588
589 if (dev_data->cb && dev_data->tx_ready) {
590 k_work_submit_to_queue(&USB_WORK_Q, &dev_data->cb_work);
591 }
592 }
593
594 /**
595 * @brief Disable TX interrupt
596 *
597 * @param dev CDC ACM device struct.
598 */
cdc_acm_irq_tx_disable(const struct device * dev)599 static void cdc_acm_irq_tx_disable(const struct device *dev)
600 {
601 struct cdc_acm_dev_data_t * const dev_data = dev->data;
602
603 dev_data->tx_irq_ena = false;
604 }
605
606 /**
607 * @brief Check if Tx IRQ has been raised
608 *
609 * @param dev CDC ACM device struct.
610 *
611 * @return 1 if a Tx IRQ is pending, 0 otherwise.
612 */
cdc_acm_irq_tx_ready(const struct device * dev)613 static int cdc_acm_irq_tx_ready(const struct device *dev)
614 {
615 struct cdc_acm_dev_data_t * const dev_data = dev->data;
616
617 if (dev_data->tx_irq_ena && dev_data->tx_ready) {
618 return ring_buf_space_get(dev_data->tx_ringbuf);
619 }
620
621 return 0;
622 }
623
624 /**
625 * @brief Enable RX interrupt
626 *
627 * @param dev CDC ACM device struct.
628 */
cdc_acm_irq_rx_enable(const struct device * dev)629 static void cdc_acm_irq_rx_enable(const struct device *dev)
630 {
631 struct cdc_acm_dev_data_t * const dev_data = dev->data;
632
633 dev_data->rx_irq_ena = true;
634
635 if (dev_data->cb && dev_data->rx_ready) {
636 k_work_submit_to_queue(&USB_WORK_Q, &dev_data->cb_work);
637 }
638 }
639
640 /**
641 * @brief Disable RX interrupt
642 *
643 * @param dev CDC ACM device struct.
644 */
cdc_acm_irq_rx_disable(const struct device * dev)645 static void cdc_acm_irq_rx_disable(const struct device *dev)
646 {
647 struct cdc_acm_dev_data_t * const dev_data = dev->data;
648
649 dev_data->rx_irq_ena = false;
650 }
651
652 /**
653 * @brief Check if Rx IRQ has been raised
654 *
655 * @param dev CDC ACM device struct.
656 *
657 * @return 1 if an IRQ is ready, 0 otherwise.
658 */
cdc_acm_irq_rx_ready(const struct device * dev)659 static int cdc_acm_irq_rx_ready(const struct device *dev)
660 {
661 struct cdc_acm_dev_data_t * const dev_data = dev->data;
662
663 if (dev_data->rx_ready && dev_data->rx_irq_ena) {
664 return 1;
665 }
666
667 return 0;
668 }
669
670 /**
671 * @brief Check if Tx or Rx IRQ is pending
672 *
673 * @param dev CDC ACM device struct.
674 *
675 * @return 1 if a Tx or Rx IRQ is pending, 0 otherwise.
676 */
cdc_acm_irq_is_pending(const struct device * dev)677 static int cdc_acm_irq_is_pending(const struct device *dev)
678 {
679 if (cdc_acm_irq_rx_ready(dev) || cdc_acm_irq_tx_ready(dev)) {
680 return 1;
681 }
682
683 return 0;
684 }
685
686 /**
687 * @brief Update IRQ status
688 *
689 * @param dev CDC ACM device struct.
690 *
691 * @return Always 1
692 */
cdc_acm_irq_update(const struct device * dev)693 static int cdc_acm_irq_update(const struct device *dev)
694 {
695 struct cdc_acm_dev_data_t * const dev_data = dev->data;
696
697 if (!ring_buf_space_get(dev_data->tx_ringbuf)) {
698 dev_data->tx_ready = false;
699 }
700
701 if (ring_buf_is_empty(dev_data->rx_ringbuf)) {
702 dev_data->rx_ready = false;
703 }
704
705 return 1;
706 }
707
708 /**
709 * @brief Set the callback function pointer for IRQ.
710 *
711 * @param dev CDC ACM device struct.
712 * @param cb Callback function pointer.
713 */
cdc_acm_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)714 static void cdc_acm_irq_callback_set(const struct device *dev,
715 uart_irq_callback_user_data_t cb,
716 void *cb_data)
717 {
718 struct cdc_acm_dev_data_t * const dev_data = dev->data;
719
720 dev_data->cb = cb;
721 dev_data->cb_data = cb_data;
722 }
723
724 #if defined(CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT)
cdc_acm_dte_rate_callback_set(const struct device * dev,cdc_dte_rate_callback_t callback)725 int cdc_acm_dte_rate_callback_set(const struct device *dev,
726 cdc_dte_rate_callback_t callback)
727 {
728 struct cdc_acm_dev_data_t *const dev_data = dev->data;
729
730 if (dev->api != &cdc_acm_driver_api) {
731 return -EINVAL;
732 }
733
734 dev_data->rate_cb = callback;
735
736 return 0;
737 }
738 #endif
739
740 #ifdef CONFIG_UART_LINE_CTRL
741
742 /**
743 * @brief Set the baud rate
744 *
745 * This routine set the given baud rate for the UART.
746 *
747 * @param dev CDC ACM device struct.
748 * @param baudrate Baud rate.
749 */
cdc_acm_baudrate_set(const struct device * dev,uint32_t baudrate)750 static void cdc_acm_baudrate_set(const struct device *dev, uint32_t baudrate)
751 {
752 struct cdc_acm_dev_data_t * const dev_data = dev->data;
753
754 dev_data->line_coding.dwDTERate = sys_cpu_to_le32(baudrate);
755 }
756
757 /**
758 * @brief Send serial line state notification to the Host
759 *
760 * This routine sends asynchronous notification of UART status
761 * on the interrupt endpoint
762 *
763 * @param dev CDC ACM device struct.
764 * @param ep_status Endpoint status code.
765 *
766 * @retval 0 on success.
767 * @retval -EIO if timed out.
768 */
cdc_acm_send_notification(const struct device * dev,uint16_t serial_state)769 static int cdc_acm_send_notification(const struct device *dev,
770 uint16_t serial_state)
771 {
772 struct cdc_acm_dev_data_t * const dev_data = dev->data;
773 struct usb_cfg_data * const cfg = (void *)dev->config;
774 struct cdc_acm_notification notification;
775 uint32_t cnt = 0U;
776
777 notification.bmRequestType = 0xA1;
778 notification.bNotificationType = 0x20;
779 notification.wValue = 0U;
780 notification.wIndex = 0U;
781 notification.wLength = sys_cpu_to_le16(sizeof(serial_state));
782 notification.data = sys_cpu_to_le16(serial_state);
783
784 dev_data->notification_sent = 0U;
785
786 usb_write(cfg->endpoint[ACM_INT_EP_IDX].ep_addr,
787 (const uint8_t *)¬ification, sizeof(notification), NULL);
788
789 /* Wait for notification to be sent */
790 while (!((volatile uint8_t)dev_data->notification_sent)) {
791 k_busy_wait(1);
792
793 if (++cnt > CDC_CONTROL_SERIAL_STATE_TIMEOUT_US) {
794 LOG_DBG("CDC ACM notification timeout!");
795 return -EIO;
796 }
797 }
798
799 return 0;
800 }
801
802 /**
803 * @brief Manipulate line control for UART.
804 *
805 * @param dev CDC ACM device struct
806 * @param ctrl The line control to be manipulated
807 * @param val Value to set the line control
808 *
809 * @return 0 if successful, failed otherwise.
810 */
cdc_acm_line_ctrl_set(const struct device * dev,uint32_t ctrl,uint32_t val)811 static int cdc_acm_line_ctrl_set(const struct device *dev,
812 uint32_t ctrl, uint32_t val)
813 {
814 struct cdc_acm_dev_data_t * const dev_data = dev->data;
815
816 switch (ctrl) {
817 case USB_CDC_LINE_CTRL_BAUD_RATE:
818 cdc_acm_baudrate_set(dev, val);
819 return 0;
820 case USB_CDC_LINE_CTRL_DCD:
821 dev_data->serial_state &= ~SERIAL_STATE_RX_CARRIER;
822
823 if (val) {
824 dev_data->serial_state |= SERIAL_STATE_RX_CARRIER;
825 }
826 cdc_acm_send_notification(dev, SERIAL_STATE_RX_CARRIER);
827 return 0;
828 case USB_CDC_LINE_CTRL_DSR:
829 dev_data->serial_state &= ~SERIAL_STATE_TX_CARRIER;
830
831 if (val) {
832 dev_data->serial_state |= SERIAL_STATE_TX_CARRIER;
833 }
834 cdc_acm_send_notification(dev, dev_data->serial_state);
835 return 0;
836 case USB_CDC_LINE_CTRL_BREAK:
837 dev_data->serial_state &= ~SERIAL_STATE_BREAK;
838
839 if (val) {
840 dev_data->serial_state |= SERIAL_STATE_BREAK;
841 }
842 cdc_acm_send_notification(dev, dev_data->serial_state);
843 return 0;
844 case USB_CDC_LINE_CTRL_RING_SIGNAL:
845 dev_data->serial_state &= ~SERIAL_STATE_RING_SIGNAL;
846
847 if (val) {
848 dev_data->serial_state |= SERIAL_STATE_RING_SIGNAL;
849 }
850 cdc_acm_send_notification(dev, dev_data->serial_state);
851 return 0;
852 case USB_CDC_LINE_CTRL_FRAMING:
853 dev_data->serial_state &= ~SERIAL_STATE_FRAMING;
854
855 if (val) {
856 dev_data->serial_state |= SERIAL_STATE_FRAMING;
857 }
858 cdc_acm_send_notification(dev, dev_data->serial_state);
859 return 0;
860 case USB_CDC_LINE_CTRL_PARITY:
861 dev_data->serial_state &= ~SERIAL_STATE_PARITY;
862
863 if (val) {
864 dev_data->serial_state |= SERIAL_STATE_PARITY;
865 }
866 cdc_acm_send_notification(dev, dev_data->serial_state);
867 return 0;
868 case USB_CDC_LINE_CTRL_OVER_RUN:
869 dev_data->serial_state &= ~SERIAL_STATE_OVER_RUN;
870
871 if (val) {
872 dev_data->serial_state |= SERIAL_STATE_OVER_RUN;
873 }
874 cdc_acm_send_notification(dev, dev_data->serial_state);
875 return 0;
876 default:
877 return -ENODEV;
878 }
879
880 return -ENOTSUP;
881 }
882
883 /**
884 * @brief Manipulate line control for UART.
885 *
886 * @param dev CDC ACM device struct
887 * @param ctrl The line control to be manipulated
888 * @param val Value to set the line control
889 *
890 * @return 0 if successful, failed otherwise.
891 */
cdc_acm_line_ctrl_get(const struct device * dev,uint32_t ctrl,uint32_t * val)892 static int cdc_acm_line_ctrl_get(const struct device *dev,
893 uint32_t ctrl, uint32_t *val)
894 {
895 struct cdc_acm_dev_data_t * const dev_data = dev->data;
896
897 switch (ctrl) {
898 case UART_LINE_CTRL_BAUD_RATE:
899 *val = sys_le32_to_cpu(dev_data->line_coding.dwDTERate);
900 return 0;
901 case UART_LINE_CTRL_RTS:
902 *val = (dev_data->line_state &
903 SET_CONTROL_LINE_STATE_RTS) ? 1 : 0;
904 return 0;
905 case UART_LINE_CTRL_DTR:
906 *val = (dev_data->line_state &
907 SET_CONTROL_LINE_STATE_DTR) ? 1 : 0;
908 return 0;
909 }
910
911 return -ENOTSUP;
912 }
913
914 #endif /* CONFIG_UART_LINE_CTRL */
915
916 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
917
cdc_acm_configure(const struct device * dev,const struct uart_config * cfg)918 static int cdc_acm_configure(const struct device *dev,
919 const struct uart_config *cfg)
920 {
921 struct cdc_acm_dev_data_t * const dev_data = dev->data;
922
923 switch (cfg->flow_ctrl) {
924 case UART_CFG_FLOW_CTRL_NONE:
925 dev_data->flow_ctrl = false;
926 break;
927 case UART_CFG_FLOW_CTRL_RTS_CTS:
928 dev_data->flow_ctrl = true;
929 break;
930 default:
931 return -ENOTSUP;
932 }
933
934 return 0;
935 }
936
cdc_acm_config_get(const struct device * dev,struct uart_config * cfg)937 static int cdc_acm_config_get(const struct device *dev,
938 struct uart_config *cfg)
939 {
940 struct cdc_acm_dev_data_t * const dev_data = dev->data;
941
942 cfg->baudrate = sys_le32_to_cpu(dev_data->line_coding.dwDTERate);
943
944 switch (dev_data->line_coding.bCharFormat) {
945 case USB_CDC_LINE_CODING_STOP_BITS_1:
946 cfg->stop_bits = UART_CFG_STOP_BITS_1;
947 break;
948 case USB_CDC_LINE_CODING_STOP_BITS_1_5:
949 cfg->stop_bits = UART_CFG_STOP_BITS_1_5;
950 break;
951 case USB_CDC_LINE_CODING_STOP_BITS_2:
952 default:
953 cfg->stop_bits = UART_CFG_STOP_BITS_2;
954 break;
955 };
956
957 switch (dev_data->line_coding.bParityType) {
958 case USB_CDC_LINE_CODING_PARITY_NO:
959 default:
960 cfg->parity = UART_CFG_PARITY_NONE;
961 break;
962 case USB_CDC_LINE_CODING_PARITY_ODD:
963 cfg->parity = UART_CFG_PARITY_ODD;
964 break;
965 case USB_CDC_LINE_CODING_PARITY_EVEN:
966 cfg->parity = UART_CFG_PARITY_EVEN;
967 break;
968 case USB_CDC_LINE_CODING_PARITY_MARK:
969 cfg->parity = UART_CFG_PARITY_MARK;
970 break;
971 case USB_CDC_LINE_CODING_PARITY_SPACE:
972 cfg->parity = UART_CFG_PARITY_SPACE;
973 break;
974 };
975
976 switch (dev_data->line_coding.bDataBits) {
977 case USB_CDC_LINE_CODING_DATA_BITS_5:
978 cfg->data_bits = UART_CFG_DATA_BITS_5;
979 break;
980 case USB_CDC_LINE_CODING_DATA_BITS_6:
981 cfg->data_bits = UART_CFG_DATA_BITS_6;
982 break;
983 case USB_CDC_LINE_CODING_DATA_BITS_7:
984 cfg->data_bits = UART_CFG_DATA_BITS_7;
985 break;
986 case USB_CDC_LINE_CODING_DATA_BITS_8:
987 default:
988 cfg->data_bits = UART_CFG_DATA_BITS_8;
989 break;
990 };
991
992 cfg->flow_ctrl = dev_data->flow_ctrl ? UART_CFG_FLOW_CTRL_RTS_CTS :
993 UART_CFG_FLOW_CTRL_NONE;
994
995 return 0;
996 }
997
998 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
999
1000
1001 /*
1002 * @brief Poll the device for input.
1003 */
cdc_acm_poll_in(const struct device * dev,unsigned char * c)1004 static int cdc_acm_poll_in(const struct device *dev, unsigned char *c)
1005 {
1006 int ret = cdc_acm_fifo_read(dev, c, 1);
1007
1008 return ret == 1 ? 0 : -1;
1009 }
1010
1011 /*
1012 * @brief Output a character in polled mode.
1013 *
1014 * According to the UART API, the implementation of this routine should block
1015 * if the transmitter is full. But blocking when the USB subsystem is not ready
1016 * is considered highly undesirable behavior. Blocking may also be undesirable
1017 * when CDC ACM UART is used as a logging backend.
1018 *
1019 * The behavior of CDC ACM poll out is:
1020 * - Block if the TX ring buffer is full, hw_flow_control property is enabled,
1021 * and called from a non-ISR context.
1022 * - Do not block if the USB subsystem is not ready, poll out implementation
1023 * is called from an ISR context, or hw_flow_control property is disabled.
1024 *
1025 */
cdc_acm_poll_out(const struct device * dev,unsigned char c)1026 static void cdc_acm_poll_out(const struct device *dev, unsigned char c)
1027 {
1028 struct cdc_acm_dev_data_t * const dev_data = dev->data;
1029 unsigned int lock;
1030 uint32_t wrote;
1031
1032 dev_data->tx_ready = false;
1033
1034 while (true) {
1035 lock = irq_lock();
1036 wrote = ring_buf_put(dev_data->tx_ringbuf, &c, 1);
1037 irq_unlock(lock);
1038 if (wrote == 1) {
1039 break;
1040 }
1041 if (k_is_in_isr() || !dev_data->flow_ctrl) {
1042 LOG_WRN_ONCE("Ring buffer full, discard data");
1043 break;
1044 }
1045
1046 k_msleep(1);
1047 }
1048
1049 /* Schedule with minimal timeout to make it possible to send more than
1050 * one byte per USB transfer. The latency increase is negligible while
1051 * the increased throughput and reduced CPU usage is easily observable.
1052 */
1053 k_work_schedule_for_queue(&USB_WORK_Q, &dev_data->tx_work, K_MSEC(1));
1054 }
1055
1056 static DEVICE_API(uart, cdc_acm_driver_api) = {
1057 .poll_in = cdc_acm_poll_in,
1058 .poll_out = cdc_acm_poll_out,
1059 .fifo_fill = cdc_acm_fifo_fill,
1060 .fifo_read = cdc_acm_fifo_read,
1061 .irq_tx_enable = cdc_acm_irq_tx_enable,
1062 .irq_tx_disable = cdc_acm_irq_tx_disable,
1063 .irq_tx_ready = cdc_acm_irq_tx_ready,
1064 .irq_rx_enable = cdc_acm_irq_rx_enable,
1065 .irq_rx_disable = cdc_acm_irq_rx_disable,
1066 .irq_rx_ready = cdc_acm_irq_rx_ready,
1067 .irq_is_pending = cdc_acm_irq_is_pending,
1068 .irq_update = cdc_acm_irq_update,
1069 .irq_callback_set = cdc_acm_irq_callback_set,
1070 #ifdef CONFIG_UART_LINE_CTRL
1071 .line_ctrl_set = cdc_acm_line_ctrl_set,
1072 .line_ctrl_get = cdc_acm_line_ctrl_get,
1073 #endif /* CONFIG_UART_LINE_CTRL */
1074 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
1075 .configure = cdc_acm_configure,
1076 .config_get = cdc_acm_config_get,
1077 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
1078 };
1079
1080 #define INITIALIZER_IAD \
1081 .iad_cdc = { \
1082 .bLength = sizeof(struct usb_association_descriptor), \
1083 .bDescriptorType = USB_DESC_INTERFACE_ASSOC, \
1084 .bFirstInterface = 0, \
1085 .bInterfaceCount = 0x02, \
1086 .bFunctionClass = USB_BCC_CDC_CONTROL, \
1087 .bFunctionSubClass = ACM_SUBCLASS, \
1088 .bFunctionProtocol = 0, \
1089 .iFunction = 0, \
1090 },
1091
1092 #define INITIALIZER_IF(iface_num, num_ep, class, subclass) \
1093 { \
1094 .bLength = sizeof(struct usb_if_descriptor), \
1095 .bDescriptorType = USB_DESC_INTERFACE, \
1096 .bInterfaceNumber = iface_num, \
1097 .bAlternateSetting = 0, \
1098 .bNumEndpoints = num_ep, \
1099 .bInterfaceClass = class, \
1100 .bInterfaceSubClass = subclass, \
1101 .bInterfaceProtocol = 0, \
1102 .iInterface = 0, \
1103 }
1104
1105 #define INITIALIZER_IF_HDR \
1106 { \
1107 .bFunctionLength = sizeof(struct cdc_header_descriptor),\
1108 .bDescriptorType = USB_DESC_CS_INTERFACE, \
1109 .bDescriptorSubtype = HEADER_FUNC_DESC, \
1110 .bcdCDC = sys_cpu_to_le16(USB_SRN_1_1), \
1111 }
1112
1113 #define INITIALIZER_IF_CM \
1114 { \
1115 .bFunctionLength = sizeof(struct cdc_cm_descriptor), \
1116 .bDescriptorType = USB_DESC_CS_INTERFACE, \
1117 .bDescriptorSubtype = CALL_MANAGEMENT_FUNC_DESC, \
1118 .bmCapabilities = 0x02, \
1119 .bDataInterface = 1, \
1120 }
1121
1122 #define INITIALIZER_IF_ACM \
1123 { \
1124 .bFunctionLength = sizeof(struct cdc_acm_descriptor), \
1125 .bDescriptorType = USB_DESC_CS_INTERFACE, \
1126 .bDescriptorSubtype = ACM_FUNC_DESC, \
1127 .bmCapabilities = 0x02, \
1128 }
1129
1130 #define INITIALIZER_IF_UNION \
1131 { \
1132 .bFunctionLength = sizeof(struct cdc_union_descriptor), \
1133 .bDescriptorType = USB_DESC_CS_INTERFACE, \
1134 .bDescriptorSubtype = UNION_FUNC_DESC, \
1135 .bControlInterface = 0, \
1136 .bSubordinateInterface0 = 1, \
1137 }
1138
1139 #define INITIALIZER_IF_EP(addr, attr, mps, interval) \
1140 { \
1141 .bLength = sizeof(struct usb_ep_descriptor), \
1142 .bDescriptorType = USB_DESC_ENDPOINT, \
1143 .bEndpointAddress = addr, \
1144 .bmAttributes = attr, \
1145 .wMaxPacketSize = sys_cpu_to_le16(mps), \
1146 .bInterval = interval, \
1147 }
1148
1149 #define CDC_ACM_CFG_AND_DATA_DEFINE(x) \
1150 USBD_CLASS_DESCR_DEFINE(primary, x) \
1151 struct usb_cdc_acm_config cdc_acm_cfg_##x = { \
1152 INITIALIZER_IAD \
1153 .if0 = INITIALIZER_IF(0, 1, \
1154 USB_BCC_CDC_CONTROL, \
1155 ACM_SUBCLASS), \
1156 .if0_header = INITIALIZER_IF_HDR, \
1157 .if0_cm = INITIALIZER_IF_CM, \
1158 .if0_acm = INITIALIZER_IF_ACM, \
1159 .if0_union = INITIALIZER_IF_UNION, \
1160 .if0_int_ep = INITIALIZER_IF_EP(AUTO_EP_IN, \
1161 USB_DC_EP_INTERRUPT, \
1162 CONFIG_CDC_ACM_INTERRUPT_EP_MPS, \
1163 0x0A), \
1164 .if1 = INITIALIZER_IF(1, 2, \
1165 USB_BCC_CDC_DATA, \
1166 0), \
1167 .if1_in_ep = INITIALIZER_IF_EP(AUTO_EP_IN, \
1168 USB_DC_EP_BULK, \
1169 CONFIG_CDC_ACM_BULK_EP_MPS, \
1170 0x00), \
1171 .if1_out_ep = INITIALIZER_IF_EP(AUTO_EP_OUT, \
1172 USB_DC_EP_BULK, \
1173 CONFIG_CDC_ACM_BULK_EP_MPS, \
1174 0x00), \
1175 }; \
1176 \
1177 static struct usb_ep_cfg_data cdc_acm_ep_data_##x[] = { \
1178 { \
1179 .ep_cb = cdc_acm_int_in, \
1180 .ep_addr = AUTO_EP_IN, \
1181 }, \
1182 { \
1183 .ep_cb = usb_transfer_ep_callback, \
1184 .ep_addr = AUTO_EP_OUT, \
1185 }, \
1186 { \
1187 .ep_cb = usb_transfer_ep_callback, \
1188 .ep_addr = AUTO_EP_IN, \
1189 }, \
1190 }; \
1191 \
1192 USBD_DEFINE_CFG_DATA(cdc_acm_config_##x) = { \
1193 .usb_device_description = NULL, \
1194 .interface_config = cdc_interface_config, \
1195 .interface_descriptor = &cdc_acm_cfg_##x.if0, \
1196 .cb_usb_status = cdc_acm_dev_status_cb, \
1197 .interface = { \
1198 .class_handler = cdc_acm_class_handle_req, \
1199 .custom_handler = NULL, \
1200 }, \
1201 .num_endpoints = ARRAY_SIZE(cdc_acm_ep_data_##x), \
1202 .endpoint = cdc_acm_ep_data_##x, \
1203 }; \
1204 \
1205 RING_BUF_DECLARE(cdc_acm_rx_rb_##x, \
1206 CONFIG_USB_CDC_ACM_RINGBUF_SIZE); \
1207 RING_BUF_DECLARE(cdc_acm_tx_rb_##x, \
1208 CONFIG_USB_CDC_ACM_RINGBUF_SIZE); \
1209 static struct cdc_acm_dev_data_t cdc_acm_dev_data_##x = { \
1210 .line_coding = CDC_ACM_DEFAULT_BAUDRATE, \
1211 .rx_ringbuf = &cdc_acm_rx_rb_##x, \
1212 .tx_ringbuf = &cdc_acm_tx_rb_##x, \
1213 .flow_ctrl = DT_INST_PROP(x, hw_flow_control), \
1214 };
1215
1216 #define DT_DRV_COMPAT zephyr_cdc_acm_uart
1217
1218 #define CDC_ACM_DT_DEVICE_DEFINE(idx) \
1219 BUILD_ASSERT(DT_INST_ON_BUS(idx, usb), \
1220 "node " DT_NODE_PATH(DT_DRV_INST(idx)) \
1221 " is not assigned to a USB device controller"); \
1222 CDC_ACM_CFG_AND_DATA_DEFINE(idx) \
1223 \
1224 DEVICE_DT_INST_DEFINE(idx, cdc_acm_init, NULL, \
1225 &cdc_acm_dev_data_##idx, &cdc_acm_config_##idx, \
1226 PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
1227 &cdc_acm_driver_api);
1228
1229 DT_INST_FOREACH_STATUS_OKAY(CDC_ACM_DT_DEVICE_DEFINE);
1230