USBFS_cdc.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. /*******************************************************************************
  2. * File Name: USBFS_cdc.c
  3. * Version 2.60
  4. *
  5. * Description:
  6. * USB HID Class request handler.
  7. *
  8. * Note:
  9. *
  10. ********************************************************************************
  11. * Copyright 2012-2013, Cypress Semiconductor Corporation. All rights reserved.
  12. * You may use this file only in accordance with the license, terms, conditions,
  13. * disclaimers, and limitations in the end user license agreement accompanying
  14. * the software package with which this file was provided.
  15. *******************************************************************************/
  16. #include "USBFS.h"
  17. #if defined(USBFS_ENABLE_CDC_CLASS)
  18. #include "USBFS_cdc.h"
  19. #include "USBFS_pvt.h"
  20. /***************************************
  21. * CDC Variables
  22. ***************************************/
  23. volatile uint8 USBFS_lineCoding[USBFS_LINE_CODING_SIZE];
  24. volatile uint8 USBFS_lineChanged;
  25. volatile uint16 USBFS_lineControlBitmap;
  26. volatile uint8 USBFS_cdc_data_in_ep;
  27. volatile uint8 USBFS_cdc_data_out_ep;
  28. /***************************************
  29. * Static Function Prototypes
  30. ***************************************/
  31. static uint16 USBFS_StrLen(const char8 string[]) ;
  32. /***************************************
  33. * Custom Declarations
  34. ***************************************/
  35. /* `#START CDC_CUSTOM_DECLARATIONS` Place your declaration here */
  36. /* `#END` */
  37. /*******************************************************************************
  38. * Function Name: USBFS_DispatchCDCClassRqst
  39. ********************************************************************************
  40. *
  41. * Summary:
  42. * This routine dispatches CDC class requests.
  43. *
  44. * Parameters:
  45. * None.
  46. *
  47. * Return:
  48. * requestHandled
  49. *
  50. * Global variables:
  51. * USBFS_lineCoding: Contains the current line coding structure.
  52. * It is set by the Host using SET_LINE_CODING request and returned to the
  53. * user code by the USBFS_GetDTERate(), USBFS_GetCharFormat(),
  54. * USBFS_GetParityType(), USBFS_GetDataBits() APIs.
  55. * USBFS_lineControlBitmap: Contains the current control signal
  56. * bitmap. It is set by the Host using SET_CONTROL_LINE request and returned
  57. * to the user code by the USBFS_GetLineControl() API.
  58. * USBFS_lineChanged: This variable is used as a flag for the
  59. * USBFS_IsLineChanged() API, to be aware that Host has been sent request
  60. * for changing Line Coding or Control Bitmap.
  61. *
  62. * Reentrant:
  63. * No.
  64. *
  65. *******************************************************************************/
  66. uint8 USBFS_DispatchCDCClassRqst(void)
  67. {
  68. uint8 requestHandled = USBFS_FALSE;
  69. if ((CY_GET_REG8(USBFS_bmRequestType) & USBFS_RQST_DIR_MASK) == USBFS_RQST_DIR_D2H)
  70. { /* Control Read */
  71. switch (CY_GET_REG8(USBFS_bRequest))
  72. {
  73. case USBFS_CDC_GET_LINE_CODING:
  74. USBFS_currentTD.count = USBFS_LINE_CODING_SIZE;
  75. USBFS_currentTD.pData = USBFS_lineCoding;
  76. requestHandled = USBFS_InitControlRead();
  77. break;
  78. /* `#START CDC_READ_REQUESTS` Place other request handler here */
  79. /* `#END` */
  80. default: /* requestHandled is initialized as FALSE by default */
  81. break;
  82. }
  83. }
  84. else if ((CY_GET_REG8(USBFS_bmRequestType) & USBFS_RQST_DIR_MASK) == \
  85. USBFS_RQST_DIR_H2D)
  86. { /* Control Write */
  87. switch (CY_GET_REG8(USBFS_bRequest))
  88. {
  89. case USBFS_CDC_SET_LINE_CODING:
  90. USBFS_currentTD.count = USBFS_LINE_CODING_SIZE;
  91. USBFS_currentTD.pData = USBFS_lineCoding;
  92. USBFS_lineChanged |= USBFS_LINE_CODING_CHANGED;
  93. requestHandled = USBFS_InitControlWrite();
  94. break;
  95. case USBFS_CDC_SET_CONTROL_LINE_STATE:
  96. USBFS_lineControlBitmap = CY_GET_REG8(USBFS_wValueLo);
  97. USBFS_lineChanged |= USBFS_LINE_CONTROL_CHANGED;
  98. requestHandled = USBFS_InitNoDataControlTransfer();
  99. break;
  100. /* `#START CDC_WRITE_REQUESTS` Place other request handler here */
  101. /* `#END` */
  102. default: /* requestHandled is initialized as FALSE by default */
  103. break;
  104. }
  105. }
  106. else
  107. { /* requestHandled is initialized as FALSE by default */
  108. }
  109. return(requestHandled);
  110. }
  111. /***************************************
  112. * Optional CDC APIs
  113. ***************************************/
  114. #if (USBFS_ENABLE_CDC_CLASS_API != 0u)
  115. /*******************************************************************************
  116. * Function Name: USBFS_CDC_Init
  117. ********************************************************************************
  118. *
  119. * Summary:
  120. * This function initialize the CDC interface to be ready for the receive data
  121. * from the PC.
  122. *
  123. * Parameters:
  124. * None.
  125. *
  126. * Return:
  127. * None.
  128. *
  129. * Global variables:
  130. * USBFS_lineChanged: Initialized to zero.
  131. * USBFS_cdc_data_out_ep: Used as an OUT endpoint number.
  132. *
  133. * Reentrant:
  134. * No.
  135. *
  136. *******************************************************************************/
  137. void USBFS_CDC_Init(void)
  138. {
  139. USBFS_lineChanged = 0u;
  140. USBFS_EnableOutEP(USBFS_cdc_data_out_ep);
  141. }
  142. /*******************************************************************************
  143. * Function Name: USBFS_PutData
  144. ********************************************************************************
  145. *
  146. * Summary:
  147. * Sends a specified number of bytes from the location specified by a
  148. * pointer to the PC.
  149. *
  150. * Parameters:
  151. * pData: pointer to the buffer containing data to be sent.
  152. * length: Specifies the number of bytes to send from the pData
  153. * buffer. Maximum length will be limited by the maximum packet
  154. * size for the endpoint.
  155. *
  156. * Return:
  157. * None.
  158. *
  159. * Global variables:
  160. * USBFS_cdc_data_in_ep: CDC IN endpoint number used for sending
  161. * data.
  162. *
  163. * Reentrant:
  164. * No.
  165. *
  166. *******************************************************************************/
  167. void USBFS_PutData(const uint8* pData, uint16 length)
  168. {
  169. /* Limits length to maximum packet size for the EP */
  170. if(length > USBFS_EP[USBFS_cdc_data_in_ep].bufferSize)
  171. {
  172. /* Caution: Data will be lost if length is greater than Max Packet Length */
  173. length = USBFS_EP[USBFS_cdc_data_in_ep].bufferSize;
  174. /* Halt CPU in debug mode */
  175. CYASSERT(0u != 0u);
  176. }
  177. USBFS_LoadInEP(USBFS_cdc_data_in_ep, pData, length);
  178. }
  179. /*******************************************************************************
  180. * Function Name: USBFS_StrLen
  181. ********************************************************************************
  182. *
  183. * Summary:
  184. * Calculates length of a null terminated string.
  185. *
  186. * Parameters:
  187. * string: pointer to the string.
  188. *
  189. * Return:
  190. * Length of the string
  191. *
  192. *******************************************************************************/
  193. static uint16 USBFS_StrLen(const char8 string[])
  194. {
  195. uint16 len = 0u;
  196. while (string[len] != (char8)0)
  197. {
  198. len++;
  199. }
  200. return (len);
  201. }
  202. /*******************************************************************************
  203. * Function Name: USBFS_PutString
  204. ********************************************************************************
  205. *
  206. * Summary:
  207. * Sends a null terminated string to the PC.
  208. *
  209. * Parameters:
  210. * string: pointer to the string to be sent to the PC
  211. *
  212. * Return:
  213. * None.
  214. *
  215. * Global variables:
  216. * USBFS_cdc_data_in_ep: CDC IN endpoint number used for sending
  217. * data.
  218. *
  219. * Reentrant:
  220. * No.
  221. *
  222. * Theory:
  223. * This function will block if there is not enough memory to place the whole
  224. * string, it will block until the entire string has been written to the
  225. * transmit buffer.
  226. *
  227. *******************************************************************************/
  228. void USBFS_PutString(const char8 string[])
  229. {
  230. uint16 str_length;
  231. uint16 send_length;
  232. uint16 buf_index = 0u;
  233. /* Get length of the null terminated string */
  234. str_length = USBFS_StrLen(string);
  235. do
  236. {
  237. /* Limits length to maximum packet size for the EP */
  238. send_length = (str_length > USBFS_EP[USBFS_cdc_data_in_ep].bufferSize) ?
  239. USBFS_EP[USBFS_cdc_data_in_ep].bufferSize : str_length;
  240. /* Enable IN transfer */
  241. USBFS_LoadInEP(USBFS_cdc_data_in_ep, (const uint8 *)&string[buf_index], send_length);
  242. str_length -= send_length;
  243. /* If more data are present to send */
  244. if(str_length > 0u)
  245. {
  246. buf_index += send_length;
  247. /* Wait for the Host to read it. */
  248. while(USBFS_EP[USBFS_cdc_data_in_ep].apiEpState ==
  249. USBFS_IN_BUFFER_FULL)
  250. {
  251. ;
  252. }
  253. }
  254. }while(str_length > 0u);
  255. }
  256. /*******************************************************************************
  257. * Function Name: USBFS_PutChar
  258. ********************************************************************************
  259. *
  260. * Summary:
  261. * Writes a single character to the PC.
  262. *
  263. * Parameters:
  264. * txDataByte: Character to be sent to the PC.
  265. *
  266. * Return:
  267. * None.
  268. *
  269. * Global variables:
  270. * USBFS_cdc_data_in_ep: CDC IN endpoint number used for sending
  271. * data.
  272. *
  273. * Reentrant:
  274. * No.
  275. *
  276. *******************************************************************************/
  277. void USBFS_PutChar(char8 txDataByte)
  278. {
  279. uint8 dataByte;
  280. dataByte = (uint8)txDataByte;
  281. USBFS_LoadInEP(USBFS_cdc_data_in_ep, &dataByte, 1u);
  282. }
  283. /*******************************************************************************
  284. * Function Name: USBFS_PutCRLF
  285. ********************************************************************************
  286. *
  287. * Summary:
  288. * Sends a carriage return (0x0D) and line feed (0x0A) to the PC
  289. *
  290. * Parameters:
  291. * None.
  292. *
  293. * Return:
  294. * None.
  295. *
  296. * Global variables:
  297. * USBFS_cdc_data_in_ep: CDC IN endpoint number used for sending
  298. * data.
  299. *
  300. * Reentrant:
  301. * No.
  302. *
  303. *******************************************************************************/
  304. void USBFS_PutCRLF(void)
  305. {
  306. const uint8 CYCODE txData[] = {0x0Du, 0x0Au};
  307. USBFS_LoadInEP(USBFS_cdc_data_in_ep, (const uint8 *)txData, 2u);
  308. }
  309. /*******************************************************************************
  310. * Function Name: USBFS_GetCount
  311. ********************************************************************************
  312. *
  313. * Summary:
  314. * This function returns the number of bytes that were received from the PC.
  315. *
  316. * Parameters:
  317. * None.
  318. *
  319. * Return:
  320. * Returns the number of received bytes.
  321. *
  322. * Global variables:
  323. * USBFS_cdc_data_out_ep: CDC OUT endpoint number used.
  324. *
  325. *******************************************************************************/
  326. uint16 USBFS_GetCount(void)
  327. {
  328. uint16 bytesCount = 0u;
  329. if (USBFS_EP[USBFS_cdc_data_out_ep].apiEpState == USBFS_OUT_BUFFER_FULL)
  330. {
  331. bytesCount = USBFS_GetEPCount(USBFS_cdc_data_out_ep);
  332. }
  333. return(bytesCount);
  334. }
  335. /*******************************************************************************
  336. * Function Name: USBFS_DataIsReady
  337. ********************************************************************************
  338. *
  339. * Summary:
  340. * Returns a nonzero value if the component received data or received
  341. * zero-length packet. The GetAll() or GetData() API should be called to read
  342. * data from the buffer and re-init OUT endpoint even when zero-length packet
  343. * received.
  344. *
  345. * Parameters:
  346. * None.
  347. *
  348. * Return:
  349. * If the OUT packet received this function returns a nonzero value.
  350. * Otherwise zero is returned.
  351. *
  352. * Global variables:
  353. * USBFS_cdc_data_out_ep: CDC OUT endpoint number used.
  354. *
  355. *******************************************************************************/
  356. uint8 USBFS_DataIsReady(void)
  357. {
  358. return(USBFS_EP[USBFS_cdc_data_out_ep].apiEpState);
  359. }
  360. /*******************************************************************************
  361. * Function Name: USBFS_CDCIsReady
  362. ********************************************************************************
  363. *
  364. * Summary:
  365. * Returns a nonzero value if the component is ready to send more data to the
  366. * PC. Otherwise returns zero. Should be called before sending new data to
  367. * ensure the previous data has finished sending.This function returns the
  368. * number of bytes that were received from the PC.
  369. *
  370. * Parameters:
  371. * None.
  372. *
  373. * Return:
  374. * If the buffer can accept new data then this function returns a nonzero value.
  375. * Otherwise zero is returned.
  376. *
  377. * Global variables:
  378. * USBFS_cdc_data_in_ep: CDC IN endpoint number used.
  379. *
  380. *******************************************************************************/
  381. uint8 USBFS_CDCIsReady(void)
  382. {
  383. return(USBFS_EP[USBFS_cdc_data_in_ep].apiEpState);
  384. }
  385. /*******************************************************************************
  386. * Function Name: USBFS_GetData
  387. ********************************************************************************
  388. *
  389. * Summary:
  390. * Gets a specified number of bytes from the input buffer and places it in a
  391. * data array specified by the passed pointer.
  392. * USBFS_DataIsReady() API should be called before, to be sure
  393. * that data is received from the Host.
  394. *
  395. * Parameters:
  396. * pData: Pointer to the data array where data will be placed.
  397. * Length: Number of bytes to read into the data array from the RX buffer.
  398. * Maximum length is limited by the the number of received bytes.
  399. *
  400. * Return:
  401. * Number of bytes received.
  402. *
  403. * Global variables:
  404. * USBFS_cdc_data_out_ep: CDC OUT endpoint number used.
  405. *
  406. * Reentrant:
  407. * No.
  408. *
  409. *******************************************************************************/
  410. uint16 USBFS_GetData(uint8* pData, uint16 length)
  411. {
  412. return(USBFS_ReadOutEP(USBFS_cdc_data_out_ep, pData, length));
  413. }
  414. /*******************************************************************************
  415. * Function Name: USBFS_GetAll
  416. ********************************************************************************
  417. *
  418. * Summary:
  419. * Gets all bytes of received data from the input buffer and places it into a
  420. * specified data array. USBFS_DataIsReady() API should be called
  421. * before, to be sure that data is received from the Host.
  422. *
  423. * Parameters:
  424. * pData: Pointer to the data array where data will be placed.
  425. *
  426. * Return:
  427. * Number of bytes received.
  428. *
  429. * Global variables:
  430. * USBFS_cdc_data_out_ep: CDC OUT endpoint number used.
  431. * USBFS_EP[].bufferSize: EP max packet size is used as a length
  432. * to read all data from the EP buffer.
  433. *
  434. * Reentrant:
  435. * No.
  436. *
  437. *******************************************************************************/
  438. uint16 USBFS_GetAll(uint8* pData)
  439. {
  440. return (USBFS_ReadOutEP(USBFS_cdc_data_out_ep, pData,
  441. USBFS_EP[USBFS_cdc_data_out_ep].bufferSize));
  442. }
  443. /*******************************************************************************
  444. * Function Name: USBFS_GetChar
  445. ********************************************************************************
  446. *
  447. * Summary:
  448. * Reads one byte of received data from the buffer.
  449. *
  450. * Parameters:
  451. * None.
  452. *
  453. * Return:
  454. * Received one character.
  455. *
  456. * Global variables:
  457. * USBFS_cdc_data_out_ep: CDC OUT endpoint number used.
  458. *
  459. * Reentrant:
  460. * No.
  461. *
  462. *******************************************************************************/
  463. uint8 USBFS_GetChar(void)
  464. {
  465. uint8 rxData;
  466. (void) USBFS_ReadOutEP(USBFS_cdc_data_out_ep, &rxData, 1u);
  467. return(rxData);
  468. }
  469. /*******************************************************************************
  470. * Function Name: USBFS_IsLineChanged
  471. ********************************************************************************
  472. *
  473. * Summary:
  474. * This function returns clear on read status of the line.
  475. *
  476. * Parameters:
  477. * None.
  478. *
  479. * Return:
  480. * If SET_LINE_CODING or CDC_SET_CONTROL_LINE_STATE request received then not
  481. * zero value returned. Otherwise zero is returned.
  482. *
  483. * Global variables:
  484. * USBFS_transferState - it is checked to be sure then OUT data
  485. * phase has been complete, and data written to the lineCoding or Control
  486. * Bitmap buffer.
  487. * USBFS_lineChanged: used as a flag to be aware that Host has been
  488. * sent request for changing Line Coding or Control Bitmap.
  489. *
  490. *******************************************************************************/
  491. uint8 USBFS_IsLineChanged(void)
  492. {
  493. uint8 state = 0u;
  494. /* transferState is checked to be sure then OUT data phase has been complete */
  495. if(USBFS_transferState == USBFS_TRANS_STATE_IDLE)
  496. {
  497. if(USBFS_lineChanged != 0u)
  498. {
  499. state = USBFS_lineChanged;
  500. USBFS_lineChanged = 0u;
  501. }
  502. }
  503. return(state);
  504. }
  505. /*******************************************************************************
  506. * Function Name: USBFS_GetDTERate
  507. ********************************************************************************
  508. *
  509. * Summary:
  510. * Returns the data terminal rate set for this port in bits per second.
  511. *
  512. * Parameters:
  513. * None.
  514. *
  515. * Return:
  516. * Returns a uint32 value of the data rate in bits per second.
  517. *
  518. * Global variables:
  519. * USBFS_lineCoding: First four bytes converted to uint32
  520. * depend on compiler, and returned as a data rate.
  521. *
  522. *******************************************************************************/
  523. uint32 USBFS_GetDTERate(void)
  524. {
  525. uint32 rate;
  526. rate = USBFS_lineCoding[USBFS_LINE_CODING_RATE + 3u];
  527. rate = (rate << 8u) | USBFS_lineCoding[USBFS_LINE_CODING_RATE + 2u];
  528. rate = (rate << 8u) | USBFS_lineCoding[USBFS_LINE_CODING_RATE + 1u];
  529. rate = (rate << 8u) | USBFS_lineCoding[USBFS_LINE_CODING_RATE];
  530. return(rate);
  531. }
  532. /*******************************************************************************
  533. * Function Name: USBFS_GetCharFormat
  534. ********************************************************************************
  535. *
  536. * Summary:
  537. * Returns the number of stop bits.
  538. *
  539. * Parameters:
  540. * None.
  541. *
  542. * Return:
  543. * Returns the number of stop bits.
  544. *
  545. * Global variables:
  546. * USBFS_lineCoding: used to get a parameter.
  547. *
  548. *******************************************************************************/
  549. uint8 USBFS_GetCharFormat(void)
  550. {
  551. return(USBFS_lineCoding[USBFS_LINE_CODING_STOP_BITS]);
  552. }
  553. /*******************************************************************************
  554. * Function Name: USBFS_GetParityType
  555. ********************************************************************************
  556. *
  557. * Summary:
  558. * Returns the parity type for the CDC port.
  559. *
  560. * Parameters:
  561. * None.
  562. *
  563. * Return:
  564. * Returns the parity type.
  565. *
  566. * Global variables:
  567. * USBFS_lineCoding: used to get a parameter.
  568. *
  569. *******************************************************************************/
  570. uint8 USBFS_GetParityType(void)
  571. {
  572. return(USBFS_lineCoding[USBFS_LINE_CODING_PARITY]);
  573. }
  574. /*******************************************************************************
  575. * Function Name: USBFS_GetDataBits
  576. ********************************************************************************
  577. *
  578. * Summary:
  579. * Returns the number of data bits for the CDC port.
  580. *
  581. * Parameters:
  582. * None.
  583. *
  584. * Return:
  585. * Returns the number of data bits.
  586. * The number of data bits can be 5, 6, 7, 8 or 16.
  587. *
  588. * Global variables:
  589. * USBFS_lineCoding: used to get a parameter.
  590. *
  591. *******************************************************************************/
  592. uint8 USBFS_GetDataBits(void)
  593. {
  594. return(USBFS_lineCoding[USBFS_LINE_CODING_DATA_BITS]);
  595. }
  596. /*******************************************************************************
  597. * Function Name: USBFS_GetLineControl
  598. ********************************************************************************
  599. *
  600. * Summary:
  601. * Returns Line control bitmap.
  602. *
  603. * Parameters:
  604. * None.
  605. *
  606. * Return:
  607. * Returns Line control bitmap.
  608. *
  609. * Global variables:
  610. * USBFS_lineControlBitmap: used to get a parameter.
  611. *
  612. *******************************************************************************/
  613. uint16 USBFS_GetLineControl(void)
  614. {
  615. return(USBFS_lineControlBitmap);
  616. }
  617. #endif /* End USBFS_ENABLE_CDC_CLASS_API*/
  618. /*******************************************************************************
  619. * Additional user functions supporting CDC Requests
  620. ********************************************************************************/
  621. /* `#START CDC_FUNCTIONS` Place any additional functions here */
  622. /* `#END` */
  623. #endif /* End USBFS_ENABLE_CDC_CLASS*/
  624. /* [] END OF FILE */