virtual_com.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  4. * Copyright 2016-2017 NXP
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted (subject to the limitations in the disclaimer below) provided
  9. * that the following conditions are met:
  10. *
  11. * o Redistributions of source code must retain the above copyright notice, this list
  12. * of conditions and the following disclaimer.
  13. *
  14. * o Redistributions in binary form must reproduce the above copyright notice, this
  15. * list of conditions and the following disclaimer in the documentation and/or
  16. * other materials provided with the distribution.
  17. *
  18. * o Neither the name of the copyright holder nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include "fsl_device_registers.h"
  35. #include "clock_config.h"
  36. #include "board.h"
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include "usb_device_config.h"
  40. #include "usb.h"
  41. #include "usb_device.h"
  42. #include "usb_device_cdc_acm.h"
  43. #include "usb_device_ch9.h"
  44. #include "usb_device_descriptor.h"
  45. #include "virtual_com.h"
  46. #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
  47. #include "fsl_sysmpu.h"
  48. #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
  49. #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
  50. #include "usb_phy.h"
  51. #endif
  52. /* Provided by users. */
  53. extern void USB_DeviceClockInit(void);
  54. extern void USB_DeviceIsrEnable(void);
  55. /*******************************************************************************
  56. * Definitions
  57. ******************************************************************************/
  58. /*******************************************************************************
  59. * Variables
  60. ******************************************************************************/
  61. /* Data structure of virtual com device */
  62. usb_cdc_vcom_struct_t s_cdcVcom;
  63. /* Line codinig of cdc device */
  64. static uint8_t s_lineCoding[LINE_CODING_SIZE] = {
  65. /* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */
  66. (LINE_CODING_DTERATE >> 0U) & 0x000000FFU,
  67. (LINE_CODING_DTERATE >> 8U) & 0x000000FFU,
  68. (LINE_CODING_DTERATE >> 16U) & 0x000000FFU,
  69. (LINE_CODING_DTERATE >> 24U) & 0x000000FFU,
  70. LINE_CODING_CHARFORMAT,
  71. LINE_CODING_PARITYTYPE,
  72. LINE_CODING_DATABITS};
  73. /* Abstract state of cdc device */
  74. static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU,
  75. (STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU};
  76. /* Country code of cdc device */
  77. static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU,
  78. (COUNTRY_SETTING >> 8U) & 0x00FFU};
  79. /* CDC ACM information */
  80. static usb_cdc_acm_info_t s_usbCdcAcmInfo = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0};
  81. /* Data buffer for receiving and sending*/
  82. static uint8_t s_currRecvBuf[DATA_BUFF_SIZE];
  83. volatile static uint32_t s_recvSize = 0;
  84. volatile static uint32_t s_sendSize = 0;
  85. volatile static uint8_t s_sendComplete = 0;
  86. volatile static uint8_t s_currRecvIndex = 0;
  87. static uint32_t s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
  88. /*******************************************************************************
  89. * Prototypes
  90. ******************************************************************************/
  91. /*******************************************************************************
  92. * Code
  93. ******************************************************************************/
  94. /*!
  95. * @brief Interrupt in pipe callback function.
  96. *
  97. * This function serves as the callback function for interrupt in pipe.
  98. *
  99. * @param handle The USB device handle.
  100. * @param message The endpoint callback message
  101. * @param callbackParam The parameter of the callback.
  102. *
  103. * @return A USB error code or kStatus_USB_Success.
  104. */
  105. usb_status_t USB_DeviceCdcAcmInterruptIn(usb_device_handle handle,
  106. usb_device_endpoint_callback_message_struct_t *message,
  107. void *callbackParam)
  108. {
  109. usb_status_t error = kStatus_USB_Error;
  110. return error;
  111. }
  112. /*!
  113. * @brief Bulk in pipe callback function.
  114. *
  115. * This function serves as the callback function for bulk in pipe.
  116. *
  117. * @param handle The USB device handle.
  118. * @param message The endpoint callback message
  119. * @param callbackParam The parameter of the callback.
  120. *
  121. * @return A USB error code or kStatus_USB_Success.
  122. */
  123. usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle,
  124. usb_device_endpoint_callback_message_struct_t *message,
  125. void *callbackParam)
  126. {
  127. usb_status_t error = kStatus_USB_Error;
  128. if ((message->length != 0) && (!(message->length % s_usbBulkMaxPacketSize)))
  129. {
  130. /* If the last packet is the size of endpoint, then send also zero-ended packet,
  131. ** meaning that we want to inform the host that we do not have any additional
  132. ** data, so it can flush the output.
  133. */
  134. USB_DeviceSendRequest(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0);
  135. }
  136. else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
  137. {
  138. if ((message->buffer != NULL) || ((message->buffer == NULL) && (message->length == 0)))
  139. {
  140. /* User: add your own code for send complete event */
  141. s_sendComplete = 1;
  142. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
  143. defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
  144. defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
  145. USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
  146. #endif
  147. }
  148. }
  149. else if ((0 == s_sendComplete) && (1 == s_cdcVcom.attach) && (0 == s_cdcVcom.startTransactions))
  150. {
  151. s_sendComplete = 1;
  152. }
  153. else
  154. {
  155. }
  156. return error;
  157. }
  158. /*!
  159. * @brief Bulk out pipe callback function.
  160. *
  161. * This function serves as the callback function for bulk out pipe.
  162. *
  163. * @param handle The USB device handle.
  164. * @param message The endpoint callback message
  165. * @param callbackParam The parameter of the callback.
  166. *
  167. * @return A USB error code or kStatus_USB_Success.
  168. */
  169. usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle,
  170. usb_device_endpoint_callback_message_struct_t *message,
  171. void *callbackParam)
  172. {
  173. usb_status_t error = kStatus_USB_Error;
  174. if (USB_UNINITIALIZED_VAL_32 == message->length)
  175. {
  176. s_recvSize = 0xFFFFFFFFU;
  177. }
  178. else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
  179. {
  180. s_recvSize = message->length;
  181. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
  182. defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
  183. defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
  184. USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK;
  185. #endif
  186. if (!s_recvSize)
  187. {
  188. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
  189. defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
  190. defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
  191. USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
  192. #endif
  193. }
  194. }
  195. else
  196. {
  197. }
  198. return error;
  199. }
  200. /*!
  201. * @brief Get the setup packet buffer.
  202. *
  203. * This function provides the buffer for setup packet.
  204. *
  205. * @param handle The USB device handle.
  206. * @param setupBuffer The pointer to the address of setup packet buffer.
  207. *
  208. * @return A USB error code or kStatus_USB_Success.
  209. */
  210. usb_status_t USB_DeviceGetSetupBuffer(usb_device_handle handle, usb_setup_struct_t **setupBuffer)
  211. {
  212. static uint32_t cdcVcomSetup[2];
  213. if (NULL == setupBuffer)
  214. {
  215. return kStatus_USB_InvalidParameter;
  216. }
  217. *setupBuffer = (usb_setup_struct_t *)&cdcVcomSetup;
  218. return kStatus_USB_Success;
  219. }
  220. /*!
  221. * @brief Get the setup packet data buffer.
  222. *
  223. * This function gets the data buffer for setup packet.
  224. *
  225. * @param handle The USB device handle.
  226. * @param setup The pointer to the setup packet.
  227. * @param length The pointer to the length of the data buffer.
  228. * @param buffer The pointer to the address of setup packet data buffer.
  229. *
  230. * @return A USB error code or kStatus_USB_Success.
  231. */
  232. usb_status_t USB_DeviceGetClassReceiveBuffer(usb_device_handle handle,
  233. usb_setup_struct_t *setup,
  234. uint32_t *length,
  235. uint8_t **buffer)
  236. {
  237. static uint8_t setupOut[8];
  238. if ((NULL == buffer) || ((*length) > sizeof(setupOut)))
  239. {
  240. return kStatus_USB_InvalidRequest;
  241. }
  242. *buffer = setupOut;
  243. return kStatus_USB_Success;
  244. }
  245. /*!
  246. * @brief Configure remote wakeup feature.
  247. *
  248. * This function configures the remote wakeup feature.
  249. *
  250. * @param handle The USB device handle.
  251. * @param enable 1: enable, 0: disable.
  252. *
  253. * @return A USB error code or kStatus_USB_Success.
  254. */
  255. usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable)
  256. {
  257. return kStatus_USB_InvalidRequest;
  258. }
  259. /*!
  260. * @brief CDC class specific callback function.
  261. *
  262. * This function handles the CDC class specific requests.
  263. *
  264. * @param handle The USB device handle.
  265. * @param setup The pointer to the setup packet.
  266. * @param length The pointer to the length of the data buffer.
  267. * @param buffer The pointer to the address of setup packet data buffer.
  268. *
  269. * @return A USB error code or kStatus_USB_Success.
  270. */
  271. usb_status_t USB_DeviceProcessClassRequest(usb_device_handle handle,
  272. usb_setup_struct_t *setup,
  273. uint32_t *length,
  274. uint8_t **buffer)
  275. {
  276. usb_status_t error = kStatus_USB_InvalidRequest;
  277. usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
  278. uint32_t len;
  279. uint16_t *uartBitmap;
  280. if (setup->wIndex != USB_CDC_VCOM_COMM_INTERFACE_INDEX)
  281. {
  282. return error;
  283. }
  284. switch (setup->bRequest)
  285. {
  286. case USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
  287. break;
  288. case USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE:
  289. break;
  290. case USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE:
  291. if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
  292. {
  293. *buffer = s_abstractState;
  294. }
  295. else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
  296. {
  297. *buffer = s_countryCode;
  298. }
  299. else
  300. {
  301. }
  302. error = kStatus_USB_Success;
  303. break;
  304. case USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE:
  305. if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
  306. {
  307. *buffer = s_abstractState;
  308. *length = COMM_FEATURE_DATA_SIZE;
  309. }
  310. else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
  311. {
  312. *buffer = s_countryCode;
  313. *length = COMM_FEATURE_DATA_SIZE;
  314. }
  315. else
  316. {
  317. }
  318. error = kStatus_USB_Success;
  319. break;
  320. case USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE:
  321. break;
  322. case USB_DEVICE_CDC_REQUEST_GET_LINE_CODING:
  323. *buffer = s_lineCoding;
  324. *length = LINE_CODING_SIZE;
  325. error = kStatus_USB_Success;
  326. break;
  327. case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING:
  328. *buffer = s_lineCoding;
  329. error = kStatus_USB_Success;
  330. break;
  331. case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE:
  332. {
  333. acmInfo->dteStatus = setup->wValue;
  334. /* activate/deactivate Tx carrier */
  335. if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
  336. {
  337. acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
  338. }
  339. else
  340. {
  341. acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
  342. }
  343. /* activate carrier and DTE */
  344. if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
  345. {
  346. acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
  347. }
  348. else
  349. {
  350. acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
  351. }
  352. /* Indicates to DCE if DTE is present or not */
  353. acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? true : false;
  354. /* Initialize the serial state buffer */
  355. acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */
  356. acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_REQUEST_SERIAL_STATE_NOTIF; /* bNotification */
  357. acmInfo->serialStateBuf[2] = 0x00; /* wValue */
  358. acmInfo->serialStateBuf[3] = 0x00;
  359. acmInfo->serialStateBuf[4] = 0x00; /* wIndex */
  360. acmInfo->serialStateBuf[5] = 0x00;
  361. acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */
  362. acmInfo->serialStateBuf[7] = 0x00;
  363. /* Notifiy to host the line state */
  364. acmInfo->serialStateBuf[4] = setup->wIndex;
  365. /* Lower byte of UART BITMAP */
  366. uartBitmap = (uint16_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2];
  367. *uartBitmap = acmInfo->uartState;
  368. len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
  369. error = USB_DeviceSendRequest(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len);
  370. /* Update status */
  371. if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION)
  372. {
  373. /* To do: CARRIER_ACTIVATED */
  374. }
  375. else
  376. {
  377. /* To do: CARRIER_DEACTIVATED */
  378. }
  379. if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE)
  380. {
  381. /* DTE_ACTIVATED */
  382. if (1 == s_cdcVcom.attach)
  383. {
  384. s_cdcVcom.startTransactions = 1;
  385. #if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
  386. defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \
  387. defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
  388. USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK;
  389. #endif
  390. }
  391. }
  392. else
  393. {
  394. /* DTE_DEACTIVATED */
  395. if (1 == s_cdcVcom.attach)
  396. {
  397. s_cdcVcom.startTransactions = 0;
  398. }
  399. }
  400. }
  401. break;
  402. case USB_DEVICE_CDC_REQUEST_SEND_BREAK:
  403. break;
  404. default:
  405. break;
  406. }
  407. return error;
  408. }
  409. /*!
  410. * @brief USB device callback function.
  411. *
  412. * This function handles the usb device specific requests.
  413. *
  414. * @param handle The USB device handle.
  415. * @param event The USB device event type.
  416. * @param param The parameter of the device specific request.
  417. *
  418. * @return A USB error code or kStatus_USB_Success.
  419. */
  420. usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
  421. {
  422. usb_status_t error = kStatus_USB_Error;
  423. uint8_t *temp8 = (uint8_t *)param;
  424. switch (event)
  425. {
  426. case kUSB_DeviceEventBusReset:
  427. {
  428. USB_DeviceControlPipeInit(s_cdcVcom.deviceHandle);
  429. s_cdcVcom.attach = 0;
  430. #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)) || \
  431. (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
  432. if (kStatus_USB_Success ==
  433. USB_DeviceGetStatus(s_cdcVcom.deviceHandle, kUSB_DeviceStatusSpeed, &s_cdcVcom.speed))
  434. {
  435. USB_DeviceSetSpeed(handle, s_cdcVcom.speed);
  436. }
  437. #endif
  438. }
  439. break;
  440. case kUSB_DeviceEventSetConfiguration:
  441. if (param)
  442. {
  443. s_cdcVcom.attach = 1;
  444. s_cdcVcom.currentConfiguration = *temp8;
  445. if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
  446. {
  447. usb_device_endpoint_init_struct_t epInitStruct;
  448. usb_device_endpoint_callback_struct_t endpointCallback;
  449. /* Initiailize endpoint for interrupt pipe */
  450. endpointCallback.callbackFn = USB_DeviceCdcAcmInterruptIn;
  451. endpointCallback.callbackParam = handle;
  452. epInitStruct.zlt = 0;
  453. epInitStruct.transferType = USB_ENDPOINT_INTERRUPT;
  454. epInitStruct.endpointAddress = USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT |
  455. (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
  456. if (USB_SPEED_HIGH == s_cdcVcom.speed)
  457. {
  458. epInitStruct.maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
  459. }
  460. else
  461. {
  462. epInitStruct.maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
  463. }
  464. USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
  465. /* Initiailize endpoints for bulk pipe */
  466. endpointCallback.callbackFn = USB_DeviceCdcAcmBulkIn;
  467. endpointCallback.callbackParam = handle;
  468. epInitStruct.zlt = 0;
  469. epInitStruct.transferType = USB_ENDPOINT_BULK;
  470. epInitStruct.endpointAddress =
  471. USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
  472. if (USB_SPEED_HIGH == s_cdcVcom.speed)
  473. {
  474. epInitStruct.maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE;
  475. }
  476. else
  477. {
  478. epInitStruct.maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE;
  479. }
  480. USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
  481. endpointCallback.callbackFn = USB_DeviceCdcAcmBulkOut;
  482. endpointCallback.callbackParam = handle;
  483. epInitStruct.zlt = 0;
  484. epInitStruct.transferType = USB_ENDPOINT_BULK;
  485. epInitStruct.endpointAddress =
  486. USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
  487. if (USB_SPEED_HIGH == s_cdcVcom.speed)
  488. {
  489. epInitStruct.maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
  490. }
  491. else
  492. {
  493. epInitStruct.maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
  494. }
  495. USB_DeviceInitEndpoint(s_cdcVcom.deviceHandle, &epInitStruct, &endpointCallback);
  496. if (USB_SPEED_HIGH == s_cdcVcom.speed)
  497. {
  498. s_usbBulkMaxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
  499. }
  500. else
  501. {
  502. s_usbBulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
  503. }
  504. }
  505. }
  506. break;
  507. default:
  508. break;
  509. }
  510. return error;
  511. }
  512. /*!
  513. * @brief USB configure endpoint function.
  514. *
  515. * This function configure endpoint status.
  516. *
  517. * @param handle The USB device handle.
  518. * @param ep Endpoint address.
  519. * @param status A flag to indicate whether to stall the endpoint. 1: stall, 0: unstall.
  520. *
  521. * @return A USB error code or kStatus_USB_Success.
  522. */
  523. usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status)
  524. {
  525. if (status)
  526. {
  527. return USB_DeviceStallEndpoint(handle, ep);
  528. }
  529. else
  530. {
  531. return USB_DeviceUnstallEndpoint(handle, ep);
  532. }
  533. }
  534. /* See virtual_com.h for documentation of this function. */
  535. void USB_VcomWriteBlocking(usb_device_handle baseAddr, const uint8_t *buf, size_t count)
  536. {
  537. while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
  538. {
  539. __NOP();
  540. };
  541. USB_DeviceSendRequest((usb_device_handle)baseAddr, USB_CDC_VCOM_BULK_IN_ENDPOINT, (uint8_t *)buf, count);
  542. while (!s_sendComplete)
  543. {
  544. __NOP();
  545. };
  546. s_sendComplete = 0;
  547. }
  548. /* See virtual_com.h for documentation of this function. */
  549. status_t USB_VcomReadBlocking(usb_device_handle baseAddr, uint8_t *buf, size_t count)
  550. {
  551. status_t error = kStatus_Success;
  552. size_t bufIndex = 0U, bytesToReceive = 0U;
  553. assert(count != 0U);
  554. /* Waiting for the USB ready. */
  555. while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
  556. {
  557. __NOP();
  558. };
  559. do
  560. {
  561. /* If no receive request. */
  562. if (s_recvSize <= 0)
  563. {
  564. if (kStatus_USB_Success !=
  565. USB_DeviceRecvRequest(baseAddr, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, s_usbBulkMaxPacketSize))
  566. {
  567. return kStatus_Fail;
  568. }
  569. s_currRecvIndex = 0;
  570. }
  571. /* Waiting for data received by virtual com. */
  572. while (s_recvSize <= 0)
  573. {
  574. __NOP();
  575. };
  576. /* When receive request is error. */
  577. if (0xFFFFFFFFU == s_recvSize)
  578. {
  579. /* Waiting for the USB ready and transfer started. */
  580. while ((s_cdcVcom.attach != 1) || (s_cdcVcom.startTransactions != 1))
  581. {
  582. __NOP();
  583. };
  584. s_recvSize = 0;
  585. }
  586. else
  587. {
  588. bytesToReceive = MIN(count, s_recvSize);
  589. memcpy((void *)&buf[bufIndex], s_currRecvBuf + s_currRecvIndex, bytesToReceive);
  590. count -= bytesToReceive;
  591. s_recvSize -= bytesToReceive;
  592. bufIndex += bytesToReceive;
  593. s_currRecvIndex += bytesToReceive;
  594. }
  595. } while (0U != count);
  596. return error;
  597. }
  598. /* See virtual_com.h for documentation of this function. */
  599. usb_device_handle USB_VcomInit(void)
  600. {
  601. usb_device_handle deviceHandle = NULL;
  602. USB_DeviceClockInit();
  603. #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
  604. SYSMPU_Enable(SYSMPU, 0);
  605. #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
  606. s_cdcVcom.speed = USB_SPEED_FULL;
  607. s_cdcVcom.attach = 0;
  608. s_cdcVcom.deviceHandle = NULL;
  609. if (kStatus_USB_Success != USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &s_cdcVcom.deviceHandle))
  610. {
  611. deviceHandle = NULL;
  612. }
  613. else
  614. {
  615. deviceHandle = s_cdcVcom.deviceHandle;
  616. USB_DeviceIsrEnable();
  617. USB_DeviceRun(s_cdcVcom.deviceHandle);
  618. }
  619. return deviceHandle;
  620. }
  621. /* See virtual_com.h for documentation of this function. */
  622. void USB_VcomDeinit(usb_device_handle deviceHandle)
  623. {
  624. USB_DeviceStop(deviceHandle);
  625. USB_DeviceDeinit(deviceHandle);
  626. s_cdcVcom.deviceHandle = NULL;
  627. #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0)
  628. USB_EhciPhyDeinit(CONTROLLER_ID);
  629. #endif
  630. #if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0)
  631. CLOCK_DisableUsbfs0Clock();
  632. #endif
  633. #if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
  634. /* enable USB IP clock, user code. */
  635. CLOCK_DisableClock(kCLOCK_Usbd0);
  636. #endif /* USB_DEVICE_CONFIG_LPCIP3511FS */
  637. #if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)
  638. /* enable USB IP clock,user code. */
  639. #endif /* USB_DEVICE_CONFIG_LPCIP3511HS */
  640. }