/firmware/rx62n/src/usb/usb_hal.c

https://bitbucket.org/monami_ya/cdclink · C · 2360 lines · 1097 code · 295 blank · 968 comment · 196 complexity · 2ec3cffce80a4397898358c6a5a80383 MD5 · raw file

  1. /*******************************************************************************
  2. * DISCLAIMER
  3. * This software is supplied by Renesas Electronics Corporation and is only
  4. * intended for use with Renesas products. No other uses are authorized. This
  5. * software is owned by Renesas Electronics Corporation and is protected under
  6. * all applicable laws, including copyright laws.
  7. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
  8. * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
  9. * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
  10. * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
  11. * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
  12. * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
  13. * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
  14. * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
  15. * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  16. * Renesas reserves the right, without notice, to make changes to this software
  17. * and to discontinue the availability of this software. By using this software,
  18. * you agree to the additional terms and conditions found by accessing the
  19. * following link:
  20. * http://www.renesas.com/disclaimer
  21. *******************************************************************************/
  22. /* Copyright (C) 2010 Renesas Electronics Corporation. All rights reserved. */
  23. /**********************************************************************
  24. * File Name : USB_HAL.c
  25. * Version : 1.00
  26. * Device : R5F562N8
  27. * Tool Chain : RX Family C Compiler
  28. * H/W Platform : RSKRX62N
  29. * Description : Hardware Abstraction Layer (HAL)
  30. Provides a hardware independent API to the USB peripheral
  31. on the RX62N.
  32. Supports:-
  33. Control IN, Control OUT, Bulk IN, Bulk OUT and Interrupt IN.
  34. **********************************************************************/
  35. /**********************************************************************
  36. * History : 27.07.2010 Ver. 1.00 First Release
  37. **********************************************************************/
  38. /*********************************************************************
  39. System Includes
  40. **********************************************************************/
  41. #include <stdio.h> //NULL (n.k)
  42. //#include <assert.h>
  43. /**********************************************************************
  44. User Includes (Project level includes)
  45. **********************************************************************/
  46. #include "usb_common.h"
  47. #include "iodefine.h"
  48. #include "usb_hal.h"
  49. //#include "itron.h"
  50. #include "usb_hal.h"
  51. #include "usb_core.h"
  52. #include "cdc/usb_cdc.h"
  53. /**********************************************************************
  54. System Definitions & Global Variables
  55. **********************************************************************/
  56. /*PID Values*/
  57. #define PID_NAK 0
  58. #define PID_BUF 1
  59. #define PID_STALL_1 2
  60. #define PID_STALL_2 3
  61. static uint16_t int_sts0;
  62. /***********************************************************************
  63. Type Definitions
  64. ***********************************************************************/
  65. /*Call Backs Registered by USB Core*/
  66. typedef struct CBs
  67. {
  68. CB_SETUP fpSetup;
  69. CB_CABLE fpCable;
  70. CB_ERROR fpError;
  71. }CBs;
  72. /*General purpose buffer*/
  73. typedef struct DataBuff
  74. {
  75. uint8_t* pucBuf;
  76. uint32_t NumBytes;
  77. }DataBuff;
  78. /*State of control pipe*/
  79. typedef enum StateControl
  80. {
  81. STATE_READY,
  82. STATE_DISCONNECTED,
  83. STATE_CONTROL_SETUP,
  84. STATE_CONTROL_IN,
  85. STATE_CONTROL_OUT
  86. }StateControl;
  87. /*Data structure used for OUT*/
  88. typedef struct OUT
  89. {
  90. uint32_t m_BuffSize;
  91. DataBuff m_DataBuff;
  92. CB_DONE_OUT m_fpDone;
  93. }OUT;
  94. /*Data structure used for IN*/
  95. typedef struct IN
  96. {
  97. DataBuff m_DataBuff;
  98. CB_DONE m_fpDone;
  99. }IN;
  100. /*Data structure used for Control*/
  101. typedef struct CONTROL
  102. {
  103. StateControl m_etState;
  104. IN m_IN;
  105. OUT m_OUT;
  106. }CONTROL;
  107. /*Data structure used for Bulk*/
  108. typedef struct BULK
  109. {
  110. /*Busy Flags*/
  111. bool m_INBusy;
  112. bool m_OUTBusy;
  113. IN m_IN;
  114. OUT m_OUT;
  115. }BULK;
  116. /*Data structure used for Interrupt*/
  117. typedef struct INTERRUPT
  118. {
  119. bool m_INBusy; /*Busy Flag*/
  120. IN m_IN;
  121. }INTERRUPT;
  122. /***********************************************************************
  123. Variables
  124. ***********************************************************************/
  125. /*Call Backs Registered by USB Core*/
  126. static volatile CBs g_CBs =
  127. {
  128. NULL,
  129. NULL,
  130. NULL,
  131. };
  132. /*Control Pipe Data*/
  133. static volatile CONTROL g_Control =
  134. {
  135. /*StateControl*/
  136. STATE_DISCONNECTED,
  137. /*IN*/
  138. {
  139. {NULL, 0}, /*DataBuff*/
  140. NULL /*CB (NOT USED)*/
  141. }
  142. ,
  143. /*OUT*/
  144. {
  145. 0, /*DataBuffSize*/
  146. {NULL, 0}, /*DataBuff*/
  147. NULL /*CB*/
  148. }
  149. };
  150. /*BULK Pipe Data*/
  151. static volatile BULK g_Bulk =
  152. {
  153. false, false, /*Busy Flags*/
  154. /*IN*/
  155. {
  156. {NULL, 0}, /*DataBuff*/
  157. NULL /*CB*/
  158. }
  159. ,
  160. /*OUT*/
  161. {
  162. 0, /*DataBuffSize*/
  163. {NULL, 0}, /*DataBuff*/
  164. NULL /*CB*/
  165. }
  166. };
  167. /*INTERRUPT Pipe Data*/
  168. static volatile INTERRUPT g_Int =
  169. {
  170. false, /*Busy Flag*/
  171. /*IN*/
  172. {
  173. {NULL, 0}, /*DataBuff*/
  174. NULL /*CB*/
  175. }
  176. };
  177. static USBHAL_CONFIG g_Config =
  178. {
  179. false, /*m_bBULK_IN_No_Short_Packet*/
  180. true /*m_bAutoStallClear*/
  181. };
  182. /***********************************************************************
  183. Private Function Prototypes
  184. ***********************************************************************/
  185. /*Initialisation*/
  186. /*static*/ void HW_Init(void); //for debug (n.k)
  187. static void ConfigurePipes(void);
  188. static void SetDefaultInterrupts(void);
  189. /*Operations*/
  190. static void WriteControlINPacket(void);
  191. static void WriteBulkINPacket(void);
  192. static void WriteIntINPacket(void);
  193. static void ReadControlOUTPacket(void);
  194. static void ReadBulkOUTPacket(void);
  195. /*Interrupt Handlers*/
  196. static void HandleVBus(void);
  197. static void HandleDVST(void);
  198. static void HandleCTRT(void);
  199. static void HandleBEMP(void);
  200. static void HandleBRDY(void);
  201. /*Not direct interrupt handlers*/
  202. static void HandleSetupCmd(void);
  203. /*Set the USB module IO access define based on selected USB Module.
  204. All access to USB peripheral registers is made through this.*/
  205. #ifndef USB_MODULE_0
  206. #ifndef USB_MODULE_1
  207. #error "No USB Module defined"
  208. #endif
  209. #endif
  210. #ifdef USB_MODULE_0
  211. #ifdef USB_MODULE_1
  212. #error "Both USB Module defined"
  213. #endif
  214. #endif
  215. #ifdef USB_MODULE_1
  216. /*NOTE USB1 is defined in iodefine.h file*/
  217. #define USBIO USB1
  218. /*HW Initalisation for USB 1 function*/
  219. static void HW_Init_Module1(void);
  220. #else
  221. /*NOTE USB0 is defined in iodefine.h file*/
  222. #define USBIO USB0
  223. /*HW Initalisation for USB 0 function*/
  224. static void HW_Init_Module0(void);
  225. #endif
  226. /**********************************************************************
  227. Function implementation
  228. ***********************************************************************/
  229. /*TODO Note: When RPDL is complete move this into RPDL Interrupt_not_RPDL.c file.*/
  230. /*Interrupt handlers*/
  231. //#pragma interrupt Interrupt_USBIO(vect=38)
  232. //void Interrupt_USBIO(void)
  233. void INT_Excep_USB0_USBI0 (void) __attribute__((interrupt));
  234. void INT_Excep_USB0_USBI0 (void)
  235. {
  236. USBHALInterruptHandler();
  237. }
  238. #if 0
  239. #pragma interrupt Interrupt_USBI1(vect=42)
  240. void Interrupt_USBI1(void)
  241. {
  242. USBHALInterruptHandler();
  243. }
  244. #endif
  245. /**********************************************************************
  246. * Outline : USBHAL_Init
  247. * Description : Initilaises this USB HAL layer.
  248. * This must be called before using any other function.
  249. * Enables the USB perhipheral ready for enumeration.
  250. *
  251. * Argument : _fpSetup: Callback function, Setup Packet received.
  252. * _fpCable: Callback function, Cable Connected/
  253. Disconnected.
  254. * _fpError: Callback function, Error occoured.
  255. *
  256. * Return value : Error code.
  257. **********************************************************************/
  258. USB_ERR USBHAL_Init(CB_SETUP _fpSetup, CB_CABLE _fpCable,
  259. CB_ERROR _fpError)
  260. {
  261. USB_ERR err = USB_ERR_OK;
  262. /*Check parameters are not NULL*/
  263. if( (NULL == _fpSetup) ||
  264. (NULL == _fpCable) ||
  265. (NULL == _fpError) )
  266. {
  267. err = USB_ERR_PARAM;
  268. }
  269. else
  270. {
  271. /*Store CallBack function pointers*/
  272. g_CBs.fpSetup = _fpSetup;
  273. g_CBs.fpCable = _fpCable;
  274. g_CBs.fpError = _fpError;
  275. }
  276. if(USB_ERR_OK == err)
  277. {
  278. /*Initialise the USB module.
  279. This includes enabling USB interrupts*/
  280. HW_Init();
  281. }
  282. return err;
  283. }
  284. /***********************************************************************************
  285. End of function USBHAL_Init
  286. ***********************************************************************************/
  287. /**********************************************************************
  288. * Outline : USBHAL_Disable
  289. * Description : Disables the USB module.
  290. * Argument :
  291. * Return value : Error code.
  292. **********************************************************************/
  293. USB_ERR USBHAL_Disable(void)
  294. {
  295. DEBUG_MSG_MID(("USBHAL: - Disable\r\n"));
  296. /*Stop the selected USB module*/
  297. #ifdef USB_MODULE_1
  298. MSTP_USB1 = 1;
  299. #else
  300. MSTP_USB0 = 1;
  301. #endif
  302. return USB_ERR_OK;
  303. }
  304. /**********************************************************************
  305. End USBHAL_Disable function
  306. **********************************************************************/
  307. /**********************************************************************
  308. * Outline : USBHAL_Control_Status
  309. * Description : Send status stage of a control transfer.
  310. * This can happen following a setup that has
  311. * no data stage or following a data stage OUT.
  312. * packet.
  313. * Argument : none
  314. * Return value : Error code.
  315. **********************************************************************/
  316. USB_ERR USBHAL_Control_Status(void)
  317. {
  318. USB_ERR err = USB_ERR_OK;
  319. DEBUG_MSG_HIGH(("USBHAL: - Control Status\r\n"));
  320. /*Set CCPL to 1 - this will cause module to automatically handle the status stage.
  321. i.e Sends ACK to host.*/
  322. /*Set PID to BUF before setting CCPL*/
  323. USBIO.DCPCTR.BIT.PID = PID_BUF;
  324. USBIO.DCPCTR.BIT.CCPL = 1;
  325. if(STATE_CONTROL_SETUP == g_Control.m_etState)
  326. {
  327. /*This is the status stage (ACK)
  328. at the end of a Control transfer with no data stage.*/
  329. g_Control.m_etState = STATE_READY;
  330. }
  331. return err;
  332. }
  333. /**********************************************************************
  334. End USBHAL_Control_Status function
  335. **********************************************************************/
  336. /**********************************************************************
  337. * Outline : USBHAL_Control_IN
  338. * Description : Sends supplied data to host and then handles
  339. * recieving Status response from host.
  340. * Note: This must only be called in response to a setup
  341. * packet.
  342. *
  343. * Note: Often Windows interrupts this ControlIN with
  344. * another setup packet - so this may not get all sent.
  345. *
  346. * Argument : _NumBytes: Number of bytes to send.
  347. * _Buffer: Data Buffer.
  348. * Return value : Error code.
  349. **********************************************************************/
  350. USB_ERR USBHAL_Control_IN(uint16_t _NumBytes, const uint8_t* _Buffer)
  351. {
  352. USB_ERR err = USB_ERR_OK;
  353. /*Check state*/
  354. if(g_Control.m_etState != STATE_CONTROL_SETUP)
  355. {
  356. /*State error - didn't expect this now*/
  357. err = USB_ERR_STATE;
  358. DEBUG_MSG_LOW(("USBHAL: Control IN State Error\r\n"));
  359. }
  360. else
  361. {
  362. g_Control.m_etState = STATE_CONTROL_IN;
  363. DEBUG_MSG_MID(("USBHAL: CONTROL IN start, %u bytes.\r\n", _NumBytes));
  364. /*Setup data buffer*/
  365. g_Control.m_IN.m_DataBuff.pucBuf = (uint8_t*)_Buffer;
  366. g_Control.m_IN.m_DataBuff.NumBytes = _NumBytes;
  367. /*Send Data*/
  368. WriteControlINPacket();
  369. /*Expect to get BEMP interrupt*/
  370. }
  371. return err;
  372. }
  373. /**********************************************************************
  374. End USBHAL_Control_IN function
  375. **********************************************************************/
  376. /**********************************************************************
  377. * Outline : USBHAL_Control_OUT
  378. * Description : This sets up the HAL to receive CONTROL OUT
  379. * data from the host and to then send a Status ACK.
  380. *
  381. * If a short packet is received before _NumBytes
  382. * have been read then this will finish. The actual
  383. * number of bytes read will be specified in the CallBack.
  384. *
  385. * Note: This must only be called in response to a setup
  386. * packet.
  387. *
  388. * Argument : _NumBytes: Number of bytes to receive.
  389. * _Buffer: Data Buffer.
  390. * _CBDone: Callback called when OUT has completed.
  391. * Return value : Error code.
  392. **********************************************************************/
  393. USB_ERR USBHAL_Control_OUT(uint16_t _NumBytes, uint8_t* _Buffer,
  394. CB_DONE_OUT _CBDone)
  395. {
  396. USB_ERR err = USB_ERR_OK;
  397. /*Check state*/
  398. if(g_Control.m_etState != STATE_CONTROL_SETUP)
  399. {
  400. /*State error - didn't expect this now*/
  401. err = USB_ERR_STATE;
  402. DEBUG_MSG_LOW(("USBHAL: Control OUT State Error\r\n"));
  403. }
  404. else
  405. {
  406. g_Control.m_etState = STATE_CONTROL_OUT;
  407. DEBUG_MSG_MID(("USBHAL: CONTROL OUT start, %u bytes.\r\n", _NumBytes));
  408. /*Store parameters*/
  409. g_Control.m_OUT.m_DataBuff.pucBuf = _Buffer;
  410. /*Number of bytes received into buffer */
  411. g_Control.m_OUT.m_DataBuff.NumBytes = 0;
  412. g_Control.m_OUT.m_BuffSize = _NumBytes;
  413. g_Control.m_OUT.m_fpDone = _CBDone;
  414. /*Setup CFIFO to receive data, select DCP (Default Control Pipe)*/
  415. USBIO.CFIFOSEL.BIT.CURPIPE = 0;
  416. /*Set PID = BUF*/
  417. USBIO.DCPCTR.BIT.PID = PID_BUF;
  418. /*Enable BRDY interrupt for Control pipe - will get interrupt
  419. when data is received.*/
  420. USBIO.BRDYENB.BIT.PIPE0BRDYE = 1;
  421. }
  422. return err;
  423. }
  424. /**********************************************************************
  425. End USBHAL_Control_OUT function
  426. **********************************************************************/
  427. /**********************************************************************
  428. * Outline : USBHAL_Bulk_OUT
  429. * Description : This sets up the HAL to receives BULK OUT
  430. * data from the host.
  431. *
  432. * If a short packet is received before _NumBytes
  433. * have been read then this will finish. The actual
  434. * number of bytes read will be specified in the CB.
  435. *
  436. * Argument : _NumBytes: Number of bytes to receive.
  437. * _Buffer: Data Buffer.
  438. * _CBDone: Callback called when OUT has completed.
  439. * Return value : Error code.
  440. **********************************************************************/
  441. USB_ERR USBHAL_Bulk_OUT(uint32_t _NumBytes, uint8_t* _Buffer,
  442. CB_DONE_OUT _CBDone)
  443. {
  444. USB_ERR err = USB_ERR_OK;
  445. /*Check cable is connected*/
  446. if(STATE_DISCONNECTED == g_Control.m_etState)
  447. {
  448. err = USB_ERR_NOT_CONNECTED;
  449. DEBUG_MSG_MID(("USBHAL: BULK OUT - Not Connected\r\n"));
  450. }
  451. else
  452. {
  453. /*Check BULK IN isn't busy*/
  454. if(true == g_Bulk.m_OUTBusy)
  455. {
  456. /*Error - already busy*/
  457. err = USB_ERR_BUSY;
  458. DEBUG_MSG_LOW(("USBHAL: BULK OUT ***BUSY***\r\n"));
  459. }
  460. else
  461. {
  462. /*Set busy flag*/
  463. g_Bulk.m_OUTBusy = true;
  464. DEBUG_MSG_MID(("USBHAL: BULK OUT start, %lu bytes.\r\n", _NumBytes));
  465. /*Store parameters*/
  466. g_Bulk.m_OUT.m_DataBuff.pucBuf = _Buffer;
  467. /*Number of bytes received into buffer */
  468. g_Bulk.m_OUT.m_DataBuff.NumBytes = 0;
  469. g_Bulk.m_OUT.m_BuffSize = _NumBytes;
  470. g_Bulk.m_OUT.m_fpDone = _CBDone;
  471. /*Expect to get a BRDY interrupt when data is received*/
  472. }
  473. }
  474. return err;
  475. }
  476. /**********************************************************************
  477. End USBHAL_Bulk_OUT function
  478. **********************************************************************/
  479. /**********************************************************************
  480. * Outline : USBHAL_Bulk_IN
  481. * Description : Sends supplied data to host using BULK IN
  482. * and then calls specified callback.
  483. * Argument : _NumBytes: Number of bytes to receive.
  484. * _Buffer: Data Buffer.
  485. * _CBDone: Callback called when IN has completed.
  486. *
  487. * Return value : Error code.
  488. **********************************************************************/
  489. USB_ERR USBHAL_Bulk_IN(uint32_t _NumBytes, const uint8_t* _Buffer, CB_DONE _CBDone)
  490. {
  491. USB_ERR err = USB_ERR_OK;
  492. /*Check cable is connected*/
  493. if(STATE_DISCONNECTED == g_Control.m_etState)
  494. {
  495. err = USB_ERR_NOT_CONNECTED;
  496. DEBUG_MSG_MID(("USBHAL: BULK IN - Not Connected\r\n"));
  497. }
  498. else
  499. {
  500. /*Check BULK IN isn't busy*/
  501. if(true == g_Bulk.m_INBusy)
  502. {
  503. /*Error - already busy*/
  504. err = USB_ERR_BUSY;
  505. DEBUG_MSG_LOW(("USBHAL: BULK IN ***BUSY***\r\n"));
  506. }
  507. else
  508. {
  509. /*Set busy flag*/
  510. g_Bulk.m_INBusy = true;
  511. DEBUG_MSG_MID(("USBHAL: BULK IN start, %lu bytes.\r\n", _NumBytes));
  512. /*Setup data buffer*/
  513. g_Bulk.m_IN.m_DataBuff.pucBuf = (uint8_t*)_Buffer;
  514. g_Bulk.m_IN.m_DataBuff.NumBytes = _NumBytes;
  515. g_Bulk.m_IN.m_fpDone = _CBDone;
  516. /*Write packet. Do this be enabling BRDY interrupt for BULK IN pipe.
  517. The actual packet will be written out when get the BRDY interrupt.*/
  518. USBIO.BRDYENB.BIT.PIPE2BRDYE = 1;
  519. }
  520. }
  521. return err;
  522. }
  523. /**********************************************************************
  524. End USBHAL_Bulk_IN function
  525. **********************************************************************/
  526. /**********************************************************************
  527. * Outline : USBHAL_Interrupt_IN
  528. * Description : Sends supplied data to host using INTERRUPT IN
  529. * and then calls specified callback.
  530. * Argument : _NumBytes: Number of bytes to receive.
  531. * _Buffer: Data Buffer.
  532. * _CBDone: Callback called when IN has completed.
  533. *
  534. * Return value : Error code.
  535. **********************************************************************/
  536. USB_ERR USBHAL_Interrupt_IN(uint32_t _NumBytes,
  537. const uint8_t* _Buffer, CB_DONE _CBDone)
  538. {
  539. USB_ERR err = USB_ERR_OK;
  540. /*Check cable is connected*/
  541. if(STATE_DISCONNECTED == g_Control.m_etState)
  542. {
  543. err = USB_ERR_NOT_CONNECTED;
  544. DEBUG_MSG_MID(("USBHAL: INT IN - Not Connected\r\n"));
  545. }
  546. else
  547. {
  548. /*Check Interrupt IN isn't busy*/
  549. if(true == g_Int.m_INBusy)
  550. {
  551. /*Error - already busy*/
  552. err = USB_ERR_BUSY;
  553. DEBUG_MSG_LOW(("USBHAL: INTERRUPT IN ***BUSY***\r\n"));
  554. }
  555. else
  556. {
  557. /*Set busy flag*/
  558. g_Int.m_INBusy = true;
  559. DEBUG_MSG_MID(("USBHAL: INT IN start, %lu bytes.\r\n", _NumBytes));
  560. /*Setup data buffer*/
  561. g_Int.m_IN.m_DataBuff.pucBuf = (uint8_t*)_Buffer;
  562. g_Int.m_IN.m_DataBuff.NumBytes = _NumBytes;
  563. g_Int.m_IN.m_fpDone = _CBDone;
  564. /*Write packet. Do this be enabling BRDY interrupt for INTERRUPT IN pipe.
  565. The actual packet will be written out when get the BRDY interrupt.*/
  566. USBIO.BRDYENB.BIT.PIPE6BRDYE = 1;
  567. }
  568. }
  569. return err;
  570. }
  571. /**********************************************************************
  572. End USBHAL_Interrupt_IN function
  573. **********************************************************************/
  574. /**********************************************************************
  575. * Outline : USBHAL_Control_Stall
  576. * Description : Generate a stall on the Control Endpoint and then
  577. * automatically clears it.
  578. * Argument : none
  579. * Return value : none
  580. **********************************************************************/
  581. void USBHAL_Control_Stall(void)
  582. {
  583. DEBUG_MSG_MID(("USBHAL: - Control_Stall\r\n"));
  584. /*There are two ways of creating a stall depending on current PID*/
  585. if(USBIO.DCPCTR.BIT.PID == PID_NAK)
  586. {
  587. USBIO.DCPCTR.BIT.PID = PID_STALL_1;
  588. }
  589. else if(USBIO.DCPCTR.BIT.PID == PID_BUF)
  590. {
  591. USBIO.DCPCTR.BIT.PID = PID_STALL_2;
  592. }
  593. }
  594. /**********************************************************************
  595. End USBHAL_Control_Stall function
  596. **********************************************************************/
  597. /**********************************************************************
  598. * Outline : USBHAL_Bulk_IN_Stall
  599. * Description : Generate a stall on the BULK IN Endpoint.
  600. * Argument : none
  601. * Return value : none
  602. **********************************************************************/
  603. void USBHAL_Bulk_IN_Stall(void)
  604. {
  605. DEBUG_MSG_MID(("USBHAL: - Bulk_IN_Stall\r\n"));
  606. /*There are two ways of creating a stall depending on current PID*/
  607. if(USBIO.PIPE2CTR.BIT.PID == PID_BUF)
  608. {
  609. USBIO.PIPE2CTR.BIT.PID = PID_STALL_2;
  610. }
  611. else
  612. {
  613. USBIO.PIPE2CTR.BIT.PID = PID_STALL_1;
  614. }
  615. }
  616. /**********************************************************************
  617. End USBHAL_Bulk_IN_Stall function
  618. **********************************************************************/
  619. /**********************************************************************
  620. * Outline : USBHAL_Bulk_OUT_Stall
  621. * Description : Generate a stall on the BULK OUT Endpoint.
  622. * Argument : none
  623. * Return value : none
  624. **********************************************************************/
  625. void USBHAL_Bulk_OUT_Stall(void)
  626. {
  627. DEBUG_MSG_MID(("USBHAL: - Bulk_OUT_Stall\r\n"));
  628. /*There are two ways of creating a stall depending on current PID*/
  629. if(USBIO.PIPE1CTR.BIT.PID == PID_BUF)
  630. {
  631. USBIO.PIPE1CTR.BIT.PID = PID_STALL_2;
  632. }
  633. else
  634. {
  635. USBIO.PIPE1CTR.BIT.PID = PID_STALL_1;
  636. }
  637. }
  638. /**********************************************************************
  639. End USBHAL_Bulk_OUT_Stall function
  640. **********************************************************************/
  641. /**********************************************************************
  642. * Outline : USBHAL_Interrupt_IN_Stall
  643. * Description : Generate a stall on the Interrupt IN Endpoint.
  644. * Argument : none
  645. * Return value : none
  646. **********************************************************************/
  647. void USBHAL_Interrupt_IN_Stall(void)
  648. {
  649. DEBUG_MSG_MID(("USBHAL: - Interrupt_IN_Stall\r\n"));
  650. /*There are two ways of creating a stall depending on current PID*/
  651. if(USBIO.PIPE6CTR.BIT.PID == PID_BUF)
  652. {
  653. USBIO.PIPE6CTR.BIT.PID = PID_STALL_2;
  654. }
  655. else
  656. {
  657. USBIO.PIPE6CTR.BIT.PID = PID_STALL_1;
  658. }
  659. }
  660. /**********************************************************************
  661. End USBHAL_Interrupt_IN_Stall function
  662. **********************************************************************/
  663. /**********************************************************************
  664. * Outline : USBHAL_Bulk_IN_Stall_Clear
  665. * Description : Clear a stall on the BULK IN Endpoint.
  666. * Also reset data toggle and clear buffer.
  667. * Argument : none
  668. * Return value : none
  669. **********************************************************************/
  670. void USBHAL_Bulk_IN_Stall_Clear(void)
  671. {
  672. DEBUG_MSG_MID(("USBHAL: - Bulk_IN_Stall Clear\r\n"));
  673. USBIO.PIPE2CTR.BIT.PID = PID_NAK;
  674. /*Wait for pipe to be not busy*/
  675. while(USBIO.PIPE2CTR.BIT.PBUSY == 1){;}
  676. /*Reset Data toggle*/
  677. USBIO.PIPE2CTR.BIT.SQCLR = 1;
  678. /*Clear Buffer*/
  679. USBIO.PIPE2CTR.BIT.ACLRM = 1;
  680. USBIO.PIPE2CTR.BIT.ACLRM = 0;
  681. }
  682. /**********************************************************************
  683. End USBHAL_Bulk_IN_Stall_Clear function
  684. **********************************************************************/
  685. /**********************************************************************
  686. * Outline : USBHAL_Bulk_OUT_Stall_Clear
  687. * Description : Clear a stall on the BULK OUT Endpoint.
  688. * Also reset data toggle and clear buffer.
  689. * Argument : none
  690. * Return value : none
  691. **********************************************************************/
  692. void USBHAL_Bulk_OUT_Stall_Clear(void)
  693. {
  694. DEBUG_MSG_MID(("USBHAL: - Bulk_OUT_Stall Clear\r\n"));
  695. /*Pipe must not be "curpipe" while being configured.*/
  696. USBIO.D1FIFOSEL.BIT.CURPIPE = 0;
  697. /*PID must be set to NAK before configuring PIPECFG*/
  698. USBIO.PIPE1CTR.BIT.PID = PID_NAK;
  699. /*Wait for pipe to be not busy*/
  700. while(USBIO.PIPE1CTR.BIT.PBUSY == 1){;}
  701. /*Reset Data toggle*/
  702. USBIO.PIPE1CTR.BIT.SQCLR = 1;
  703. /*Clear Buffer*/
  704. USBIO.PIPE1CTR.BIT.ACLRM = 1;
  705. USBIO.PIPE1CTR.BIT.ACLRM = 0;
  706. /*Set PID to BUF for this OUT pipe*/
  707. USBIO.PIPE1CTR.BIT.PID = PID_BUF;
  708. /*Re-select this pipe for D1FIFO*/
  709. USBIO.D1FIFOSEL.BIT.CURPIPE = PIPE_BULK_OUT;
  710. }
  711. /**********************************************************************
  712. End USBHAL_Bulk_OUT_Stall_Clear function
  713. **********************************************************************/
  714. /**********************************************************************
  715. * Outline : USBHAL_Interrupt_IN_Stall_Clear
  716. * Description : Clear a stall on the Interrupt IN Endpoint.
  717. * Also reset data toggle and clear buffer.
  718. * Argument : none
  719. * Return value : none
  720. **********************************************************************/
  721. void USBHAL_Interrupt_IN_Stall_Clear(void)
  722. {
  723. DEBUG_MSG_MID(("USBHAL: - Interrupt_IN_Stall Clear\r\n"));
  724. USBIO.PIPE6CTR.BIT.PID = PID_NAK;
  725. /*Wait for pipe to be not busy*/
  726. while(USBIO.PIPE6CTR.BIT.PBUSY == 1){;}
  727. /*Reset Data toggle*/
  728. USBIO.PIPE6CTR.BIT.SQCLR = 1;
  729. /*Clear Buffer*/
  730. USBIO.PIPE6CTR.BIT.ACLRM = 1;
  731. USBIO.PIPE6CTR.BIT.ACLRM = 0;
  732. }
  733. /**********************************************************************
  734. End USBHAL_Interrupt_IN_Stall_Clear function
  735. **********************************************************************/
  736. /**********************************************************************
  737. * Outline : USBHAL_Bulk_IN_Is_Stalled
  738. * Description : Returns true if the endpoint is stalled.
  739. * Argument : none
  740. * Return value : true: Endpoint is stalled.
  741. **********************************************************************/
  742. bool USBHAL_Bulk_IN_Is_Stalled(void)
  743. {
  744. if( (USBIO.PIPE2CTR.BIT.PID == PID_STALL_1) ||
  745. (USBIO.PIPE2CTR.BIT.PID == PID_STALL_2))
  746. {
  747. return true;
  748. }
  749. else
  750. {
  751. return false;
  752. }
  753. }
  754. /**********************************************************************
  755. End USBHAL_Bulk_IN_Is_Stalled function
  756. **********************************************************************/
  757. /**********************************************************************
  758. * Outline : USBHAL_Bulk_OUT_Is_Stalled
  759. * Description : Returns true if the endpoint is stalled.
  760. * Argument : none
  761. * Return value : true: Endpoint is stalled.
  762. **********************************************************************/
  763. bool USBHAL_Bulk_OUT_Is_Stalled(void)
  764. {
  765. if( (USBIO.PIPE1CTR.BIT.PID == PID_STALL_1) ||
  766. (USBIO.PIPE1CTR.BIT.PID == PID_STALL_2))
  767. {
  768. return true;
  769. }
  770. else
  771. {
  772. return false;
  773. }
  774. }
  775. /**********************************************************************
  776. End USBHAL_Bulk_OUT_Is_Stalled function
  777. **********************************************************************/
  778. /**********************************************************************
  779. * Outline : USBHAL_Interrupt_IN_Is_Stalled
  780. * Description : Returns true if the endpoint is stalled.
  781. * Argument : none
  782. * Return value : true: Endpoint is stalled.
  783. **********************************************************************/
  784. bool USBHAL_Interrupt_IN_Is_Stalled(void)
  785. {
  786. if( (USBIO.PIPE6CTR.BIT.PID == PID_STALL_1) ||
  787. (USBIO.PIPE6CTR.BIT.PID == PID_STALL_2))
  788. {
  789. return true;
  790. }
  791. else
  792. {
  793. return false;
  794. }
  795. }
  796. /**********************************************************************
  797. End USBHAL_Interrupt_IN_Is_Stalled function
  798. **********************************************************************/
  799. /**********************************************************************
  800. * Outline : USBHAL_Config_Get
  801. * Description : Gets the current HAL configuration.
  802. * Argument : none
  803. * Return value : Configuration structure.
  804. **********************************************************************/
  805. const USBHAL_CONFIG* USBHAL_Config_Get(void)
  806. {
  807. return (const USBHAL_CONFIG*)&g_Config;
  808. }
  809. /**********************************************************************
  810. End USBHAL_Config_Get function
  811. **********************************************************************/
  812. /**********************************************************************
  813. * Outline : USBHAL_Config_Set
  814. * Description : Sets the HAL configuration.
  815. * This only need to be used if the default configuration
  816. * is not suitable.
  817. * Argument : _pConfig: New Configuration.
  818. * Return value : Error code
  819. **********************************************************************/
  820. USB_ERR USBHAL_Config_Set(USBHAL_CONFIG* _pConfig)
  821. {
  822. g_Config = *_pConfig;
  823. return USB_ERR_OK;
  824. }
  825. /**********************************************************************
  826. End USBHAL_Config_Set function
  827. **********************************************************************/
  828. /**********************************************************************
  829. * Outline : USBHAL_Cancel
  830. * Description : Cancel any current operations.
  831. * Perform a HAL reset.
  832. * Any pending "Done" callbacks will then be called with
  833. * supplied error code.
  834. *
  835. * Note: This is automatically called when the cable
  836. * is disconnected.
  837. *
  838. * Argument : _err: Error code to complete callbacks with.
  839. * Return value : Error code.
  840. **********************************************************************/
  841. USB_ERR USBHAL_Cancel(USB_ERR _err)
  842. {
  843. USB_ERR err = USB_ERR_OK;
  844. CB_DONE cbBulkIN;
  845. CB_DONE cbIntIN;
  846. CB_DONE_OUT cbBulkOUT;
  847. uint32_t NumBytesBulkOUT;
  848. DEBUG_MSG_MID( ("USBHAL: - Cancel called\r\n"));
  849. /*Copy callbacks as cleared in USBHAL_Reset*/
  850. cbBulkIN = g_Bulk.m_IN.m_fpDone;
  851. cbIntIN = g_Int.m_IN.m_fpDone;
  852. cbBulkOUT = g_Bulk.m_OUT.m_fpDone;
  853. /*For OUT also record bytes received so far*/
  854. NumBytesBulkOUT = g_Bulk.m_OUT.m_DataBuff.NumBytes;
  855. /*Reset HAL */
  856. err = USBHAL_Reset();
  857. /*Call any registered callbacks pending*/
  858. if((true == g_Bulk.m_INBusy) && (NULL != cbBulkIN))
  859. {
  860. cbBulkIN(_err);
  861. }
  862. if((true == g_Int.m_INBusy) && (NULL != cbIntIN))
  863. {
  864. cbIntIN(_err);
  865. }
  866. if((true == g_Bulk.m_OUTBusy) && (NULL != cbBulkOUT))
  867. {
  868. cbBulkOUT(_err, NumBytesBulkOUT);
  869. }
  870. return err;
  871. }
  872. /**********************************************************************
  873. End USBHAL_Cancel function
  874. **********************************************************************/
  875. /**********************************************************************
  876. * Outline : USBHAL_Reset
  877. * Description : Resets the HAL.
  878. * Resets the HAL to default state.
  879. *
  880. * Can be used after an unexpected error or when wanting to
  881. * cancel a pending operation where you don't want the
  882. * 'done' callbacks called.
  883. *
  884. * Note: Used internally to reset HAL after detecting the USB
  885. * cable has been disconnected/connected.
  886. * 1. Reset State and Busy flags and clear "done" CBs.
  887. * (CBs are not called!)
  888. * 2. Clear all buffers
  889. * 3. Clear stalls.
  890. * 4. Enable default interrupts.
  891. * Argument : none
  892. * Return value : Error code.
  893. **********************************************************************/
  894. USB_ERR USBHAL_Reset(void)
  895. {
  896. USB_ERR err = USB_ERR_OK;
  897. DEBUG_MSG_MID( ("USBHAL: - Resetting HAL\r\n"));
  898. /*If connected then go to ready state*/
  899. if(STATE_DISCONNECTED != g_Control.m_etState)
  900. {
  901. g_Control.m_etState = STATE_READY;
  902. }
  903. /*Reset busy flags*/
  904. g_Bulk.m_INBusy = false;
  905. g_Bulk.m_OUTBusy = false;
  906. g_Int.m_INBusy = false;
  907. /*Clear all buffers*/
  908. g_Control.m_IN.m_DataBuff.NumBytes = 0;
  909. g_Control.m_OUT.m_DataBuff.NumBytes = 0;
  910. g_Control.m_OUT.m_BuffSize = 0;
  911. g_Bulk.m_IN.m_DataBuff.NumBytes = 0;
  912. g_Bulk.m_OUT.m_DataBuff.NumBytes = 0;
  913. g_Bulk.m_OUT.m_BuffSize = 0;
  914. g_Int.m_IN.m_DataBuff.NumBytes = 0;
  915. /*Clear all "Done" CBs*/
  916. g_Control.m_IN.m_fpDone = NULL;
  917. g_Control.m_OUT.m_fpDone = NULL;
  918. g_Bulk.m_IN.m_fpDone = NULL;
  919. g_Bulk.m_OUT.m_fpDone = NULL;
  920. g_Int.m_IN.m_fpDone = NULL;
  921. /*Clear stalls (this also resets data toggle and clears buffers*/
  922. USBHAL_Bulk_OUT_Stall_Clear();
  923. USBHAL_Bulk_IN_Stall_Clear();
  924. USBHAL_Interrupt_IN_Stall_Clear();
  925. /*Return to the default interrupts*/
  926. SetDefaultInterrupts();
  927. return err;
  928. }
  929. /**********************************************************************
  930. End USBHAL_Reset function
  931. **********************************************************************/
  932. /**********************************************************************
  933. * Outline : USBHAL_ResetEndpoints
  934. * Description : Resets the data toggle bits and clears buffers.
  935. * Should be used following USB bus reset.
  936. * USB request.
  937. * Argument : none
  938. * Return value : Error code.
  939. **********************************************************************/
  940. USB_ERR USBHAL_ResetEndpoints(void)
  941. {
  942. /*** BULK OUT ***/
  943. /*Pipe must not be "curpipe" while being configured.*/
  944. USBIO.D1FIFOSEL.BIT.CURPIPE = 0;
  945. /*PID must be set to NAK before configuring PIPECFG*/
  946. USBIO.PIPE1CTR.BIT.PID = PID_NAK;
  947. /*Wait for pipe to be not busy*/
  948. while(USBIO.PIPE1CTR.BIT.PBUSY == 1){;}
  949. /*Reset Data toggle*/
  950. USBIO.PIPE1CTR.BIT.SQCLR = 1;
  951. /*Clear Buffer*/
  952. USBIO.PIPE1CTR.BIT.ACLRM = 1;
  953. USBIO.PIPE1CTR.BIT.ACLRM = 0;
  954. /*Set PID to BUF for this OUT pipe*/
  955. USBIO.PIPE1CTR.BIT.PID = PID_BUF;
  956. /*Re-select this pipe for D1FIFO and 16bit access.*/
  957. USBIO.D1FIFOSEL.BIT.MBW = 1;
  958. USBIO.D1FIFOSEL.BIT.CURPIPE = PIPE_BULK_OUT;
  959. /***BULK IN***/
  960. /*PID must be set to NAK before configuring PIPECFG*/
  961. USBIO.PIPE2CTR.BIT.PID = PID_NAK;
  962. /*Wait for pipe to be not busy*/
  963. while(USBIO.PIPE2CTR.BIT.PBUSY == 1){;}
  964. /*Reset Data toggle*/
  965. USBIO.PIPE2CTR.BIT.SQCLR = 1;
  966. /*Clear Buffer*/
  967. USBIO.PIPE2CTR.BIT.ACLRM = 1;
  968. USBIO.PIPE2CTR.BIT.ACLRM = 0;
  969. /***Interrupt IN***/
  970. /*PID must be set to NAK before configuring PIPECFG*/
  971. USBIO.PIPE6CTR.BIT.PID = PID_NAK;
  972. /*Wait for pipe to be not busy*/
  973. while(USBIO.PIPE6CTR.BIT.PBUSY == 1){;}
  974. /*Reset Data toggle*/
  975. USBIO.PIPE6CTR.BIT.SQCLR = 1;
  976. /*Clear Buffer*/
  977. USBIO.PIPE6CTR.BIT.ACLRM = 1;
  978. USBIO.PIPE6CTR.BIT.ACLRM = 0;
  979. return USB_ERR_OK;
  980. }
  981. /**********************************************************************
  982. End USBHAL_ResetEndpoints function
  983. **********************************************************************/
  984. /**********************************************************************
  985. * Outline : ReadBulkOUTPacket
  986. * Description : If a buffer has been setup for BULK OUT then
  987. * read data into the buffer.
  988. * If buffer is full or a short packet
  989. * is received then call the done callback.
  990. * If data is available but there is no buffer
  991. * setup for it then call the error callback.
  992. * Argument : none
  993. * Return value : none
  994. **********************************************************************/
  995. static void ReadBulkOUTPacket(void)
  996. {
  997. uint32_t Count = 0;
  998. uint16_t DataLength;
  999. volatile uint16_t dummy;
  1000. DEBUG_MSG_HIGH(("USBHAL: - ReadBulkOUTPacket\r\n"));
  1001. /*Read data using D1FIFO*/
  1002. /*NOTE: This probably will have already been selected if using BRDY interrupt.*/
  1003. USBIO.D1FIFOSEL.BIT.CURPIPE = PIPE_BULK_OUT;
  1004. /*Set PID to BUF*/
  1005. USBIO.PIPE1CTR.BIT.PID = PID_BUF;
  1006. /*Wait for buffer to be ready*/
  1007. while(USBIO.D1FIFOCTR.BIT.FRDY == 0){;}
  1008. /*Set Read Count Mode - so DTLN count will decrement as data read from buffer*/
  1009. USBIO.D1FIFOSEL.BIT.RCNT = 1;
  1010. /*Read length of data */
  1011. DataLength = USBIO.D1FIFOCTR.BIT.DTLN;
  1012. /*Read data while there is data in the FIFO and
  1013. room in buffer to store it in.*/
  1014. while((DataLength != 0) &&
  1015. (g_Bulk.m_OUT.m_BuffSize > g_Bulk.m_OUT.m_DataBuff.NumBytes))
  1016. {
  1017. /*If there is at least 2 bytes to read and at least 2 bytes storage in the buffer
  1018. then read 2 bytes with single 16bit access */
  1019. if((DataLength >= 2) &&
  1020. (g_Bulk.m_OUT.m_BuffSize >= (g_Bulk.m_OUT.m_DataBuff.NumBytes+2)))
  1021. {
  1022. /*Read from the FIFO*/
  1023. uint16_t Data = USBIO.D1FIFO.WORD;
  1024. if(NULL != g_Bulk.m_OUT.m_DataBuff.pucBuf)
  1025. {
  1026. /*Save data to buffer*/
  1027. /*Save first byte*/
  1028. *g_Bulk.m_OUT.m_DataBuff.pucBuf = (uint8_t)Data;
  1029. g_Bulk.m_OUT.m_DataBuff.pucBuf++;
  1030. /*Save second byte*/
  1031. *g_Bulk.m_OUT.m_DataBuff.pucBuf = (uint8_t)(Data>>8);
  1032. g_Bulk.m_OUT.m_DataBuff.pucBuf++;
  1033. }
  1034. else
  1035. {
  1036. /*Bulk out was set up to read data but throw it away*/
  1037. //volatile uint16_t
  1038. dummy = USBIO.D1FIFO.WORD;
  1039. }
  1040. /*Update counts*/
  1041. g_Bulk.m_OUT.m_DataBuff.NumBytes+=2;
  1042. DataLength-=2;
  1043. Count+=2;
  1044. }
  1045. else
  1046. {
  1047. /*The last byte.
  1048. This is written to the Least Significant Byte of 16bit FIFO*/
  1049. if(g_Bulk.m_OUT.m_DataBuff.pucBuf != NULL)
  1050. {
  1051. *g_Bulk.m_OUT.m_DataBuff.pucBuf = (uint8_t)USBIO.D1FIFO.BYTE.L;
  1052. g_Bulk.m_OUT.m_DataBuff.pucBuf++;
  1053. }
  1054. else
  1055. {
  1056. /*Bulk out was set up to read data but throw it away*/
  1057. //volatile uint8_t
  1058. dummy = (uint8_t)USBIO.D1FIFO.BYTE.L;
  1059. }
  1060. g_Bulk.m_OUT.m_DataBuff.NumBytes++;
  1061. DataLength--;
  1062. Count++;
  1063. }
  1064. }
  1065. /*Have we completed the BULK OUT request?*/
  1066. /*If this wasn't a full packet or we have filled the buffer*/
  1067. /*Check BULK OUT has been setup*/
  1068. if(0 != g_Bulk.m_OUT.m_BuffSize)
  1069. {
  1070. if((g_Bulk.m_OUT.m_BuffSize == g_Bulk.m_OUT.m_DataBuff.NumBytes) ||
  1071. (Count != BULK_OUT_PACKET_SIZE))
  1072. {
  1073. CB_DONE_OUT CBTemp;
  1074. DEBUG_MSG_MID( ("USBHAL: - ReadBulkOUTPacket Done, %lu Bytes\r\n",
  1075. g_Bulk.m_OUT.m_DataBuff.NumBytes));
  1076. /*Buffer not valid anymore*/
  1077. g_Bulk.m_OUT.m_BuffSize = 0;
  1078. /*Before clearing busy flag copy CB.
  1079. NOTE Can't call CB before clearing flag as then CB
  1080. wouldn't be able to set up new request.*/
  1081. CBTemp = g_Bulk.m_OUT.m_fpDone;
  1082. /*Have finished this BULK OUT*/
  1083. g_Bulk.m_OUTBusy = false;
  1084. /*Call registered callback*/
  1085. if(CBTemp != NULL)
  1086. {
  1087. CBTemp(USB_ERR_OK, g_Bulk.m_OUT.m_DataBuff.NumBytes);
  1088. }
  1089. }
  1090. }
  1091. /*NOTE: In double buffer mode DTLN wil be updated with second buffers count.
  1092. Therefore only say error if we've not had a buffer available to at least
  1093. read somne data.*/
  1094. /*If data available and we've not got a buffer then call Error CallBack*/
  1095. if((Count == 0) && (0 != USBIO.D1FIFOCTR.BIT.DTLN))
  1096. {
  1097. /*No buffer available for BULK OUT*/
  1098. DEBUG_MSG_LOW(("USBHAL: ERROR, USB_ERR_BULK_OUT_NO_BUFFER\r\n"));
  1099. /*Call error callback*/
  1100. g_CBs.fpError(USB_ERR_BULK_OUT_NO_BUFFER);
  1101. /*Empty buffer*/
  1102. while(0 != USBIO.D1FIFOCTR.BIT.DTLN)
  1103. {
  1104. //volatile uint8_t
  1105. dummy = (uint8_t)USBIO.D1FIFO.BYTE.L;
  1106. }
  1107. }
  1108. (void)dummy;
  1109. }
  1110. /**********************************************************************
  1111. End ReadBulkOUTPacket function
  1112. **********************************************************************/
  1113. /**********************************************************************
  1114. * Outline : WriteIntINPacket
  1115. * Description : If the Interrupt IN buffer contains data then this will
  1116. * write it to the pipe buffer until either the packet
  1117. * is full or all the data has been written.
  1118. * This controls BRDY interrupt for the pipe to ensure all
  1119. * data is sent and that the transfer completes on a short packet.
  1120. * Argument : none
  1121. * Return value : none
  1122. **********************************************************************/
  1123. static void WriteIntINPacket(void)
  1124. {
  1125. uint32_t Count = 0;
  1126. /*Write data to Interrupt IN pipe using D0FIFO*/
  1127. /*Select Interrupt Pipe and use 8 bit access*/
  1128. USBIO.D0FIFOSEL.BIT.MBW = 0;
  1129. USBIO.D0FIFOSEL.BIT.CURPIPE = PIPE_INTERRUPT_IN;
  1130. /*Wait for buffer to be ready*/
  1131. while(USBIO.D0FIFOCTR.BIT.FRDY == 0){;}
  1132. /* Write data to the IN Fifo untill have written a full packet
  1133. or we have no more data to write */
  1134. while((Count < INTERRUPT_IN_PACKET_SIZE) &&
  1135. (g_Int.m_IN.m_DataBuff.NumBytes != 0))
  1136. {
  1137. /*For 8 bit access write only to low 8 bits of CFIFO.*/
  1138. USBIO.D0FIFO.BYTE.L = *g_Int.m_IN.m_DataBuff.pucBuf;
  1139. g_Int.m_IN.m_DataBuff.pucBuf++;
  1140. g_Int.m_IN.m_DataBuff.NumBytes--;
  1141. Count++;
  1142. }
  1143. DEBUG_MSG_HIGH(("USBHAL: INT IN - sending %lu, %lu remaining\r\n",
  1144. Count, g_Int.m_IN.m_DataBuff.NumBytes));
  1145. /*Send the packet */
  1146. /*Set PID to BUF*/
  1147. USBIO.PIPE6CTR.BIT.PID = PID_BUF;
  1148. /*If we have not written a full packets worth to the buffer then need to
  1149. signal that the buffer is now ready to be sent, set the buffer valid flag (BVAL).*/
  1150. if(Count != BULK_IN_PACKET_SIZE)
  1151. {
  1152. USBIO.D0FIFOCTR.BIT.BVAL = 1;
  1153. }
  1154. /*If have written all data*/
  1155. if(0 == g_Int.m_IN.m_DataBuff.NumBytes)
  1156. {
  1157. /*If this was not a full packet then have finished.*/
  1158. if(Count != INTERRUPT_IN_PACKET_SIZE)
  1159. {
  1160. CB_DONE CBTemp;
  1161. /*Disable interrupts*/
  1162. /*BEMP*/
  1163. USBIO.BEMPENB.BIT.PIPE6BEMPE = 0;
  1164. /*BRDY*/
  1165. USBIO.BRDYENB.BIT.PIPE6BRDYE = 0;
  1166. DEBUG_MSG_MID( ("USBHAL: INT IN - done\r\n"));
  1167. /*Before clearing busy flag copy CB.
  1168. NOTE Can't call CB before clearing flag as then CB
  1169. wouldn't be able to set up new request.*/
  1170. CBTemp = g_Int.m_IN.m_fpDone;
  1171. /*Int IN finished*/
  1172. g_Int.m_INBusy = false;
  1173. /*Call Registered Callback to say this is done*/
  1174. if(NULL != CBTemp)
  1175. {
  1176. CBTemp(USB_ERR_OK);
  1177. }
  1178. }
  1179. else
  1180. {
  1181. /*As this filled the packet exactly we need to send a zero length packet
  1182. to end the transfer*/
  1183. /*Ensure BRDY interrupt is enabled so will send zero packet*/
  1184. USBIO.BRDYENB.BIT.PIPE6BRDYE = 1;
  1185. }
  1186. }
  1187. else
  1188. {
  1189. /*Not written all data so ensure BRDY interrupt is enabled so can send another packet
  1190. when this one has been sent.*/
  1191. USBIO.BRDYENB.BIT.PIPE6BRDYE = 1;
  1192. }
  1193. }
  1194. /**********************************************************************
  1195. End WriteIntINPacket function
  1196. **********************************************************************/
  1197. /**********************************************************************
  1198. * Outline : WriteBulkINPacket
  1199. * Description : If the Bulk IN buffer contains data then this will
  1200. * write it to the pipe buffer until either the packet is
  1201. * full or all the data has been written.
  1202. * This controls BRDY interrupt fo rthis pipe to ensure
  1203. * all data is sent and that the transfer completes on a short packet.
  1204. * (Unless configuration m_bBULK_IN_No_Short_Packet is set.)
  1205. * Argument : none
  1206. * Return value : none
  1207. **********************************************************************/
  1208. static void WriteBulkINPacket(void)
  1209. {
  1210. uint32_t Count = 0;
  1211. /*Write data to Bulk IN pipe using D0FIFO*/
  1212. /*Select Interrupt Pipe and 16 bit access*/
  1213. USBIO.D0FIFOSEL.BIT.MBW = 1;
  1214. USBIO.D0FIFOSEL.BIT.CURPIPE = PIPE_BULK_IN;
  1215. /*Wait for buffer to be ready*/
  1216. while(USBIO.D0FIFOCTR.BIT.FRDY == 0){;}
  1217. /* Write data to the IN Fifo untill have written a full packet
  1218. or we have no more data to write */
  1219. while((Count < BULK_IN_PACKET_SIZE) &&
  1220. (g_Bulk.m_IN.m_DataBuff.NumBytes != 0))
  1221. {
  1222. if((g_Bulk.m_IN.m_DataBuff.NumBytes != 1) &&
  1223. ((Count+2) <= BULK_IN_PACKET_SIZE))
  1224. {
  1225. /*Enough data to do a 16bit write and enough room in this packet*/
  1226. uint16_t Data = (uint16_t)*g_Bulk.m_IN.m_DataBuff.pucBuf;
  1227. g_Bulk.m_IN.m_DataBuff.pucBuf++;
  1228. Data |= (uint16_t)(((uint16_t)*g_Bulk.m_IN.m_DataBuff.pucBuf) << 8);
  1229. g_Bulk.m_IN.m_DataBuff.pucBuf++;
  1230. /*Write data to Data Port*/
  1231. USBIO.D0FIFO.WORD = Data;
  1232. g_Bulk.m_IN.m_DataBuff.NumBytes-=2;
  1233. Count+=2;
  1234. }
  1235. else
  1236. {
  1237. /*The last byte.
  1238. This is written to the Least Significant Byte of 16bit data port*/
  1239. if(g_Bulk.m_IN.m_DataBuff.pucBuf != NULL)
  1240. {
  1241. USBIO.D0FIFO.BYTE.L = *g_Bulk.m_IN.m_DataBuff.pucBuf;
  1242. g_Bulk.m_IN.m_DataBuff.pucBuf++;
  1243. }
  1244. else
  1245. {
  1246. /*This BULK IN was setup to just send dummy data*/
  1247. USBIO.D0FIFO.BYTE.L = 0xAA;
  1248. }
  1249. g_Bulk.m_IN.m_DataBuff.NumBytes--;
  1250. Count++;
  1251. }
  1252. }
  1253. /*Often commented as it slows it down coniderably.*/
  1254. DEBUG_MSG_HIGH( ("USBHAL: BULK IN - sending %lu, %lu remaining\r\n",
  1255. Count, g_Bulk.m_IN.m_DataBuff.NumBytes));
  1256. /*Send the packet */
  1257. /*Set PID to BUF*/
  1258. USBIO.PIPE2CTR.BIT.PID = PID_BUF;
  1259. /*If we have not written a full packets worth to the buffer then need to
  1260. signal that the buffer is now ready to be sent, set the buffer valid flag (BVAL).*/
  1261. if(Count != BULK_IN_PACKET_SIZE)
  1262. {
  1263. USBIO.D0FIFOCTR.BIT.BVAL = 1;
  1264. }
  1265. /*If have written all data*/
  1266. if(0 == g_Bulk.m_IN.m_DataBuff.NumBytes)
  1267. {
  1268. /*If this was a full packet then will need to send a zero packet
  1269. to end the transfer (unless m_bBULK_IN_No_Short_Packet) */
  1270. if((Count != BULK_IN_PACKET_SIZE) ||
  1271. (true == g_Config.m_bBULK_IN_No_Short_Packet))
  1272. {
  1273. CB_DONE CBTemp;
  1274. /*Disable this BRDY interrupt*/
  1275. USBIO.BRDYENB.BIT.PIPE2BRDYE = 0;
  1276. DEBUG_MSG_HIGH( ("USBHAL: BULK IN - done.\r\n"));
  1277. /*Before clearing busy flag copy CB.
  1278. NOTE Can't call CB before clearing flag as then CB
  1279. wouldn't be able to set up new request.*/
  1280. CBTemp = g_Bulk.m_IN.m_fpDone;
  1281. /*BULK IN finished*/
  1282. g_Bulk.m_INBusy = false;
  1283. /*Call Registered Callback to say this BULK IN is done*/
  1284. if(NULL != CBTemp)
  1285. {
  1286. CBTemp(USB_ERR_OK);
  1287. }
  1288. }
  1289. else
  1290. {
  1291. /*Enable Interrupt so will send zero packet*/
  1292. USBIO.BRDYENB.BIT.PIPE2BRDYE = 1;
  1293. }
  1294. }
  1295. else
  1296. {
  1297. /*Enable Interrupt so can write rest of data out.*/
  1298. USBIO.BRDYENB.BIT.PIPE2BRDYE = 1;
  1299. }
  1300. }
  1301. /**********************************************************************
  1302. End WriteBulkINPacket function
  1303. **********************************************************************/
  1304. /**********************************************************************
  1305. * Outline : WriteControlINPacket
  1306. * Description : If the Control IN buffer contains data then this will
  1307. * write it to the pipe buffer until either the packet
  1308. * is full or all the data has been written.
  1309. * If there is no data in the buffer this will send
  1310. * a zero length packet.
  1311. *
  1312. * Argument : none
  1313. * Return value : none
  1314. **********************************************************************/
  1315. static void WriteControlINPacket(void)
  1316. {
  1317. uint16_t Count = 0;
  1318. /*Write data to DCP using CFIFO*/
  1319. /*Select DCP (Default Control Pipe)*/
  1320. USBIO.CFIFOSEL.BIT.CURPIPE = 0;
  1321. /*Enable buffer for reading*/
  1322. /*HW Manual says to check the setting has worked*/
  1323. do
  1324. {
  1325. USBIO.CFIFOSEL.BIT.ISEL = 1;
  1326. }while(0 == USBIO.CFIFOSEL.BIT.ISEL);
  1327. /*Wait for buffer to be ready*/
  1328. while(USBIO.CFIFOCTR.BIT.FRDY == 0){;}
  1329. /* Write data to the IN Fifo untill have written a full packet
  1330. or we have no more data to write */
  1331. while((Count < CONTROL_IN_PACKET_SIZE) &&
  1332. (g_Control.m_IN.m_DataBuff.NumBytes != 0))
  1333. {
  1334. /*For 8 bit access write only to low 8 bits of CFIFO.*/
  1335. USBIO.CFIFO.BYTE.L = *g_Control.m_IN.m_DataBuff.pucBuf;
  1336. g_Control.m_IN.m_DataBuff.pucBuf++;
  1337. g_Control.m_IN.m_DataBuff.NumBytes--;
  1338. Count++;
  1339. }
  1340. /*Set PID to BUF*/
  1341. USBIO.DCPCTR.BIT.PID = PID_BUF;
  1342. /*If we have not written a full packets worth to the buffer then need to
  1343. signal that the buffer is now ready to be sent, set the buffer valid flag (BVAL).*/
  1344. if(Count != BULK_IN_PACKET_SIZE)
  1345. {
  1346. USBIO.CFIFOCTR.BIT.BVAL = 1;
  1347. }
  1348. DEBUG_MSG_HIGH(("USBHAL: CONTROL IN - sending %u, %lu remaining\r\n",
  1349. Count, g_Control.m_IN.m_DataBuff.NumBytes));
  1350. /*Expect a BEMP interrupt when this has been sent.
  1351. Can then send more data if required or status stage.*/
  1352. }
  1353. /**********************************************************************
  1354. End WriteControlINPacket function
  1355. **********************************************************************/
  1356. /**********************************************************************
  1357. * Outline : ReadControlOUTPacket
  1358. * Description : If a buffer has been setup for Control OUT then
  1359. * read data into the buffer.
  1360. * If buffer is full or a short packet
  1361. * is received then call the done callback.
  1362. * If data is available but there is no buffer
  1363. * setup for it then call the error callback.
  1364. * Argument : none
  1365. * Return value : none
  1366. **********************************************************************/
  1367. static void ReadControlOUTPacket(void)
  1368. {
  1369. volatile uint8_t dummy=0;
  1370. uint32_t Count = 0;
  1371. /*Read data from DCP using CFIFO*/
  1372. /*Select DCP*/
  1373. /*NOTE this probably will have already been done if using BRDY interrupt.*/
  1374. USBIO.CFIFOSEL.BIT.CURPIPE = 0;
  1375. /*Set PID to BUF*/
  1376. USBIO.DCPCTR.BIT.PID = PID_BUF;
  1377. /*Enable buffer for reading*/
  1378. /*HW Manual says to check the setting has worked*/
  1379. do
  1380. {
  1381. USBIO.CFIFOSEL.BIT.ISEL = 0;
  1382. }while(1 == USBIO.CFIFOSEL.BIT.ISEL);
  1383. /*Set Read Count Mode - so DTLN count will decrement as data read from buffer*/
  1384. USBIO.CFIFOSEL.BIT.RCNT = 1;
  1385. /*Wait for buffer to be ready*/
  1386. while(USBIO.CFIFOCTR.BIT.FRDY == 0){;}
  1387. /*Read data while there is data in the FIFO and
  1388. room in buffer to store it in.*/
  1389. while((g_Control.m_OUT.m_BuffSize > g_Control.m_OUT.m_DataBuff.NumBytes) &&
  1390. (0 != USBIO.CFIFOCTR.BIT.DTLN))
  1391. {
  1392. if(g_Control.m_OUT.m_DataBuff.pucBuf != NULL)
  1393. {
  1394. *g_Control.m_OUT.m_DataBuff.pucBuf = (uint8_t)USBIO.CFIFO.BYTE.L;
  1395. g_Control.m_OUT.m_DataBuff.pucBuf++;
  1396. Count++;
  1397. }
  1398. else
  1399. {
  1400. dummy = (uint8_t)USBIO.CFIFO.BYTE.L;
  1401. }
  1402. g_Control.m_OUT.m_DataBuff.NumBytes++;
  1403. }
  1404. /*Have we completed the CONTROL OUT request?*/
  1405. /*If this wasn't a full packet or we have filled the buffer*/
  1406. if(((0 != g_Control.m_OUT.m_BuffSize) && /*Check CONTROL OUT has been setup*/
  1407. (g_Control.m_OUT.m_BuffSize == g_Control.m_OUT.m_DataBuff.NumBytes)) ||
  1408. (Count != CONTROL_OUT_PACKET_SIZE))
  1409. {
  1410. /*Buffer not valid anymore*/
  1411. g_Control.m_OUT.m_BuffSize = 0;
  1412. /*Disable this interrupt*/
  1413. USBIO.BRDYENB.BIT.PIPE2BRDYE = 0;
  1414. /*End of data transfer - now onto status stage*/
  1415. /*Set CCPL to 1 - this will cause module to automatically handle the status stage.
  1416. i.e Read a zero length packet from host and send ACK response*/
  1417. /*Set PID to BUF before setting CCPL*/
  1418. USBIO.DCPCTR.BIT.PID = PID_BUF;
  1419. USBIO.DCPCTR.BIT.CCPL = 1;
  1420. /*Call registered callback*/
  1421. if(g_Control.m_OUT.m_fpDone != NULL)
  1422. {
  1423. g_Control.m_OUT.m_fpDone(USB_ERR_OK,
  1424. g_Control.m_OUT.m_DataBuff.NumBytes);
  1425. }
  1426. }
  1427. /*If at this point more data is available then call Error CallBack*/
  1428. if(0 != USBIO.CFIFOCTR.BIT.DTLN)
  1429. {
  1430. /*No buffer available for CONTROL OUT*/
  1431. g_CBs.fpError(USB_ERR_CONTROL_OUT);
  1432. }
  1433. (void) dummy;
  1434. }
  1435. /**********************************************************************
  1436. End ReadControlOUTPacket function
  1437. **********************************************************************/
  1438. /**********************************************************************
  1439. * Outline : HandleVBus
  1440. * Description : VBUS interrupt has occoured.
  1441. * USB cable has been connected or disconnected.
  1442. * If Disconnected then use registered callback to inform user.
  1443. * Note: User is not informed of connection event until SetAddress
  1444. * USB request is received.
  1445. * Argument : none
  1446. * Return value : none
  1447. **********************************************************************/
  1448. static void HandleVBus(void)
  1449. {
  1450. /*Check VBSTS to see the VBUS value.*/
  1451. uint8_t vbsts_value;
  1452. uint8_t count;
  1453. #define CHATTER_COUNT 5
  1454. /*Keep reading VBSTS until it is stable*/
  1455. do
  1456. {
  1457. count = CHATTER_COUNT;
  1458. /*Read VBSTS then confirm it's value does not change for CHATTER_COUNT times */
  1459. vbsts_value = (uint8_t)USBIO.INTSTS0.BIT.VBSTS;
  1460. while(count != 0)
  1461. {
  1462. if((uint8_t)USBIO.INTSTS0.BIT.VBSTS != vbsts_value)
  1463. {
  1464. /*Chatter - signal is not stable*/
  1465. break;
  1466. }
  1467. else
  1468. {
  1469. count--;
  1470. }
  1471. }
  1472. }while(count != 0);
  1473. if(1 == vbsts_value)
  1474. {
  1475. /* USB Bus Connected */
  1476. g_Control.m_etState = STATE_READY;
  1477. /*Reset HAL*/
  1478. USBHAL_Reset();
  1479. /*Call Registered Callback to tell that cable is connected*/
  1480. /*NOTE: Moved until Set Address has been recieved as more important for
  1481. user to know when enumerated that just vbus change.*/
  1482. /*g_CBs.fpCable(true);*/
  1483. }
  1484. else
  1485. {
  1486. /* USB Bus Disconnected */
  1487. g_Control.m_etState = STATE_DISCONNECTED;
  1488. /*Cancel any pending operations -
  1489. including calling any 'done' callbacks */
  1490. USBHAL_Cancel(USB_ERR_NOT_CONNECTED);
  1491. /*Call Registered Callback*/
  1492. g_CBs.fpCable(false);
  1493. }
  1494. }
  1495. /**********************************************************************
  1496. End HandleVBus function
  1497. **********************************************************************/
  1498. /**********************************************************************
  1499. * Outline : HandleDVST
  1500. * Description : Device State Transition Interrupt.
  1501. * Used to detect a USB bus reset.
  1502. * Argument : none
  1503. * Return value : none
  1504. **********************************************************************/
  1505. static void HandleDVST(void)
  1506. {
  1507. /*Read new device state in DVSQ bits*/
  1508. switch(USBIO.INTSTS0.BIT.DVSQ)
  1509. {
  1510. case 0:
  1511. DEBUG_MSG_LOW(("USBHAL: Entered Powered State\r\n"));
  1512. break;
  1513. case 1:
  1514. DEBUG_MSG_LOW(("USBHAL: Entered Default State\r\n"));
  1515. /*Has a bus reset just occured*/
  1516. if(USBIO.DVSTCTR0.BIT.RHST == 4)
  1517. {
  1518. DEBUG_MSG_LOW(("USBHAL: USB BUS RESET\r\n"));
  1519. /*Reset endpoints - this also ensures BULK out is still able
  1520. to receive data.*/
  1521. USBHAL_ResetEndpoints();
  1522. }
  1523. break;
  1524. case 2:
  1525. DEBUG_MSG_LOW(("USBHAL: Entered Address State\r\n"));
  1526. /*This is a conveniant point to tell user that USB is connected. */
  1527. g_CBs.fpCable(true);
  1528. break;
  1529. case 3:
  1530. DEBUG_MSG_LOW(("USBHAL: Entered Configured State\r\n"));
  1531. /*Nothing todo*/
  1532. break;
  1533. case 4:
  1534. default:
  1535. DEBUG_MSG_LOW(("USBHAL: Entered Suspended State\r\n"));
  1536. /*Nothing todo*/
  1537. };
  1538. }
  1539. /**********************************************************************
  1540. End HandleDVST function
  1541. **********************************************************************/
  1542. /**********************************************************************
  1543. * Outline : HandleCTRT
  1544. * Description : Control Transfer Stage Transition Interrupt
  1545. * Used to detect the receipt of a Setup command.
  1546. * Argument : none
  1547. * Return value : none
  1548. **********************************************************************/
  1549. static void HandleCTRT(void)
  1550. {
  1551. switch(USBIO.INTSTS0.BIT.CTSQ)
  1552. {
  1553. case 0:
  1554. DEBUG_MSG_MID(("USBHAL: CTSQ: IDLE or Setup\r\n"));
  1555. break;
  1556. case 1:
  1557. DEBUG_MSG_MID(("USBHAL: CTSQ: Control Read Data\r\n"));
  1558. /*Setup packet has been received.*/
  1559. /*This is a Request that has a data write stage*/
  1560. HandleSetupCmd();
  1561. break;
  1562. case 2:
  1563. DEBUG_MSG_MID(("USBHAL: CTSQ: Control Read Status\r\n"));
  1564. break;
  1565. case 3:
  1566. DEBUG_MSG_MID(("USBHAL: CTSQ: Control Write Data\r\n"));
  1567. /*Setup packet has been received.*/
  1568. /*This is a Request that has a data write stage*/
  1569. HandleSetupCmd();
  1570. break;
  1571. case 4:
  1572. DEBUG_MSG_MID(("USBHAL: CTSQ: Control Write Status\r\n"));
  1573. break;
  1574. case 5:
  1575. DEBUG_MSG_MID(("USBHAL: CTSQ: Control Write(no data) Status\r\n"));
  1576. /*Setup packet has been received.*/
  1577. /*This is a Request that doesn't have a data stage*/
  1578. HandleSetupCmd();
  1579. break;
  1580. case 6:
  1581. DEBUG_MSG_MID(("USBHAL: CTSQ: Control Transfer Error\r\n"));
  1582. break;
  1583. default:
  1584. DEBUG_MSG_LOW(("USBHAL: CTSQ: INVALID\r\n"));
  1585. break;
  1586. };
  1587. }
  1588. /**********************************************************************
  1589. End HandleCTRT function
  1590. **********************************************************************/
  1591. /**********************************************************************
  1592. * Outline : HandleBRDY
  1593. * Description : Buffer Ready Interrupt.
  1594. * Used to start/continue:
  1595. * 1. Interrupt IN packets.
  1596. * 2. Bulk IN packets.
  1597. * 3. Bulk IN packets.
  1598. * 4. Bulk OUT packets.
  1599. * 5. Control Out packets.
  1600. * Argument : none
  1601. * Return value : none
  1602. **********************************************************************/
  1603. static void HandleBRDY(void)
  1604. {
  1605. DEBUG_MSG_HIGH(("USBHAL: BRDY\r\n"));
  1606. /*Has Interrupt pipe caused this interrupt (pipe6)*/
  1607. if((1 == USBIO.BRDYSTS.BIT.PIPE6BRDY) && (1 == USBIO.BRDYENB.BIT.PIPE6BRDYE))
  1608. {
  1609. DEBUG_MSG_HIGH(("USBHAL: BRDY PIPE Interrupt\r\n"));
  1610. /*Clear this bit (write 1 to all other bits)*/
  1611. USBIO.BRDYSTS.WORD = ~0x0040;
  1612. /*Send another packet (possibly zero legth)*/
  1613. WriteIntINPacket();
  1614. }
  1615. /*Has BULK IN pipe caused this interrupt (pipe2)*/
  1616. if((1 == USBIO.BRDYSTS.BIT.PIPE2BRDY) && (1== USBIO.BRDYENB.BIT.PIPE2BRDYE))
  1617. {
  1618. DEBUG_MSG_HIGH(("USBHAL: BRDY PIPE Bulk IN\r\n"));
  1619. /*Clear this bit (write 1 to all other bits)*/
  1620. USBIO.BRDYSTS.WORD = ~0x0004;
  1621. /*Send another packet (possibly zero legth)*/
  1622. WriteBulkINPacket();
  1623. }
  1624. /*Has BULK OUT pipe caused this interrupt (pipe1)*/
  1625. if((1 == USBIO.BRDYSTS.BIT.PIPE1BRDY) && (1== USBIO.BRDYENB.BIT.PIPE1BRDYE))
  1626. {
  1627. DEBUG_MSG_HIGH(("USBHAL: BRDY PIPE Bulk OUT\r\n"));
  1628. /*Clear this bit (write 1 to all other bits)*/
  1629. USBIO.BRDYSTS.WORD = ~0x0002;
  1630. /*Read received packet*/
  1631. ReadBulkOUTPacket();
  1632. }
  1633. /*Has Control OUT pipe caused this interrupt (pipe1)*/
  1634. if((1 == USBIO.BRDYSTS.BIT.PIPE0BRDY) && (1== USBIO.BRDYENB.BIT.PIPE0BRDYE))
  1635. {
  1636. DEBUG_MSG_HIGH(("USBHAL: BRDY PIPE Control OUT\r\n"));
  1637. /*Clear this bit (write 1 to all other bits)*/
  1638. USBIO.BRDYSTS.WORD = ~0x0001;
  1639. /*Read received packet*/
  1640. ReadControlOUTPacket();
  1641. }
  1642. }
  1643. /**********************************************************************
  1644. End HandleBRDY function
  1645. **********************************************************************/
  1646. /**********************************************************************
  1647. * Outline : HandleBEMP
  1648. * Description : Buffer Empty Interrupt
  1649. * Used for Control IN to write another packet or
  1650. * move to status stage.
  1651. * Argument : none
  1652. * Return value : none
  1653. **********************************************************************/
  1654. static void HandleBEMP(void)
  1655. {
  1656. DEBUG_MSG_HIGH(("USBHAL: BEMP\r\n"));
  1657. /*Has control pipe caused this interrupt*/
  1658. if(1 == USBIO.BEMPSTS.BIT.PIPE0BENP)
  1659. {
  1660. DEBUG_MSG_HIGH(("USBHAL: BEMP PIPE0\r\n"));
  1661. /*Clear this bit (write 1 to all other bits)*/
  1662. USBIO.BEMPSTS.WORD = ~0x0001;
  1663. /*If we are performing a CONTROL IN DATA*/
  1664. if(STATE_CONTROL_IN == g_Control.m_etState)
  1665. {
  1666. /*If there is more data to send*/
  1667. if(g_Control.m_IN.m_DataBuff.NumBytes != 0)
  1668. {
  1669. WriteControlINPacket();
  1670. }
  1671. else
  1672. {
  1673. /*End of data transfer*/
  1674. /*Clear CFIFO (seemed necessary to prevent duplicate transfers)*/
  1675. USBIO.CFIFOCTR.BIT.BCLR = 1;
  1676. /*Status Stage*/
  1677. /*Set CCPL to 1 - this will cause module to automatically handle the status stage.
  1678. i.e Transmit zero length packet and recieve ACK from host.*/
  1679. /*Ensure PID is set to BUF before setting CCPL*/
  1680. USBIO.DCPCTR.BIT.PID = PID_BUF;
  1681. USBIO.DCPCTR.BIT.CCPL = 1;
  1682. }
  1683. }
  1684. }
  1685. /*NOTE: for other pipes we are not using BEMP, only BRDY*/
  1686. }
  1687. /**********************************************************************
  1688. End HandleBEMP function
  1689. **********************************************************************/
  1690. /**********************************************************************
  1691. * Outline : HandleSetupCmd
  1692. * Description : Have received a Contol Setup packet.
  1693. * Use registered callback to inform user.
  1694. * Argument : none
  1695. * Return value : none
  1696. **********************************************************************/
  1697. static void HandleSetupCmd(void)
  1698. {
  1699. // uint8_t SetupCmdBuffer[USB_SETUP_PACKET_SIZE];
  1700. uint16_t SetupCmdBuffer[USB_SETUP_PACKET_SIZE];
  1701. uint16_t* p_16;
  1702. DEBUG_MSG_MID(("USBHAL: - Setup Received\r\n"));
  1703. /*Don't check state as host may have aborted other states -
  1704. so this just sets the state to STATE_CONTROL_SETUP*/
  1705. /*Clear VALID flag*/
  1706. USBIO.INTSTS0.BIT.VALID = 0;
  1707. /*Read the 8 bytes setup command into temporary buffer*/
  1708. p_16 = (uint16_t*)SetupCmdBuffer;
  1709. *p_16++ = USBIO.USBREQ.WORD;
  1710. *p_16++ = USBIO.USBVAL;
  1711. *p_16++ = USBIO.USBINDX;
  1712. *p_16 = USBIO.USBLENG;
  1713. g_Control.m_etState = STATE_CONTROL_SETUP;
  1714. /*NOTE: Expect to continue with a Data Stage
  1715. - (either Control IN or Control OUT) or straight to a Status Stage ,
  1716. Users of this HAL must set this up when handling the Setup callback.*/
  1717. /*Call Registered Callback*/
  1718. g_CBs.fpSetup((const uint8_t(*)[USB_SETUP_PACKET_SIZE])SetupCmdBuffer);
  1719. }
  1720. /**********************************************************************
  1721. End HandleSetupCmd function
  1722. **********************************************************************/
  1723. /**********************************************************************
  1724. * Outline : HW_Init
  1725. * Description : Enable and Initiailise the USB perhipheral.
  1726. * Note: USB requires EXTAL = 12MHz.
  1727. * UCLK = EXTAL*4 = 48MHz.
  1728. * Argument : none
  1729. * Return value : none
  1730. **********************************************************************/
  1731. /*static*/ void HW_Init(void)
  1732. {
  1733. // volatile unsigned long Delay;
  1734. /*Module specific Initialisation*/
  1735. #ifdef USB_MODULE_1
  1736. HW_Init_Module1();
  1737. #else
  1738. HW_Init_Module0(); //select pins, pwr enable, INT(USB0)
  1739. #endif
  1740. /*Start USB clock*/
  1741. USBIO.SYSCFG.BIT.SCKE = 1;
  1742. /*Enable USB operation (in SCKE=1)*/
  1743. USBIO.SYSCFG.BIT.USBE = 1;
  1744. /*Select Function not Host*/
  1745. USBIO.SYSCFG.BIT.DCFM = 0;
  1746. /*Enable D+ pull up*/
  1747. USBIO.SYSCFG.BIT.DPRPU = 1; //assert pin of DPUPE
  1748. /*Configire Pipes/Endpoints */
  1749. ConfigurePipes();
  1750. /* Enable specific USB interrupts */
  1751. SetDefaultInterrupts();
  1752. }
  1753. /**********************************************************************
  1754. End HW_Init function
  1755. **********************************************************************/
  1756. /**********************************************************************
  1757. * Outline : HW_Init_Module0
  1758. * Description : HW Initialisation specific for module 0
  1759. * Argument : -
  1760. * Return value : -
  1761. **********************************************************************/
  1762. #ifdef USB_MODULE_0
  1763. static void HW_Init_Module0(void)
  1764. {
  1765. /*Set Port P23(USB0DPUPE-A) as Input direction*/
  1766. /*NOTE: Document "USB_RSK+RX62N_Jumper_DIP-SW" stated this.*/
  1767. // PORT2.DDR.BIT.B3 = 0;
  1768. MSTP(USB0) = 0;
  1769. //Set Port P14 as output to be served as USB0DPUPE-B
  1770. //if PFKUSB.USBE==1, PFKUSB.USBMD==0
  1771. PORT1.DDR.BIT.B4 = 1;
  1772. /*Enable input buffer for USB0_VBUS pin*/
  1773. PORT1.ICR.BIT.B6 = 1;
  1774. /*Pin Function Select*/
  1775. /*USB0 pins enable*/
  1776. // IOPORT.PFKUSB.BIT.USBE = 1;
  1777. /*Select fuction mode for USB0 pins*/
  1778. // IOPORT.PFKUSB.BIT.USBMD = 0;
  1779. IOPORT.PFKUSB.BYTE = 0x14;
  1780. /*Enable USB interrupts at high level*/
  1781. ICU.IER[0x04].BIT.IEN6 = 1;
  1782. /*Set interrupt priority*/
  1783. ICU.IPR[0x0E].BIT.IPR = USB_HAL_INTERRUPT_PROIRITY;
  1784. /*Cancel USB Module stop state.*/
  1785. // MSTP_USB0 = 0;
  1786. // MSTP(USB0) = 0;
  1787. }
  1788. #endif
  1789. /**********************************************************************
  1790. End HW_Init_Module0 function
  1791. **********************************************************************/
  1792. /**********************************************************************
  1793. * Outline : HW_Init_Module1
  1794. * Description : HW Initialisation specific for module 1
  1795. *
  1796. * Argument : -
  1797. * Return value : -
  1798. **********************************************************************/
  1799. #ifdef USB_MODULE_1
  1800. static void HW_Init_Module1(void)
  1801. {
  1802. /*Set Port P10(USB1DPUPE-A) as Input direction*/
  1803. /*NOTE: Document "USB_RSK+RX62N_Jumper_DIP-SW" stated this.*/
  1804. PORT1.DDR.BIT.B0 = 0;
  1805. /*Enable input buffer for USB0_VBUS pin*/
  1806. PORT1.ICR.BIT.B7 = 1;
  1807. /*Pin Function Select*/
  1808. /*USB1 pins enable*/
  1809. IOPORT.PFLUSB.BIT.USBE = 1;
  1810. /*Select fuction mode for USB1 pins*/
  1811. IOPORT.PFLUSB.BIT.USBMD = 0;
  1812. /*Enable USB interrupts at high level*/
  1813. ICU.IER[0x05].BIT.IEN2 = 1;
  1814. /*Set interrupt priority*/
  1815. ICU.IPR[0x12].BIT.IPR = USB_HAL_INTERRUPT_PROIRITY;
  1816. /*Cancel USB Module stop state.*/
  1817. MSTP_USB1 = 0;
  1818. }
  1819. #endif
  1820. /**********************************************************************
  1821. End HW_Init_Module1 function
  1822. **********************************************************************/
  1823. /**********************************************************************
  1824. * Outline : ConfigurePipes
  1825. * Description : Configures BULK IN, BULK OUT and Interrupt IN pipes.
  1826. * Pipe 1 = BULK OUT
  1827. * Pipe 2 = BULK IN
  1828. * Pipe 6 = Interrupt IN
  1829. * Argument : -
  1830. * Return value : -
  1831. **********************************************************************/
  1832. static void ConfigurePipes(void)
  1833. {
  1834. /*** BULK OUT ***/
  1835. {
  1836. /*This is written for a particular pipe*/
  1837. #if(1 != PIPE_BULK_OUT)
  1838. #error
  1839. #endif
  1840. /*Select Pipe*/
  1841. USBIO.PIPESEL.BIT.PIPESEL = PIPE_BULK_OUT;
  1842. /*Pipe Control*/
  1843. /*Note: PID must be set to NAK before configuring PIPECFG*/
  1844. USBIO.PIPE1CTR.WORD = 0x000;
  1845. /*Wait for pipe to be not busy*/
  1846. while(USBIO.PIPE1CTR.BIT.PBUSY == 1){;}
  1847. /*Pipe Configure, Direction, Type, Double Buffer, BRDY Interrupt operation*/
  1848. /*Default */
  1849. USBIO.PIPECFG.WORD = 0;
  1850. /*Endpoint*/
  1851. USBIO.PIPECFG.BIT.EPNUM = EP_BULK_OUT;
  1852. /*Direction*/
  1853. USBIO.PIPECFG.BIT.DIR = 0;
  1854. /*Double Buffer */
  1855. USBIO.PIPECFG.BIT.DBLB = 1;
  1856. /*BRDY Interrupt Operation*/
  1857. USBIO.PIPECFG.BIT.BFRE = 0;
  1858. /*Transfer Type */
  1859. USBIO.PIPECFG.BIT.TYPE = 1;
  1860. /*Pipe Packet Size*/
  1861. USBIO.PIPEMAXP.BIT.MXPS = BULK_OUT_PACKET_SIZE;
  1862. /*Reset Data toggle*/
  1863. USBIO.PIPE1CTR.BIT.SQCLR = 1;
  1864. /*Clear Buffer*/
  1865. USBIO.PIPE1CTR.BIT.ACLRM = 1;
  1866. USBIO.PIPE1CTR.BIT.ACLRM = 0;
  1867. /*Set PID to BUF so it can receive data*/
  1868. USBIO.PIPE1CTR.BIT.PID = PID_BUF;
  1869. /*Exclusively use D1FIFO for BULK OUT pipe and 16bit access*/
  1870. USBIO.D1FIFOSEL.BIT.MBW = 1;
  1871. USBIO.D1FIFOSEL.BIT.CURPIPE = PIPE_BULK_OUT;
  1872. }
  1873. /*** BULK IN ***/
  1874. {
  1875. /*This is written for a particular pipe*/
  1876. #if(2 != PIPE_BULK_IN)
  1877. #error
  1878. #endif
  1879. /*Select Pipe*/
  1880. USBIO.PIPESEL.BIT.PIPESEL = PIPE_BULK_IN;
  1881. /*Pipe Control*/
  1882. /*Note: PID must be set to NAK before configuring PIPECFG*/
  1883. USBIO.PIPE2CTR.WORD = 0x000;
  1884. /*Wait for pipe to be not busy*/
  1885. while(USBIO.PIPE2CTR.BIT.PBUSY == 1){;}
  1886. /*Pipe Configure, Direction, Type, Double Buffer, BRDY Interrupt operation*/
  1887. /*Default */
  1888. USBIO.PIPECFG.WORD = 0;
  1889. /*Endpoint*/
  1890. USBIO.PIPECFG.BIT.EPNUM = EP_BULK_IN;
  1891. /*Direction*/
  1892. USBIO.PIPECFG.BIT.DIR = 1;
  1893. /*Double Buffer */
  1894. USBIO.PIPECFG.BIT.DBLB = 1;
  1895. /*BRDY Interrupt Operation*/
  1896. USBIO.PIPECFG.BIT.BFRE = 0;
  1897. /*Transfer Type */
  1898. USBIO.PIPECFG.BIT.TYPE = 1;
  1899. /*Pipe Packet Size*/
  1900. USBIO.PIPEMAXP.BIT.MXPS = BULK_IN_PACKET_SIZE;
  1901. }
  1902. /*** INTERRUPT IN ***/
  1903. {
  1904. /*This is written for a particular pipe*/
  1905. #if(6 != PIPE_INTERRUPT_IN)
  1906. #error
  1907. #endif
  1908. /*Select Pipe*/
  1909. USBIO.PIPESEL.BIT.PIPESEL = PIPE_INTERRUPT_IN;
  1910. /*Pipe Control*/
  1911. /*Note: PID must be set to NAK before configuring PIPECFG*/
  1912. USBIO.PIPE6CTR.WORD = 0x000;
  1913. /*Pipe Configure, Direction, Type, Double Buffer, BRDY Interrupt operation*/
  1914. /*Default */
  1915. USBIO.PIPECFG.WORD = 0;
  1916. /*Endpoint*/
  1917. USBIO.PIPECFG.BIT.EPNUM = EP_INTERRUPT_IN;
  1918. /*Direction*/
  1919. USBIO.PIPECFG.BIT.DIR = 1;
  1920. /*Double Buffer */
  1921. USBIO.PIPECFG.BIT.DBLB = 1;
  1922. /*BRDY Interrupt Operation*/
  1923. USBIO.PIPECFG.BIT.BFRE = 0;
  1924. /*Transfer Type */
  1925. USBIO.PIPECFG.BIT.TYPE = 2;
  1926. /*Pipe Packet Size*/
  1927. USBIO.PIPEMAXP.BIT.MXPS = INTERRUPT_IN_PACKET_SIZE;
  1928. }
  1929. /*Un-select any pipe*/
  1930. USBIO.PIPESEL.BIT.PIPESEL = 0;
  1931. }
  1932. /**********************************************************************
  1933. End ConfigurePipes function
  1934. **********************************************************************/
  1935. /**********************************************************************
  1936. * Outline : SetDefaultInterrupts
  1937. * Description : Enable the default set of interrupts.
  1938. * Some interrupts will be enabled later as they are required.
  1939. * Argument : none
  1940. * Return value : none
  1941. **********************************************************************/
  1942. static void SetDefaultInterrupts(void)
  1943. {
  1944. /*Enable VBSE (VBUS) Interrupt*/
  1945. USBIO.INTENB0.BIT.VBSE = 1;
  1946. /*Enable DVST (Device State Transition) Interrupt*/
  1947. USBIO.INTENB0.BIT.DVSE = 1;
  1948. /*Enable CTRT (Control Transfer Stage Transition) Interrupt*/
  1949. USBIO.INTENB0.BIT.CTRE = 1;
  1950. /*Enable BEMP - see particular pipe BEMP enable aswell*/
  1951. USBIO.INTENB0.BIT.BEMPE = 1;
  1952. /*Enable BRDY - see particular pipe BRDY enable aswell*/
  1953. USBIO.INTENB0.BIT.BRDYE = 1;
  1954. /***Pipe specific***/
  1955. /*Contol pipe*/
  1956. /*BEMP: used to continue sending data (or moving on to status stage)
  1957. during CONTROL IN DATA*/
  1958. USBIO.BEMPENB.BIT.PIPE0BEMPE = 1;
  1959. /*BRDY used for Control OUT = enabled when required*/
  1960. USBIO.BRDYENB.BIT.PIPE0BRDYE = 0;
  1961. /*Interrupt IN pipe (pipe6)*/
  1962. /*BEMP - enable only as required*/
  1963. USBIO.BEMPENB.BIT.PIPE6BEMPE = 0;
  1964. /*BRDY - enable only as required*/
  1965. USBIO.BRDYENB.BIT.PIPE6BRDYE = 0;
  1966. /*Bulk IN pipe (pipe2)*/
  1967. /*BEMP - enable only as required*/
  1968. USBIO.BEMPENB.BIT.PIPE2BEMPE = 0;
  1969. /*BRDY - enable only as required*/
  1970. USBIO.BRDYENB.BIT.PIPE2BRDYE = 0;
  1971. /*Bulk OUT pipe (pipe1)*/
  1972. /*BEMP - enable only as required*/
  1973. USBIO.BEMPENB.BIT.PIPE1BEMPE = 0;
  1974. /*BRDY - enable so host can always send us data*/
  1975. USBIO.BRDYENB.BIT.PIPE1BRDYE = 1;
  1976. }
  1977. /**********************************************************************
  1978. End SetDefaultInterrupts function
  1979. **********************************************************************/
  1980. /**********************************************************************
  1981. * Outline : USBHALInterruptHandler
  1982. * Description : USB interrupt handler.
  1983. * User must ensure that this gets called when
  1984. * the USB interrupt occours.
  1985. *
  1986. * Argument : none
  1987. * Return value : none
  1988. **********************************************************************/
  1989. uint16_t getINTSTS0(void)
  1990. {
  1991. return(int_sts0);
  1992. }
  1993. void USBHALInterruptHandler(void)
  1994. {
  1995. /*The status flag tells us what caused the interrupt. */
  1996. int_sts0 = USB0.INTSTS0.WORD; /////////////////////(n.k)
  1997. /*Is this a VBUS Interrupt?*/
  1998. if(1 == USBIO.INTSTS0.BIT.VBINT)
  1999. {
  2000. /*Clear interrupt flag*/
  2001. USBIO.INTSTS0.BIT.VBINT = 0;
  2002. /* VBUS State change i.e USB cable connected/disconnected */
  2003. HandleVBus();
  2004. }
  2005. /*Is this a DVST Interrupt?*/
  2006. if(1 == USBIO.INTSTS0.BIT.DVST)
  2007. {
  2008. /*Clear interrupt flag*/
  2009. USBIO.INTSTS0.BIT.DVST = 0;
  2010. /* Device State Transition */
  2011. HandleDVST();
  2012. }
  2013. /*Is this a CTRT interrupt?*/
  2014. if(1 == USBIO.INTSTS0.BIT.CTRT)
  2015. {
  2016. /* Control Transfer Stage Transition */
  2017. HandleCTRT();
  2018. /*Clear interrupt flag*/
  2019. /*Note: Had to do this after call to HandleCTRT to avoid getting
  2020. two interrupts for same setup packet. */
  2021. USBIO.INTSTS0.BIT.CTRT = 0;
  2022. }
  2023. /*Is this a BEMP interrupt?*/
  2024. if(1 == USBIO.INTSTS0.BIT.BEMP)
  2025. {
  2026. /*Note: Can't clear this flag by SW.*/
  2027. /*Buffer Empty Interrupt*/
  2028. HandleBEMP();
  2029. }
  2030. /*Is this a BRDY interrupt?*/
  2031. if(1 == USBIO.INTSTS0.BIT.BRDY)
  2032. {
  2033. /*Note: Can't clear this flag by SW.*/
  2034. /*Buffer Ready Interrupt*/
  2035. HandleBRDY();
  2036. }
  2037. }
  2038. /**********************************************************************
  2039. End USBHALInterruptHandler function
  2040. **********************************************************************/
  2041. void usbc_cpu_Delay1us(uint16_t usec)
  2042. {
  2043. volatile register uint16_t i;
  2044. /* Wait 1us (Please change for your MCU) */
  2045. for( i = 0; i < (3 * usec); ++i )
  2046. {
  2047. };
  2048. }
  2049. bool usb_VBUS(void)
  2050. {
  2051. uint16_t buf1, buf2, buf3;
  2052. /* VBUS chattering cut */
  2053. do
  2054. {
  2055. buf1 = USB0.INTSTS0.BIT.VBSTS;
  2056. usbc_cpu_Delay1us((uint16_t)10);
  2057. buf2 = USB0.INTSTS0.BIT.VBSTS;
  2058. usbc_cpu_Delay1us((uint16_t)10);
  2059. buf3 = USB0.INTSTS0.BIT.VBSTS;
  2060. }while((buf1 != buf2) || (buf2 != buf3));
  2061. /* VBUS status judge */
  2062. return buf1;
  2063. }