USBFS_drv.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. /*******************************************************************************
  2. * File Name: USBFS_drv.c
  3. * Version 2.60
  4. *
  5. * Description:
  6. * Endpoint 0 Driver for the USBFS Component.
  7. *
  8. * Note:
  9. *
  10. ********************************************************************************
  11. * Copyright 2008-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. #include "USBFS_pvt.h"
  18. /***************************************
  19. * Global data allocation
  20. ***************************************/
  21. volatile T_USBFS_EP_CTL_BLOCK USBFS_EP[USBFS_MAX_EP];
  22. volatile uint8 USBFS_configuration;
  23. volatile uint8 USBFS_interfaceNumber;
  24. volatile uint8 USBFS_configurationChanged;
  25. volatile uint8 USBFS_deviceAddress;
  26. volatile uint8 USBFS_deviceStatus;
  27. volatile uint8 USBFS_interfaceSetting[USBFS_MAX_INTERFACES_NUMBER];
  28. volatile uint8 USBFS_interfaceSetting_last[USBFS_MAX_INTERFACES_NUMBER];
  29. volatile uint8 USBFS_interfaceStatus[USBFS_MAX_INTERFACES_NUMBER];
  30. volatile uint8 USBFS_device;
  31. const uint8 CYCODE *USBFS_interfaceClass;
  32. /***************************************
  33. * Local data allocation
  34. ***************************************/
  35. volatile uint8 USBFS_ep0Toggle;
  36. volatile uint8 USBFS_lastPacketSize;
  37. volatile uint8 USBFS_transferState;
  38. volatile T_USBFS_TD USBFS_currentTD;
  39. volatile uint8 USBFS_ep0Mode;
  40. volatile uint8 USBFS_ep0Count;
  41. volatile uint16 USBFS_transferByteCount;
  42. /*******************************************************************************
  43. * Function Name: USBFS_ep_0_Interrupt
  44. ********************************************************************************
  45. *
  46. * Summary:
  47. * This Interrupt Service Routine handles Endpoint 0 (Control Pipe) traffic.
  48. * It dispatches setup requests and handles the data and status stages.
  49. *
  50. * Parameters:
  51. * None.
  52. *
  53. * Return:
  54. * None.
  55. *
  56. *******************************************************************************/
  57. CY_ISR(USBFS_EP_0_ISR)
  58. {
  59. uint8 bRegTemp;
  60. uint8 modifyReg;
  61. bRegTemp = CY_GET_REG8(USBFS_EP0_CR_PTR);
  62. if ((bRegTemp & USBFS_MODE_ACKD) != 0u)
  63. {
  64. modifyReg = 1u;
  65. if ((bRegTemp & USBFS_MODE_SETUP_RCVD) != 0u)
  66. {
  67. if((bRegTemp & USBFS_MODE_MASK) != USBFS_MODE_NAK_IN_OUT)
  68. {
  69. modifyReg = 0u; /* When mode not NAK_IN_OUT => invalid setup */
  70. }
  71. else
  72. {
  73. USBFS_HandleSetup();
  74. if((USBFS_ep0Mode & USBFS_MODE_SETUP_RCVD) != 0u)
  75. {
  76. modifyReg = 0u; /* if SETUP bit set -> exit without modifying the mode */
  77. }
  78. }
  79. }
  80. else if ((bRegTemp & USBFS_MODE_IN_RCVD) != 0u)
  81. {
  82. USBFS_HandleIN();
  83. }
  84. else if ((bRegTemp & USBFS_MODE_OUT_RCVD) != 0u)
  85. {
  86. USBFS_HandleOUT();
  87. }
  88. else
  89. {
  90. modifyReg = 0u;
  91. }
  92. if(modifyReg != 0u)
  93. {
  94. bRegTemp = CY_GET_REG8(USBFS_EP0_CR_PTR); /* unlock registers */
  95. if((bRegTemp & USBFS_MODE_SETUP_RCVD) == 0u) /* Check if SETUP bit is not set, otherwise exit */
  96. {
  97. /* Update the count register */
  98. bRegTemp = USBFS_ep0Toggle | USBFS_ep0Count;
  99. CY_SET_REG8(USBFS_EP0_CNT_PTR, bRegTemp);
  100. if(bRegTemp == CY_GET_REG8(USBFS_EP0_CNT_PTR)) /* continue if writing was successful */
  101. {
  102. do
  103. {
  104. modifyReg = USBFS_ep0Mode; /* Init temporary variable */
  105. /* Unlock registers */
  106. bRegTemp = CY_GET_REG8(USBFS_EP0_CR_PTR) & USBFS_MODE_SETUP_RCVD;
  107. if(bRegTemp == 0u) /* Check if SETUP bit is not set */
  108. {
  109. /* Set the Mode Register */
  110. CY_SET_REG8(USBFS_EP0_CR_PTR, USBFS_ep0Mode);
  111. /* Writing check */
  112. modifyReg = CY_GET_REG8(USBFS_EP0_CR_PTR) & USBFS_MODE_MASK;
  113. }
  114. }while(modifyReg != USBFS_ep0Mode); /* Repeat if writing was not successful */
  115. }
  116. }
  117. }
  118. }
  119. }
  120. /*******************************************************************************
  121. * Function Name: USBFS_HandleSetup
  122. ********************************************************************************
  123. *
  124. * Summary:
  125. * This Routine dispatches requests for the four USB request types
  126. *
  127. * Parameters:
  128. * None.
  129. *
  130. * Return:
  131. * None.
  132. *
  133. * Reentrant:
  134. * No.
  135. *
  136. *******************************************************************************/
  137. void USBFS_HandleSetup(void)
  138. {
  139. uint8 requestHandled;
  140. requestHandled = CY_GET_REG8(USBFS_EP0_CR_PTR); /* unlock registers */
  141. CY_SET_REG8(USBFS_EP0_CR_PTR, requestHandled); /* clear setup bit */
  142. requestHandled = CY_GET_REG8(USBFS_EP0_CR_PTR); /* reread register */
  143. if((requestHandled & USBFS_MODE_SETUP_RCVD) != 0u)
  144. {
  145. USBFS_ep0Mode = requestHandled; /* if SETUP bit set -> exit without modifying the mode */
  146. }
  147. else
  148. {
  149. /* In case the previous transfer did not complete, close it out */
  150. USBFS_UpdateStatusBlock(USBFS_XFER_PREMATURE);
  151. switch (CY_GET_REG8(USBFS_bmRequestType) & USBFS_RQST_TYPE_MASK)
  152. {
  153. case USBFS_RQST_TYPE_STD:
  154. requestHandled = USBFS_HandleStandardRqst();
  155. break;
  156. case USBFS_RQST_TYPE_CLS:
  157. requestHandled = USBFS_DispatchClassRqst();
  158. break;
  159. case USBFS_RQST_TYPE_VND:
  160. requestHandled = USBFS_HandleVendorRqst();
  161. break;
  162. default:
  163. requestHandled = USBFS_FALSE;
  164. break;
  165. }
  166. if (requestHandled == USBFS_FALSE)
  167. {
  168. USBFS_ep0Mode = USBFS_MODE_STALL_IN_OUT;
  169. }
  170. }
  171. }
  172. /*******************************************************************************
  173. * Function Name: USBFS_HandleIN
  174. ********************************************************************************
  175. *
  176. * Summary:
  177. * This routine handles EP0 IN transfers.
  178. *
  179. * Parameters:
  180. * None.
  181. *
  182. * Return:
  183. * None.
  184. *
  185. * Reentrant:
  186. * No.
  187. *
  188. *******************************************************************************/
  189. void USBFS_HandleIN(void)
  190. {
  191. switch (USBFS_transferState)
  192. {
  193. case USBFS_TRANS_STATE_IDLE:
  194. break;
  195. case USBFS_TRANS_STATE_CONTROL_READ:
  196. USBFS_ControlReadDataStage();
  197. break;
  198. case USBFS_TRANS_STATE_CONTROL_WRITE:
  199. USBFS_ControlWriteStatusStage();
  200. break;
  201. case USBFS_TRANS_STATE_NO_DATA_CONTROL:
  202. USBFS_NoDataControlStatusStage();
  203. break;
  204. default: /* there are no more states */
  205. break;
  206. }
  207. }
  208. /*******************************************************************************
  209. * Function Name: USBFS_HandleOUT
  210. ********************************************************************************
  211. *
  212. * Summary:
  213. * This routine handles EP0 OUT transfers.
  214. *
  215. * Parameters:
  216. * None.
  217. *
  218. * Return:
  219. * None.
  220. *
  221. * Reentrant:
  222. * No.
  223. *
  224. *******************************************************************************/
  225. void USBFS_HandleOUT(void)
  226. {
  227. switch (USBFS_transferState)
  228. {
  229. case USBFS_TRANS_STATE_IDLE:
  230. break;
  231. case USBFS_TRANS_STATE_CONTROL_READ:
  232. USBFS_ControlReadStatusStage();
  233. break;
  234. case USBFS_TRANS_STATE_CONTROL_WRITE:
  235. USBFS_ControlWriteDataStage();
  236. break;
  237. case USBFS_TRANS_STATE_NO_DATA_CONTROL:
  238. /* Update the completion block */
  239. USBFS_UpdateStatusBlock(USBFS_XFER_ERROR);
  240. /* We expect no more data, so stall INs and OUTs */
  241. USBFS_ep0Mode = USBFS_MODE_STALL_IN_OUT;
  242. break;
  243. default: /* There are no more states */
  244. break;
  245. }
  246. }
  247. /*******************************************************************************
  248. * Function Name: USBFS_LoadEP0
  249. ********************************************************************************
  250. *
  251. * Summary:
  252. * This routine loads the EP0 data registers for OUT transfers. It uses the
  253. * currentTD (previously initialized by the _InitControlWrite function and
  254. * updated for each OUT transfer, and the bLastPacketSize) to determine how
  255. * many uint8s to transfer on the current OUT.
  256. *
  257. * If the number of uint8s remaining is zero and the last transfer was full,
  258. * we need to send a zero length packet. Otherwise we send the minimum
  259. * of the control endpoint size (8) or remaining number of uint8s for the
  260. * transaction.
  261. *
  262. * Parameters:
  263. * None.
  264. *
  265. * Return:
  266. * None.
  267. *
  268. * Global variables:
  269. * USBFS_transferByteCount - Update the transfer byte count from the
  270. * last transaction.
  271. * USBFS_ep0Count - counts the data loaded to the SIE memory in
  272. * current packet.
  273. * USBFS_lastPacketSize - remembers the USBFS_ep0Count value for the
  274. * next packet.
  275. * USBFS_transferByteCount - sum of the previous bytes transferred
  276. * on previous packets(sum of USBFS_lastPacketSize)
  277. * USBFS_ep0Toggle - inverted
  278. * USBFS_ep0Mode - prepare for mode register content.
  279. * USBFS_transferState - set to TRANS_STATE_CONTROL_READ
  280. *
  281. * Reentrant:
  282. * No.
  283. *
  284. *******************************************************************************/
  285. void USBFS_LoadEP0(void)
  286. {
  287. uint8 ep0Count = 0u;
  288. /* Update the transfer byte count from the last transaction */
  289. USBFS_transferByteCount += USBFS_lastPacketSize;
  290. /* Now load the next transaction */
  291. while ((USBFS_currentTD.count > 0u) && (ep0Count < 8u))
  292. {
  293. CY_SET_REG8((reg8 *)(USBFS_EP0_DR0_IND + ep0Count), *USBFS_currentTD.pData);
  294. USBFS_currentTD.pData = &USBFS_currentTD.pData[1u];
  295. ep0Count++;
  296. USBFS_currentTD.count--;
  297. }
  298. /* Support zero-length packet*/
  299. if( (USBFS_lastPacketSize == 8u) || (ep0Count > 0u) )
  300. {
  301. /* Update the data toggle */
  302. USBFS_ep0Toggle ^= USBFS_EP0_CNT_DATA_TOGGLE;
  303. /* Set the Mode Register */
  304. USBFS_ep0Mode = USBFS_MODE_ACK_IN_STATUS_OUT;
  305. /* Update the state (or stay the same) */
  306. USBFS_transferState = USBFS_TRANS_STATE_CONTROL_READ;
  307. }
  308. else
  309. {
  310. /* Expect Status Stage Out */
  311. USBFS_ep0Mode = USBFS_MODE_STATUS_OUT_ONLY;
  312. /* Update the state (or stay the same) */
  313. USBFS_transferState = USBFS_TRANS_STATE_CONTROL_READ;
  314. }
  315. /* Save the packet size for next time */
  316. USBFS_lastPacketSize = ep0Count;
  317. USBFS_ep0Count = ep0Count;
  318. }
  319. /*******************************************************************************
  320. * Function Name: USBFS_InitControlRead
  321. ********************************************************************************
  322. *
  323. * Summary:
  324. * Initialize a control read transaction, usable to send data to the host.
  325. * The following global variables should be initialized before this function
  326. * called. To send zero length packet use InitZeroLengthControlTransfer
  327. * function.
  328. *
  329. * Parameters:
  330. * None.
  331. *
  332. * Return:
  333. * requestHandled state.
  334. *
  335. * Global variables:
  336. * USBFS_currentTD.count - counts of data to be sent.
  337. * USBFS_currentTD.pData - data pointer.
  338. *
  339. * Reentrant:
  340. * No.
  341. *
  342. *******************************************************************************/
  343. uint8 USBFS_InitControlRead(void)
  344. {
  345. uint16 xferCount;
  346. if(USBFS_currentTD.count == 0u)
  347. {
  348. (void) USBFS_InitZeroLengthControlTransfer();
  349. }
  350. else
  351. {
  352. /* Set up the state machine */
  353. USBFS_transferState = USBFS_TRANS_STATE_CONTROL_READ;
  354. /* Set the toggle, it gets updated in LoadEP */
  355. USBFS_ep0Toggle = 0u;
  356. /* Initialize the Status Block */
  357. USBFS_InitializeStatusBlock();
  358. xferCount = (((uint16)CY_GET_REG8(USBFS_lengthHi) << 8u) | (CY_GET_REG8(USBFS_lengthLo)));
  359. if (USBFS_currentTD.count > xferCount)
  360. {
  361. USBFS_currentTD.count = xferCount;
  362. }
  363. USBFS_LoadEP0();
  364. }
  365. return(USBFS_TRUE);
  366. }
  367. /*******************************************************************************
  368. * Function Name: USBFS_InitZeroLengthControlTransfer
  369. ********************************************************************************
  370. *
  371. * Summary:
  372. * Initialize a zero length data IN transfer.
  373. *
  374. * Parameters:
  375. * None.
  376. *
  377. * Return:
  378. * requestHandled state.
  379. *
  380. * Global variables:
  381. * USBFS_ep0Toggle - set to EP0_CNT_DATA_TOGGLE
  382. * USBFS_ep0Mode - prepare for mode register content.
  383. * USBFS_transferState - set to TRANS_STATE_CONTROL_READ
  384. * USBFS_ep0Count - cleared, means the zero-length packet.
  385. * USBFS_lastPacketSize - cleared.
  386. *
  387. * Reentrant:
  388. * No.
  389. *
  390. *******************************************************************************/
  391. uint8 USBFS_InitZeroLengthControlTransfer(void)
  392. {
  393. /* Update the state */
  394. USBFS_transferState = USBFS_TRANS_STATE_CONTROL_READ;
  395. /* Set the data toggle */
  396. USBFS_ep0Toggle = USBFS_EP0_CNT_DATA_TOGGLE;
  397. /* Set the Mode Register */
  398. USBFS_ep0Mode = USBFS_MODE_ACK_IN_STATUS_OUT;
  399. /* Save the packet size for next time */
  400. USBFS_lastPacketSize = 0u;
  401. USBFS_ep0Count = 0u;
  402. return(USBFS_TRUE);
  403. }
  404. /*******************************************************************************
  405. * Function Name: USBFS_ControlReadDataStage
  406. ********************************************************************************
  407. *
  408. * Summary:
  409. * Handle the Data Stage of a control read transfer.
  410. *
  411. * Parameters:
  412. * None.
  413. *
  414. * Return:
  415. * None.
  416. *
  417. * Reentrant:
  418. * No.
  419. *
  420. *******************************************************************************/
  421. void USBFS_ControlReadDataStage(void)
  422. {
  423. USBFS_LoadEP0();
  424. }
  425. /*******************************************************************************
  426. * Function Name: USBFS_ControlReadStatusStage
  427. ********************************************************************************
  428. *
  429. * Summary:
  430. * Handle the Status Stage of a control read transfer.
  431. *
  432. * Parameters:
  433. * None.
  434. *
  435. * Return:
  436. * None.
  437. *
  438. * Global variables:
  439. * USBFS_USBFS_transferByteCount - updated with last packet size.
  440. * USBFS_transferState - set to TRANS_STATE_IDLE.
  441. * USBFS_ep0Mode - set to MODE_STALL_IN_OUT.
  442. *
  443. * Reentrant:
  444. * No.
  445. *
  446. *******************************************************************************/
  447. void USBFS_ControlReadStatusStage(void)
  448. {
  449. /* Update the transfer byte count */
  450. USBFS_transferByteCount += USBFS_lastPacketSize;
  451. /* Go Idle */
  452. USBFS_transferState = USBFS_TRANS_STATE_IDLE;
  453. /* Update the completion block */
  454. USBFS_UpdateStatusBlock(USBFS_XFER_STATUS_ACK);
  455. /* We expect no more data, so stall INs and OUTs */
  456. USBFS_ep0Mode = USBFS_MODE_STALL_IN_OUT;
  457. }
  458. /*******************************************************************************
  459. * Function Name: USBFS_InitControlWrite
  460. ********************************************************************************
  461. *
  462. * Summary:
  463. * Initialize a control write transaction
  464. *
  465. * Parameters:
  466. * None.
  467. *
  468. * Return:
  469. * requestHandled state.
  470. *
  471. * Global variables:
  472. * USBFS_USBFS_transferState - set to TRANS_STATE_CONTROL_WRITE
  473. * USBFS_ep0Toggle - set to EP0_CNT_DATA_TOGGLE
  474. * USBFS_ep0Mode - set to MODE_ACK_OUT_STATUS_IN
  475. *
  476. * Reentrant:
  477. * No.
  478. *
  479. *******************************************************************************/
  480. uint8 USBFS_InitControlWrite(void)
  481. {
  482. uint16 xferCount;
  483. /* Set up the state machine */
  484. USBFS_transferState = USBFS_TRANS_STATE_CONTROL_WRITE;
  485. /* This might not be necessary */
  486. USBFS_ep0Toggle = USBFS_EP0_CNT_DATA_TOGGLE;
  487. /* Initialize the Status Block */
  488. USBFS_InitializeStatusBlock();
  489. xferCount = (((uint16)CY_GET_REG8(USBFS_lengthHi) << 8u) | (CY_GET_REG8(USBFS_lengthLo)));
  490. if (USBFS_currentTD.count > xferCount)
  491. {
  492. USBFS_currentTD.count = xferCount;
  493. }
  494. /* Expect Data or Status Stage */
  495. USBFS_ep0Mode = USBFS_MODE_ACK_OUT_STATUS_IN;
  496. return(USBFS_TRUE);
  497. }
  498. /*******************************************************************************
  499. * Function Name: USBFS_ControlWriteDataStage
  500. ********************************************************************************
  501. *
  502. * Summary:
  503. * Handle the Data Stage of a control write transfer
  504. * 1. Get the data (We assume the destination was validated previously)
  505. * 2. Update the count and data toggle
  506. * 3. Update the mode register for the next transaction
  507. *
  508. * Parameters:
  509. * None.
  510. *
  511. * Return:
  512. * None.
  513. *
  514. * Global variables:
  515. * USBFS_transferByteCount - Update the transfer byte count from the
  516. * last transaction.
  517. * USBFS_ep0Count - counts the data loaded from the SIE memory
  518. * in current packet.
  519. * USBFS_transferByteCount - sum of the previous bytes transferred
  520. * on previous packets(sum of USBFS_lastPacketSize)
  521. * USBFS_ep0Toggle - inverted
  522. * USBFS_ep0Mode - set to MODE_ACK_OUT_STATUS_IN.
  523. *
  524. * Reentrant:
  525. * No.
  526. *
  527. *******************************************************************************/
  528. void USBFS_ControlWriteDataStage(void)
  529. {
  530. uint8 ep0Count;
  531. uint8 regIndex = 0u;
  532. ep0Count = (CY_GET_REG8(USBFS_EP0_CNT_PTR) & USBFS_EPX_CNT0_MASK) -
  533. USBFS_EPX_CNTX_CRC_COUNT;
  534. USBFS_transferByteCount += ep0Count;
  535. while ((USBFS_currentTD.count > 0u) && (ep0Count > 0u))
  536. {
  537. *USBFS_currentTD.pData = CY_GET_REG8((reg8 *)(USBFS_EP0_DR0_IND + regIndex));
  538. USBFS_currentTD.pData = &USBFS_currentTD.pData[1u];
  539. regIndex++;
  540. ep0Count--;
  541. USBFS_currentTD.count--;
  542. }
  543. USBFS_ep0Count = ep0Count;
  544. /* Update the data toggle */
  545. USBFS_ep0Toggle ^= USBFS_EP0_CNT_DATA_TOGGLE;
  546. /* Expect Data or Status Stage */
  547. USBFS_ep0Mode = USBFS_MODE_ACK_OUT_STATUS_IN;
  548. }
  549. /*******************************************************************************
  550. * Function Name: USBFS_ControlWriteStatusStage
  551. ********************************************************************************
  552. *
  553. * Summary:
  554. * Handle the Status Stage of a control write transfer
  555. *
  556. * Parameters:
  557. * None.
  558. *
  559. * Return:
  560. * None.
  561. *
  562. * Global variables:
  563. * USBFS_transferState - set to TRANS_STATE_IDLE.
  564. * USBFS_USBFS_ep0Mode - set to MODE_STALL_IN_OUT.
  565. *
  566. * Reentrant:
  567. * No.
  568. *
  569. *******************************************************************************/
  570. void USBFS_ControlWriteStatusStage(void)
  571. {
  572. /* Go Idle */
  573. USBFS_transferState = USBFS_TRANS_STATE_IDLE;
  574. /* Update the completion block */
  575. USBFS_UpdateStatusBlock(USBFS_XFER_STATUS_ACK);
  576. /* We expect no more data, so stall INs and OUTs */
  577. USBFS_ep0Mode = USBFS_MODE_STALL_IN_OUT;
  578. }
  579. /*******************************************************************************
  580. * Function Name: USBFS_InitNoDataControlTransfer
  581. ********************************************************************************
  582. *
  583. * Summary:
  584. * Initialize a no data control transfer
  585. *
  586. * Parameters:
  587. * None.
  588. *
  589. * Return:
  590. * requestHandled state.
  591. *
  592. * Global variables:
  593. * USBFS_transferState - set to TRANS_STATE_NO_DATA_CONTROL.
  594. * USBFS_ep0Mode - set to MODE_STATUS_IN_ONLY.
  595. * USBFS_ep0Count - cleared.
  596. * USBFS_ep0Toggle - set to EP0_CNT_DATA_TOGGLE
  597. *
  598. * Reentrant:
  599. * No.
  600. *
  601. *******************************************************************************/
  602. uint8 USBFS_InitNoDataControlTransfer(void)
  603. {
  604. USBFS_transferState = USBFS_TRANS_STATE_NO_DATA_CONTROL;
  605. USBFS_ep0Mode = USBFS_MODE_STATUS_IN_ONLY;
  606. USBFS_ep0Toggle = USBFS_EP0_CNT_DATA_TOGGLE;
  607. USBFS_ep0Count = 0u;
  608. return(USBFS_TRUE);
  609. }
  610. /*******************************************************************************
  611. * Function Name: USBFS_NoDataControlStatusStage
  612. ********************************************************************************
  613. * Summary:
  614. * Handle the Status Stage of a no data control transfer.
  615. *
  616. * SET_ADDRESS is special, since we need to receive the status stage with
  617. * the old address.
  618. *
  619. * Parameters:
  620. * None.
  621. *
  622. * Return:
  623. * None.
  624. *
  625. * Global variables:
  626. * USBFS_transferState - set to TRANS_STATE_IDLE.
  627. * USBFS_ep0Mode - set to MODE_STALL_IN_OUT.
  628. * USBFS_ep0Toggle - set to EP0_CNT_DATA_TOGGLE
  629. * USBFS_deviceAddress - used to set new address and cleared
  630. *
  631. * Reentrant:
  632. * No.
  633. *
  634. *******************************************************************************/
  635. void USBFS_NoDataControlStatusStage(void)
  636. {
  637. /* Change the USB address register if we got a SET_ADDRESS. */
  638. if (USBFS_deviceAddress != 0u)
  639. {
  640. CY_SET_REG8(USBFS_CR0_PTR, USBFS_deviceAddress | USBFS_CR0_ENABLE);
  641. USBFS_deviceAddress = 0u;
  642. }
  643. /* Go Idle */
  644. USBFS_transferState = USBFS_TRANS_STATE_IDLE;
  645. /* Update the completion block */
  646. USBFS_UpdateStatusBlock(USBFS_XFER_STATUS_ACK);
  647. /* We expect no more data, so stall INs and OUTs */
  648. USBFS_ep0Mode = USBFS_MODE_STALL_IN_OUT;
  649. }
  650. /*******************************************************************************
  651. * Function Name: USBFS_UpdateStatusBlock
  652. ********************************************************************************
  653. *
  654. * Summary:
  655. * Update the Completion Status Block for a Request. The block is updated
  656. * with the completion code the USBFS_transferByteCount. The
  657. * StatusBlock Pointer is set to NULL.
  658. *
  659. * Parameters:
  660. * completionCode - status.
  661. *
  662. * Return:
  663. * None.
  664. *
  665. * Global variables:
  666. * USBFS_currentTD.pStatusBlock->status - updated by the
  667. * completionCode parameter.
  668. * USBFS_currentTD.pStatusBlock->length - updated.
  669. * USBFS_currentTD.pStatusBlock - cleared.
  670. *
  671. * Reentrant:
  672. * No.
  673. *
  674. *******************************************************************************/
  675. void USBFS_UpdateStatusBlock(uint8 completionCode)
  676. {
  677. if (USBFS_currentTD.pStatusBlock != NULL)
  678. {
  679. USBFS_currentTD.pStatusBlock->status = completionCode;
  680. USBFS_currentTD.pStatusBlock->length = USBFS_transferByteCount;
  681. USBFS_currentTD.pStatusBlock = NULL;
  682. }
  683. }
  684. /*******************************************************************************
  685. * Function Name: USBFS_InitializeStatusBlock
  686. ********************************************************************************
  687. *
  688. * Summary:
  689. * Initialize the Completion Status Block for a Request. The completion
  690. * code is set to USB_XFER_IDLE.
  691. *
  692. * Also, initializes USBFS_transferByteCount. Save some space,
  693. * this is the only consumer.
  694. *
  695. * Parameters:
  696. * None.
  697. *
  698. * Return:
  699. * None.
  700. *
  701. * Global variables:
  702. * USBFS_currentTD.pStatusBlock->status - set to XFER_IDLE.
  703. * USBFS_currentTD.pStatusBlock->length - cleared.
  704. * USBFS_transferByteCount - cleared.
  705. *
  706. * Reentrant:
  707. * No.
  708. *
  709. *******************************************************************************/
  710. void USBFS_InitializeStatusBlock(void)
  711. {
  712. USBFS_transferByteCount = 0u;
  713. if(USBFS_currentTD.pStatusBlock != NULL)
  714. {
  715. USBFS_currentTD.pStatusBlock->status = USBFS_XFER_IDLE;
  716. USBFS_currentTD.pStatusBlock->length = 0u;
  717. }
  718. }
  719. /* [] END OF FILE */