cdc_acm.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. /*******************************************************************************
  2. *
  3. * Copyright(c) 2015,2016 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. * @file
  34. * @brief CDC ACM device class driver
  35. *
  36. * Driver for USB CDC ACM device class driver
  37. */
  38. #include <kernel.h>
  39. #include <init.h>
  40. #include <drivers/uart.h>
  41. #include <string.h>
  42. #include <sys/byteorder.h>
  43. #include <usb/class/usb_cdc.h>
  44. #include <usb/usb_device.h>
  45. #include <usb/usb_common.h>
  46. #ifdef CONFIG_NVRAM_CONFIG
  47. #include <drivers/nvram_config.h>
  48. #endif
  49. #include "cdc_acm_descriptor.h"
  50. #ifndef CONFIG_UART_INTERRUPT_DRIVEN
  51. #error "CONFIG_UART_INTERRUPT_DRIVEN must be set for CDC ACM driver"
  52. #endif
  53. /* fixing compiler warning */
  54. #ifdef DEV_DATA
  55. #undef DEV_DATA
  56. #endif
  57. #undef __DEPRECATED_MACRO
  58. #define __DEPRECATED_MACRO
  59. #define LOG_LEVEL CONFIG_SYS_LOG_USB_CDC_ACM_LEVEL
  60. #include <logging/log.h>
  61. LOG_MODULE_REGISTER(cdc_acm);
  62. #define DEV_DATA(dev) \
  63. ((struct cdc_acm_dev_data_t * const)(dev)->data)
  64. /* 115200bps, no parity, 1 stop bit, 8bit char */
  65. #define CDC_ACM_DEFAUL_BAUDRATE {sys_cpu_to_le32(115200), 0, 0, 8}
  66. /* Size of the internal buffer used for storing received data */
  67. #define CDC_ACM_BUFFER_SIZE (2 * HS_BULK_EP_MPS)
  68. /* Max CDC ACM class request max data size */
  69. #define CDC_CLASS_REQ_MAX_DATA_SIZE 8
  70. /* Serial state notification timeout */
  71. #define CDC_CONTROL_SERIAL_STATE_TIMEOUT_US 100000
  72. #define ACM_INT_EP_IDX 0
  73. #define ACM_OUT_EP_IDX 1
  74. #define ACM_IN_EP_IDX 2
  75. #define ACM_IF0_STRING "ACM-CDC"
  76. const struct device *cdc_acm_dev;
  77. static struct k_sem poll_wait_sem;
  78. /* Device data structure */
  79. struct cdc_acm_dev_data_t {
  80. /* USB device status code */
  81. enum usb_dc_status_code usb_status;
  82. /* Callback function pointer */
  83. uart_irq_callback_user_data_t cb;
  84. void *cb_data;
  85. /* Tx ready status. Signals when */
  86. u8_t tx_ready;
  87. u8_t rx_ready; /* Rx ready status */
  88. u8_t tx_irq_ena; /* Tx interrupt enable status */
  89. u8_t rx_irq_ena; /* Rx interrupt enable status */
  90. u8_t rx_buf[CDC_ACM_BUFFER_SIZE];/* Internal Rx buffer */
  91. u32_t rx_buf_head; /* Head of the internal Rx buffer */
  92. u32_t rx_buf_tail; /* Tail of the internal Rx buffer */
  93. /* Interface data buffer */
  94. u8_t interface_data[CDC_CLASS_REQ_MAX_DATA_SIZE];
  95. /* CDC ACM line coding properties. LE order */
  96. struct cdc_acm_line_coding line_coding;
  97. /* CDC ACM line state bitmap, DTE side */
  98. u8_t line_state;
  99. /* CDC ACM serial state bitmap, DCE side */
  100. u8_t serial_state;
  101. /* CDC ACM notification sent status */
  102. u8_t notification_sent;
  103. };
  104. /**
  105. * @brief Handler called for Class requests not handled by the USB stack.
  106. *
  107. * @param pSetup Information about the request to execute.
  108. * @param len Size of the buffer.
  109. * @param data Buffer containing the request result.
  110. *
  111. * @return 0 on success, negative errno code on fail.
  112. */
  113. static int cdc_acm_class_handle_req(struct usb_setup_packet *pSetup,
  114. s32_t *len, u8_t **data)
  115. {
  116. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(cdc_acm_dev);
  117. switch (pSetup->bRequest) {
  118. case SET_LINE_CODING:
  119. memcpy(&dev_data->line_coding,
  120. *data, sizeof(dev_data->line_coding));
  121. LOG_DBG("CDC_SET_LINE_CODING %d %d %d %d",
  122. sys_le32_to_cpu(dev_data->line_coding.dwDTERate),
  123. dev_data->line_coding.bCharFormat,
  124. dev_data->line_coding.bParityType,
  125. dev_data->line_coding.bDataBits);
  126. break;
  127. case SET_CONTROL_LINE_STATE:
  128. dev_data->line_state = (u8_t)sys_le16_to_cpu(pSetup->wValue);
  129. LOG_DBG("CDC_SET_CONTROL_LINE_STATE 0x%x",
  130. dev_data->line_state);
  131. break;
  132. case GET_LINE_CODING:
  133. *data = (u8_t *)(&dev_data->line_coding);
  134. *len = sizeof(dev_data->line_coding);
  135. LOG_DBG("CDC_GET_LINE_CODING %d %d %d %d",
  136. sys_le32_to_cpu(dev_data->line_coding.dwDTERate),
  137. dev_data->line_coding.bCharFormat,
  138. dev_data->line_coding.bParityType,
  139. dev_data->line_coding.bDataBits);
  140. break;
  141. default:
  142. LOG_DBG("CDC ACM request 0x%x, value 0x%x",
  143. pSetup->bRequest, pSetup->wValue);
  144. return -EINVAL;
  145. }
  146. return 0;
  147. }
  148. /**
  149. * @brief EP Bulk IN handler, used to send data to the Host
  150. *
  151. * @param ep Endpoint address.
  152. * @param ep_status Endpoint status code.
  153. *
  154. * @return N/A.
  155. */
  156. static void cdc_acm_bulk_in(u8_t ep, enum usb_dc_ep_cb_status_code ep_status)
  157. {
  158. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(cdc_acm_dev);
  159. ARG_UNUSED(ep_status);
  160. ARG_UNUSED(ep);
  161. dev_data->tx_ready = 1;
  162. k_sem_give(&poll_wait_sem);
  163. /* Call callback only if tx irq ena */
  164. if (dev_data->cb && dev_data->tx_irq_ena) {
  165. dev_data->cb(cdc_acm_dev, dev_data->cb_data);
  166. }
  167. }
  168. /**
  169. * @brief EP Bulk OUT handler, used to read the data received from the Host
  170. *
  171. * @param ep Endpoint address.
  172. * @param ep_status Endpoint status code.
  173. *
  174. * @return N/A.
  175. */
  176. static void cdc_acm_bulk_out(u8_t ep,
  177. enum usb_dc_ep_cb_status_code ep_status)
  178. {
  179. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(cdc_acm_dev);
  180. u32_t actual;
  181. u32_t buf_head;
  182. ARG_UNUSED(ep_status);
  183. usb_read_actual(ep, &actual);
  184. buf_head = dev_data->rx_buf_head;
  185. if (((buf_head + actual) % CDC_ACM_BUFFER_SIZE) ==
  186. dev_data->rx_buf_tail) {
  187. /* FIFO full, discard data */
  188. LOG_ERR("CDC buffer full!");
  189. } else {
  190. buf_head = (buf_head + actual) % CDC_ACM_BUFFER_SIZE;
  191. }
  192. dev_data->rx_buf_head = buf_head;
  193. dev_data->rx_ready = 1;
  194. /* Call callback only if rx irq ena */
  195. if (dev_data->cb && dev_data->rx_irq_ena) {
  196. dev_data->cb(cdc_acm_dev, dev_data->cb_data);
  197. }
  198. }
  199. /**
  200. * @brief EP Interrupt handler
  201. *
  202. * @param ep Endpoint address.
  203. * @param ep_status Endpoint status code.
  204. *
  205. * @return N/A.
  206. */
  207. static void cdc_acm_int_in(u8_t ep, enum usb_dc_ep_cb_status_code ep_status)
  208. {
  209. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(cdc_acm_dev);
  210. ARG_UNUSED(ep_status);
  211. dev_data->notification_sent = 1;
  212. }
  213. /**
  214. * @brief Callback used to know the USB connection status
  215. *
  216. * @param status USB device status code.
  217. *
  218. * @return N/A.
  219. */
  220. static void cdc_acm_dev_status_cb(enum usb_dc_status_code status, u8_t *param)
  221. {
  222. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(cdc_acm_dev);
  223. ARG_UNUSED(param);
  224. /* Store the new status */
  225. dev_data->usb_status = status;
  226. /* Check the USB status and do needed action if required */
  227. switch (status) {
  228. case USB_DC_ERROR:
  229. LOG_DBG("USB device error");
  230. break;
  231. case USB_DC_RESET:
  232. LOG_DBG("USB device reset detected");
  233. break;
  234. case USB_DC_CONNECTED:
  235. LOG_DBG("USB device connected");
  236. break;
  237. case USB_DC_CONFIGURED:
  238. LOG_DBG("USB device configured");
  239. usb_read_async(CONFIG_CDC_ACM_BULK_OUT_EP_ADDR, dev_data->rx_buf, HS_BULK_EP_MPS, NULL);
  240. break;
  241. case USB_DC_DISCONNECTED:
  242. LOG_DBG("USB device disconnected");
  243. break;
  244. case USB_DC_SUSPEND:
  245. LOG_DBG("USB device suspended");
  246. break;
  247. case USB_DC_RESUME:
  248. LOG_DBG("USB device resumed");
  249. break;
  250. case USB_DC_HIGHSPEED:
  251. LOG_DBG("USB high-speed inter");
  252. break;
  253. case USB_DC_UNKNOWN:
  254. default:
  255. LOG_DBG("USB unknown state");
  256. break;
  257. }
  258. }
  259. /* Describe EndPoints configuration */
  260. static const struct usb_ep_cfg_data cdc_acm_ep_data[] = {
  261. {
  262. .ep_cb = cdc_acm_int_in,
  263. .ep_addr = CONFIG_CDC_ACM_INTERRUPT_EP_ADDR
  264. },
  265. {
  266. .ep_cb = cdc_acm_bulk_out,
  267. .ep_addr = CONFIG_CDC_ACM_BULK_OUT_EP_ADDR
  268. },
  269. {
  270. .ep_cb = cdc_acm_bulk_in,
  271. .ep_addr = CONFIG_CDC_ACM_BULK_IN_EP_ADDR
  272. }
  273. };
  274. static const struct usb_cfg_data cdc_acm_config = {
  275. .usb_device_description = NULL,
  276. .cb_usb_status = cdc_acm_dev_status_cb,
  277. .interface = {
  278. .class_handler = cdc_acm_class_handle_req,
  279. .custom_handler = NULL,
  280. .vendor_handler = NULL,
  281. },
  282. .num_endpoints = ARRAY_SIZE(cdc_acm_ep_data),
  283. .endpoint = cdc_acm_ep_data
  284. };
  285. /**
  286. * @brief Set the baud rate
  287. *
  288. * This routine set the given baud rate for the UART.
  289. *
  290. * @param dev CDC ACM device struct.
  291. * @param baudrate Baud rate.
  292. *
  293. * @return N/A.
  294. */
  295. static void cdc_acm_baudrate_set(const struct device *dev, u32_t baudrate)
  296. {
  297. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  298. dev_data->line_coding.dwDTERate = sys_cpu_to_le32(baudrate);
  299. }
  300. static int usb_cdc_acm_fix_dev_sn(void)
  301. {
  302. int ret;
  303. #ifdef CONFIG_NVRAM_CONFIG
  304. int read_len;
  305. u8_t mac_str[CONFIG_USB_DEVICE_STRING_DESC_MAX_LEN];
  306. read_len = nvram_config_get(CONFIG_USB_CDC_ACM_SN_NVRAM, mac_str, CONFIG_USB_DEVICE_STRING_DESC_MAX_LEN);
  307. if (read_len < 0) {
  308. LOG_DBG("no sn data in nvram: %d", read_len);
  309. ret = usb_device_register_string_descriptor(DEV_SN_DESC, CONFIG_USB_CDC_ACM_SN, strlen(CONFIG_USB_CDC_ACM_SN));
  310. if (ret)
  311. return ret;
  312. } else {
  313. ret = usb_device_register_string_descriptor(DEV_SN_DESC, mac_str, read_len);
  314. if (ret)
  315. return ret;
  316. }
  317. #else
  318. ret = usb_device_register_string_descriptor(DEV_SN_DESC, CONFIG_USB_CDC_ACM_SN, strlen(CONFIG_USB_CDC_ACM_SN));
  319. if (ret)
  320. return ret;
  321. #endif
  322. return 0;
  323. }
  324. /**
  325. * @brief Initialize UART channel
  326. *
  327. * This routine is called to reset the chip in a quiescent state.
  328. * It is assumed that this function is called only once per UART.
  329. *
  330. * @param dev CDC ACM device struct.
  331. *
  332. * @return 0 always.
  333. */
  334. static int cdc_acm_init(const struct device *dev)
  335. {
  336. cdc_acm_dev = dev;
  337. int ret;
  338. /* Register string descriptor */
  339. ret = usb_device_register_string_descriptor(MANUFACTURE_STR_DESC, CONFIG_USB_CDC_ACM_MANUFACTURER, strlen(CONFIG_USB_CDC_ACM_MANUFACTURER));
  340. if (ret) {
  341. return ret;
  342. }
  343. ret = usb_device_register_string_descriptor(PRODUCT_STR_DESC, CONFIG_USB_CDC_ACM_PRODUCT, strlen(CONFIG_USB_CDC_ACM_PRODUCT));
  344. if (ret) {
  345. return ret;
  346. }
  347. ret = usb_cdc_acm_fix_dev_sn();
  348. if (ret) {
  349. return ret;
  350. }
  351. /* Register device descriptor */
  352. usb_device_register_descriptors(cdc_acm_usb_fs_descriptor, cdc_acm_usb_hs_descriptor);
  353. /* Initialize the USB driver with the right configuration */
  354. ret = usb_set_config(&cdc_acm_config);
  355. if (ret < 0) {
  356. LOG_ERR("Failed to config USB");
  357. return ret;
  358. }
  359. /* Enable USB driver */
  360. ret = usb_enable(&cdc_acm_config);
  361. if (ret < 0) {
  362. LOG_ERR("Failed to enable USB");
  363. return ret;
  364. }
  365. k_sem_init(&poll_wait_sem, 0, UINT_MAX);
  366. return 0;
  367. }
  368. /**
  369. * @brief Fill FIFO with data
  370. *
  371. * @param dev CDC ACM device struct.
  372. * @param tx_data Data to transmit.
  373. * @param len Number of bytes to send.
  374. *
  375. * @return Number of bytes sent.
  376. */
  377. static int cdc_acm_fifo_fill(const struct device *dev,
  378. const u8_t *tx_data, int len)
  379. {
  380. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  381. static u8_t cdc_acm_recursive;
  382. u32_t wrote = 0;
  383. int err;
  384. if (dev_data->usb_status != USB_DC_CONFIGURED) {
  385. return -ENODEV;
  386. }
  387. if (cdc_acm_recursive) {
  388. return -EIO;
  389. }
  390. dev_data->tx_ready = 0;
  391. /* FIXME: On Quark SE Family processor, restrict writing more than
  392. * 4 bytes into TX USB Endpoint. When more than 4 bytes are written,
  393. * sometimes (freq ~1/3000) first 4 bytes are repeated.
  394. * (example: abcdef prints as abcdabcdef) (refer Jira GH-3515).
  395. * Application should handle partial data transfer while writing
  396. * into USB TX Endpoint.
  397. */
  398. #ifdef CONFIG_SOC_SERIES_QUARK_SE
  399. len = len > sizeof(u32_t) ? sizeof(u32_t) : len;
  400. #endif
  401. cdc_acm_recursive = 1;
  402. err = usb_write(cdc_acm_ep_data[ACM_IN_EP_IDX].ep_addr,
  403. tx_data, len, &wrote);
  404. if (err != 0) {
  405. cdc_acm_recursive = 0;
  406. return err;
  407. }
  408. cdc_acm_recursive = 0;
  409. return wrote;
  410. }
  411. /**
  412. * @brief Read data from FIFO
  413. *
  414. * @param dev CDC ACM device struct.
  415. * @param rx_data Pointer to data container.
  416. * @param size Container size.
  417. *
  418. * @return Number of bytes read.
  419. */
  420. static int cdc_acm_fifo_read(const struct device *dev, u8_t *rx_data,
  421. const int size)
  422. {
  423. u32_t avail_data, bytes_read, i;
  424. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  425. u8_t read = 0;
  426. avail_data = (CDC_ACM_BUFFER_SIZE + dev_data->rx_buf_head -
  427. dev_data->rx_buf_tail) % CDC_ACM_BUFFER_SIZE;
  428. if (avail_data > size) {
  429. bytes_read = size;
  430. } else {
  431. bytes_read = avail_data;
  432. read = 1;
  433. }
  434. for (i = 0; i < bytes_read; i++) {
  435. rx_data[i] = dev_data->rx_buf[(dev_data->rx_buf_tail + i) %
  436. CDC_ACM_BUFFER_SIZE];
  437. }
  438. dev_data->rx_buf_tail = (dev_data->rx_buf_tail + bytes_read) %
  439. CDC_ACM_BUFFER_SIZE;
  440. if (dev_data->rx_buf_tail == dev_data->rx_buf_head) {
  441. /* Buffer empty */
  442. dev_data->rx_ready = 0;
  443. }
  444. if (dev_data->usb_status != USB_DC_CONFIGURED) {
  445. read = 0;
  446. }
  447. if (read == 1) {
  448. dev_data->rx_buf_tail = 0;
  449. dev_data->rx_buf_head = 0;
  450. usb_read_async(CONFIG_CDC_ACM_BULK_OUT_EP_ADDR,
  451. dev_data->rx_buf,
  452. HS_BULK_EP_MPS, NULL);
  453. }
  454. return bytes_read;
  455. }
  456. /**
  457. * @brief Enable TX interrupt
  458. *
  459. * @param dev CDC ACM device struct.
  460. *
  461. * @return N/A.
  462. */
  463. static void cdc_acm_irq_tx_enable(const struct device *dev)
  464. {
  465. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  466. dev_data->tx_irq_ena = 1;
  467. }
  468. /**
  469. * @brief Disable TX interrupt
  470. *
  471. * @param dev CDC ACM device struct.
  472. *
  473. * @return N/A.
  474. */
  475. static void cdc_acm_irq_tx_disable(const struct device *dev)
  476. {
  477. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  478. dev_data->tx_irq_ena = 0;
  479. }
  480. /**
  481. * @brief Check if Tx IRQ has been raised
  482. *
  483. * @param dev CDC ACM device struct.
  484. *
  485. * @return 1 if a Tx IRQ is pending, 0 otherwise.
  486. */
  487. static int cdc_acm_irq_tx_ready(const struct device *dev)
  488. {
  489. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  490. if (dev_data->tx_ready) {
  491. dev_data->tx_ready = 0;
  492. return 1;
  493. }
  494. return 0;
  495. }
  496. /**
  497. * @brief Enable RX interrupt
  498. *
  499. * @param dev CDC ACM device struct.
  500. *
  501. * @return N/A
  502. */
  503. static void cdc_acm_irq_rx_enable(const struct device *dev)
  504. {
  505. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  506. dev_data->rx_irq_ena = 1;
  507. }
  508. /**
  509. * @brief Disable RX interrupt
  510. *
  511. * @param dev CDC ACM device struct.
  512. *
  513. * @return N/A.
  514. */
  515. static void cdc_acm_irq_rx_disable(const struct device *dev)
  516. {
  517. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  518. dev_data->rx_irq_ena = 0;
  519. }
  520. /**
  521. * @brief Check if Rx IRQ has been raised
  522. *
  523. * @param dev CDC ACM device struct.
  524. *
  525. * @return 1 if an IRQ is ready, 0 otherwise.
  526. */
  527. static int cdc_acm_irq_rx_ready(const struct device *dev)
  528. {
  529. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  530. if (dev_data->rx_ready) {
  531. dev_data->rx_ready = 0;
  532. return 1;
  533. }
  534. return 0;
  535. }
  536. /**
  537. * @brief Check if Tx or Rx IRQ is pending
  538. *
  539. * @param dev CDC ACM device struct.
  540. *
  541. * @return 1 if a Tx or Rx IRQ is pending, 0 otherwise.
  542. */
  543. static int cdc_acm_irq_is_pending(const struct device *dev)
  544. {
  545. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  546. if (dev_data->tx_ready && dev_data->tx_irq_ena) {
  547. return 1;
  548. } else if (dev_data->rx_ready && dev_data->rx_irq_ena) {
  549. return 1;
  550. } else {
  551. return 0;
  552. }
  553. }
  554. /**
  555. * @brief Update IRQ status
  556. *
  557. * @param dev CDC ACM device struct.
  558. *
  559. * @return Always 1
  560. */
  561. static int cdc_acm_irq_update(const struct device *dev)
  562. {
  563. ARG_UNUSED(dev);
  564. return 1;
  565. }
  566. /**
  567. * @brief Set the callback function pointer for IRQ.
  568. *
  569. * @param dev CDC ACM device struct.
  570. * @param cb Callback function pointer.
  571. *
  572. * @return N/A
  573. */
  574. static void cdc_acm_irq_callback_set(const struct device *dev,
  575. uart_irq_callback_user_data_t cb, void *user_data)
  576. {
  577. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  578. dev_data->cb = cb;
  579. dev_data->cb_data = user_data;
  580. }
  581. #ifdef CONFIG_UART_LINE_CTRL
  582. /**
  583. * @brief Send serial line state notification to the Host
  584. *
  585. * This routine sends asynchronous notification of UART status
  586. * on the interrupt endpoint
  587. *
  588. * @param dev CDC ACM device struct.
  589. * @param ep_status Endpoint status code.
  590. *
  591. * @return N/A.
  592. */
  593. static int cdc_acm_send_notification(const struct device *dev, u16_t serial_state)
  594. {
  595. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  596. struct cdc_acm_notification notification;
  597. u32_t cnt = 0;
  598. notification.bmRequestType = 0xA1;
  599. notification.bNotificationType = 0x20;
  600. notification.wValue = 0;
  601. notification.wIndex = 0;
  602. notification.wLength = sys_cpu_to_le16(sizeof(serial_state));
  603. notification.data = sys_cpu_to_le16(serial_state);
  604. dev_data->notification_sent = 0;
  605. usb_write(cdc_acm_ep_data[ACM_INT_EP_IDX].ep_addr,
  606. (const u8_t *)&notification, sizeof(notification), NULL);
  607. /* Wait for notification to be sent */
  608. while (!((volatile u8_t)dev_data->notification_sent)) {
  609. k_busy_wait(1);
  610. if (++cnt > CDC_CONTROL_SERIAL_STATE_TIMEOUT_US) {
  611. LOG_DBG("CDC ACM notification timeout!");
  612. return -EIO;
  613. }
  614. }
  615. return 0;
  616. }
  617. /**
  618. * @brief Manipulate line control for UART.
  619. *
  620. * @param dev CDC ACM device struct
  621. * @param ctrl The line control to be manipulated
  622. * @param val Value to set the line control
  623. *
  624. * @return 0 if successful, failed otherwise.
  625. */
  626. static int cdc_acm_line_ctrl_set(const struct device *dev,
  627. u32_t ctrl, u32_t val)
  628. {
  629. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  630. if (dev_data->usb_status != USB_DC_CONFIGURED) {
  631. return -ENODEV;
  632. }
  633. switch (ctrl) {
  634. case UART_LINE_CTRL_BAUD_RATE:
  635. cdc_acm_baudrate_set(dev, val);
  636. return 0;
  637. case UART_LINE_CTRL_DCD:
  638. dev_data->serial_state &= ~SERIAL_STATE_RX_CARRIER;
  639. if (val) {
  640. dev_data->serial_state |= SERIAL_STATE_RX_CARRIER;
  641. }
  642. cdc_acm_send_notification(dev, SERIAL_STATE_RX_CARRIER);
  643. return 0;
  644. case UART_LINE_CTRL_DSR:
  645. dev_data->serial_state &= ~SERIAL_STATE_TX_CARRIER;
  646. if (val) {
  647. dev_data->serial_state |= SERIAL_STATE_TX_CARRIER;
  648. }
  649. cdc_acm_send_notification(dev, dev_data->serial_state);
  650. return 0;
  651. default:
  652. return -ENODEV;
  653. }
  654. return -ENOTSUP;
  655. }
  656. /**
  657. * @brief Manipulate line control for UART.
  658. *
  659. * @param dev CDC ACM device struct
  660. * @param ctrl The line control to be manipulated
  661. * @param val Value to set the line control
  662. *
  663. * @return 0 if successful, failed otherwise.
  664. */
  665. static int cdc_acm_line_ctrl_get(const struct device *dev,
  666. u32_t ctrl, u32_t *val)
  667. {
  668. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  669. switch (ctrl) {
  670. case UART_LINE_CTRL_BAUD_RATE:
  671. *val = sys_le32_to_cpu(dev_data->line_coding.dwDTERate);
  672. return 0;
  673. case UART_LINE_CTRL_RTS:
  674. *val = (dev_data->line_state &
  675. SET_CONTROL_LINE_STATE_RTS) ? 1 : 0;
  676. return 0;
  677. case UART_LINE_CTRL_DTR:
  678. *val = (dev_data->line_state &
  679. SET_CONTROL_LINE_STATE_DTR) ? 1 : 0;
  680. return 0;
  681. }
  682. return -ENOTSUP;
  683. }
  684. #endif /* CONFIG_UART_LINE_CTRL */
  685. /*
  686. * @brief Poll the device for input.
  687. *
  688. * @return -ENOTSUP Since underlying USB device controller always uses
  689. * interrupts, polled mode UART APIs are not implemented for the UART interface
  690. * exported by CDC ACM driver. Apps should use fifo_read API instead.
  691. */
  692. static int cdc_acm_poll_in(const struct device *dev, unsigned char *c)
  693. {
  694. ARG_UNUSED(dev);
  695. ARG_UNUSED(c);
  696. return -ENOTSUP;
  697. }
  698. /*
  699. * @brief Output a character in polled mode.
  700. *
  701. * The UART poll method for USB UART is simulated by waiting till
  702. * we get the next BULK In upcall from the USB device controller or 100 ms.
  703. *
  704. * @return the same character which is sent
  705. */
  706. static void cdc_acm_poll_out(const struct device *dev,
  707. unsigned char c)
  708. {
  709. cdc_acm_fifo_fill(dev, &c, 1);
  710. k_sem_take(&poll_wait_sem, K_MSEC(100));
  711. }
  712. static const struct uart_driver_api cdc_acm_driver_api = {
  713. .poll_in = cdc_acm_poll_in,
  714. .poll_out = cdc_acm_poll_out,
  715. .fifo_fill = cdc_acm_fifo_fill,
  716. .fifo_read = cdc_acm_fifo_read,
  717. .irq_tx_enable = cdc_acm_irq_tx_enable,
  718. .irq_tx_disable = cdc_acm_irq_tx_disable,
  719. .irq_tx_ready = cdc_acm_irq_tx_ready,
  720. .irq_rx_enable = cdc_acm_irq_rx_enable,
  721. .irq_rx_disable = cdc_acm_irq_rx_disable,
  722. .irq_rx_ready = cdc_acm_irq_rx_ready,
  723. .irq_is_pending = cdc_acm_irq_is_pending,
  724. .irq_update = cdc_acm_irq_update,
  725. .irq_callback_set = cdc_acm_irq_callback_set,
  726. #ifdef CONFIG_UART_LINE_CTRL
  727. .line_ctrl_set = cdc_acm_line_ctrl_set,
  728. .line_ctrl_get = cdc_acm_line_ctrl_get,
  729. #endif /* CONFIG_UART_LINE_CTRL */
  730. };
  731. static struct cdc_acm_dev_data_t cdc_acm_dev_data = {
  732. .usb_status = USB_DC_UNKNOWN,
  733. .line_coding = CDC_ACM_DEFAUL_BAUDRATE,
  734. };
  735. /*
  736. * API: initialize USB CDC ACM
  737. */
  738. int usb_cdc_acm_init(const struct device *dev)
  739. {
  740. struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev);
  741. int ret;
  742. if (cdc_acm_dev != NULL) {
  743. LOG_WRN("Already");
  744. return -EALREADY;
  745. }
  746. /* initialize states */
  747. dev_data->usb_status = USB_DC_UNKNOWN;
  748. dev_data->tx_ready = 1;
  749. dev_data->rx_ready = 0;
  750. dev_data->rx_buf_head = 0;
  751. dev_data->rx_buf_tail = 0;
  752. dev_data->line_coding.dwDTERate = 0;
  753. dev_data->line_coding.bCharFormat = 0;
  754. dev_data->line_coding.bParityType = 0;
  755. dev_data->line_coding.bDataBits = 0;
  756. dev_data->serial_state = 0;
  757. dev_data->line_state = 0;
  758. dev_data->tx_irq_ena = 0;
  759. dev_data->rx_irq_ena = 0;
  760. ret = cdc_acm_init(dev);
  761. if (ret) {
  762. cdc_acm_dev = NULL;
  763. }
  764. return ret;
  765. }
  766. /*
  767. * API: deinitialize USB CDC ACM
  768. */
  769. int usb_cdc_acm_exit(void)
  770. {
  771. int ret;
  772. if (cdc_acm_dev == NULL) {
  773. LOG_WRN("Already");
  774. return -EALREADY;
  775. }
  776. ret = usb_disable();
  777. if (ret) {
  778. LOG_ERR("Failed to disable USB: %d", ret);
  779. return ret;
  780. }
  781. usb_deconfig();
  782. cdc_acm_dev = NULL;
  783. cdc_acm_dev_data.usb_status = USB_DC_UNKNOWN;
  784. LOG_INF("done");
  785. return 0;
  786. }
  787. static int cdc_acm_init_dummy(const struct device *dev)
  788. {
  789. ARG_UNUSED(dev);
  790. return 0;
  791. }
  792. DEVICE_DEFINE(cdc_acm, CONFIG_CDC_ACM_PORT_NAME, cdc_acm_init_dummy,
  793. NULL, &cdc_acm_dev_data, NULL,
  794. APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
  795. &cdc_acm_driver_api);