usb_framework.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /***********************************************************************************
  2. Filename: usb_framework.h
  3. Description: USB library common functionality.
  4. ***********************************************************************************/
  5. #ifndef USBFRAMEWORK_H
  6. #define USBFRAMEWORK_H
  7. /** \addtogroup module_usb_framework USB Framework (usbfw)
  8. * \brief This module contains USB status information, functions for initialization, USB device reset
  9. * handling, and most importantly, the framework for transfers on endpoint 0, FIFO access, and endpoint
  10. * control.
  11. *
  12. * \section section_init Framework Initialization
  13. * The framework and the USB peripheral unit can be initialized once the crystal oscillator (48 MHz for
  14. * CC1111/CC2511, 32 MHz for CC2531) is running. This is done by \ref usbfwInit(), which:
  15. * \li Initializes framework variables
  16. * \li Enables the USB peripheral unit by setting the \c SLEEP.USB_EN bit
  17. * \li Enables the pull-up resistor via a GPIO pin
  18. *
  19. * When completing the last step, the host will be recognize the USB device, and start the enumeration
  20. * process. To reply to the shortly incoming standard requests, the call to \ref usbfwInit() must be
  21. * followed immediately by USB Interrupt \ref section_usbirq_initialization.
  22. *
  23. * \section section_endpoint_0_transfers Endpoint 0 Transfers
  24. * The USB interface uses endpoint 0 to perform setup requests of the standard, vendor and class types.
  25. * Such transfers consist of three phases:
  26. * - A setup phase, where an 8-byte \ref USB_SETUP_HEADER is transferred to the device.
  27. * - An IN/OUT data phase, if the length field of the \ref USB_SETUP_HEADER structure is non-zero.
  28. * - A handshake phase, where the application can stall the endpoint to indicate error conditions.
  29. *
  30. * The setup handler, \ref usbfwSetupHandler(), takes care of the low-level parts of these transfers,
  31. * including the IN/OUT buffering during the data phase (when there is one). The transfers fall into two
  32. * categories:
  33. * - Most standard requests are processed internally, with little or no intervention form the user
  34. * application. This is done by the \ref module_usb_standard_requests module.
  35. * - Vendor and class requests are application specific and must always be processed by the application.
  36. * Whenever such a request is received, the following hooks will be called between the phases:
  37. * - \ref usbcrHookProcessOut(): Class requests with OUT data phase
  38. * - \ref usbcrHookProcessIn(): Class requests with IN data phase
  39. * - \ref usbvrHookProcessOut(): Vendor requests with OUT data phase
  40. * - \ref usbvrHookProcessIn(): Vendor requests with IN data phase
  41. *
  42. * \section section_setup_handler_usage Setup Handler Usage
  43. * This section describes what is required to make the vendor and class request hooks work. This
  44. * information also applies to the standard requests that needs application processing
  45. * (\ref usbsrHookSetDescriptor(), \ref usbsrHookSynchFrame(), and some cases of
  46. * \ref usbsrHookSetFeature() and \ref usbsrHookClearFeature()).
  47. *
  48. * The transactions are made using a clean and efficient interface, consisting of two data structures and
  49. * the endpoint 0 status byte:
  50. * - The endpoint status is initially \ref EP_IDLE, which basically means that the setup handler is ready
  51. * for a new setup phase (a new request). Upon an incoming request, the processing hook is called, and
  52. * the \ref usbSetupHeader structure contains the 8 bytes received during the setup phase. At this
  53. * point there are four different outcomes:
  54. * - If the request is unknown or contains errors, the endpoint should be stalled. This is done by
  55. * setting the endpoint status to \ref EP_STALL.
  56. * - If there is no data phase (the length field is zero), the endpoint status should just remain in
  57. * it's current state, \ref EP_IDLE.
  58. * - If the request has an IN data phase, the \ref usbSetupData structure must be prepared. This
  59. * includes setting a pointer to where IN data should be taken from, and the number of bytes to be
  60. * transferred (usually the same number as indicated by the length field, but it can also be a
  61. * lower number). The endpoint state is then changed to \ref EP_TX.
  62. * - If the request has an OUT data phase, the \ref usbSetupData structure must be prepared. This
  63. * includes setting a pointer to where OUT data should be stored, and the number of bytes to be
  64. * transferred (always the same number as indicated by the length field). The endpoint state is
  65. * then changed to \ref EP_RX.
  66. * - When the data phase is complete, the processing hook function will be called a second time to notify
  67. * the application. Under normal conditions the endpoint status will be either \ref EP_TX or \ref EP_RX,
  68. * and does not need to be changed any further (as this is done automatically upon return). If the
  69. * endpoint status is \ref EP_CANCEL, it means that the USB host cancelled the setup transfer.
  70. *
  71. * The following code examples illustrate practical usage (more code is available in the application
  72. * example projects):
  73. *
  74. * \par Example 1: Endpoint 0 Requests With OUT Data phase
  75. *
  76. * \code
  77. * uint8 pLcdBuffer[358];
  78. *
  79. * void usbvrHookProcessOut(void) {
  80. *
  81. * // When this vendor request is received, we should either update a part of pLcdBuffer[] or leave
  82. * // it as it is, and then refresh the LCD display. The index field of the setup header contains the
  83. * // index of the first character to be updated, and the length field how many characters to update.
  84. * if (usbSetupHeader.request == VR_LCD_UPDATE) {
  85. *
  86. * // First the endpoint status is EP_IDLE... (we have just received the Setup packet)
  87. * if (usbfwData.ep0Status == EP_IDLE) {
  88. *
  89. * // There is no new data -> Just refresh the display
  90. * if (usbSetupHeader.length == 0) {
  91. * lcdRefresh();
  92. * // There is no change to the endpoint status in this case
  93. *
  94. * // The PC wants to send data that will be stored outside pLcdBuffer -> stall the endpoint!
  95. * } else if ((usbSetupHeader.length > sizeof(pLcdBuffer) ||
  96. * (usbSetupHeader.index >= sizeof(pLcdBuffer) ||
  97. * ((usbSetupHeader.index + usbSetupHeader.length) > sizeof(pLcdBuffer)) {
  98. * usbfwData.ep0Status = EP_STALL;
  99. *
  100. * // Prepare for OUT data phase, setup the data buffer to receive the LCD data
  101. * } else {
  102. * usbSetupData.pBuffer = &pLcdBuffer[usbSetupHeader.index];
  103. * usbSetupData.bytesLeft = usbSetupHeader.length;
  104. * usbfwData.ep0Status = EP_RX;
  105. * }
  106. *
  107. * // Then the endpoint status is EP_RX (remember: we did that here when setting up the buffer)
  108. * } else if (usbfwData.ep0Status == EP_RX) {
  109. * // usbfwSetupHandler() has now updated pLcdBuffer, so all we need to do is refresh the LCD
  110. * lcdRefresh();
  111. * // usbfwData.ep0Status is automatically reset to EP_IDLE when returning to usbfwSetupHandler()
  112. * }
  113. *
  114. * // Unknown vendor request?
  115. * } else {
  116. * usbfwData.ep0Status = EP_STALL;
  117. * }
  118. * }
  119. * \endcode
  120. *
  121. * \par Example 2: Endpoint 0 Requests With IN Data phase
  122. *
  123. * \code
  124. * uint8 keyBufferPos;
  125. * BOOL blockKeyboard;
  126. * char pKeyBuffer[150];
  127. *
  128. * void usbvrProcessIn(void) {
  129. *
  130. * // When this vendor request is received, we should send all registered key-strokes, and reset the
  131. * // position counter. New keystrokes are blocked during the transfer to avoid overwriting the buffer
  132. * // before it has been sent to the host.
  133. * if (usbSetupHeader.request == VR_GET_KEYS) {
  134. *
  135. * // First the endpoint status is EP_IDLE...
  136. * if (usbfwData.ep0Status == EP_IDLE) {
  137. *
  138. * // Make sure that we do not send more than the PC asked for
  139. * if (usbSetupHeader.length < keyBufferPos) {
  140. * usbfwData.ep0Status = EP_STALL;
  141. *
  142. * // Otherwise...
  143. * } else {
  144. * // Block for new keystrokes
  145. * blockKeyboard = TRUE;
  146. *
  147. * // Setup the buffer
  148. * usbSetupData.pBuffer = pKeyBuffer;
  149. * usbSetupData.bytesLeft = keyBufferPos;
  150. * usbfwData.ep0Status = EP_TX;
  151. *
  152. * // Reset the position counter
  153. * keyBufferPos = 0;
  154. * }
  155. *
  156. * // Then the endpoint status is EP_TX (remember: we did that here when setting up the buffer)
  157. * } else if (usbfwData.ep0Status == EP_TX) {
  158. *
  159. * // pKeyBuffer has now been sent to the host, so new keystrokes can safely be registered
  160. * blockKeyboard = FALSE;
  161. *
  162. * // usbfwData.ep0Status is automatically reset to EP_IDLE when returning to usbfwSetupHandler()
  163. * }
  164. *
  165. * // Unknown request?
  166. * } else {
  167. * usbfwData.ep0Status = EP_STALL;
  168. * }
  169. * }
  170. * \endcode
  171. *
  172. * If automated data transfer is not desired, the application should set \c usbfwData.ep0Status to
  173. * either \ref EP_MANUAL_RX or \ref EP_MANUAL_TX instead of \ref EP_RX or \ref EP_TX, respectively. Until
  174. * the transfer is completed, the processing hook function (e.g. \ref usbvrHookProcessIn()) will be called
  175. * at every endpoint 0 interrupt.
  176. * @{
  177. */
  178. #include "usb_board_cfg.h"
  179. #include "usb_framework_structs.h"
  180. #ifdef EXTERN
  181. #undef EXTERN
  182. #endif
  183. #ifdef USBFRAMEWORK_C
  184. #define EXTERN ///< Definition used only for usb_framework.c
  185. #else
  186. #define EXTERN extern ///< Definition used in other source files to declare external
  187. #endif
  188. //-------------------------------------------------------------------------------------------------------
  189. /// \name Module Data
  190. //@{
  191. EXTERN USBFW_DATA __xdata usbfwData; ///< USBFW internal module data
  192. //@}
  193. //-------------------------------------------------------------------------------------------------------
  194. /// \name Setup Handler Data
  195. //@{
  196. EXTERN USB_SETUP_DATA __xdata usbSetupData; ///< Setup handler data phase configuration
  197. EXTERN USB_SETUP_HEADER __xdata usbSetupHeader; ///< Setup header
  198. //@}
  199. //-------------------------------------------------------------------------------------------------------
  200. //-------------------------------------------------------------------------------------------------------
  201. /// \name Request Type Fields
  202. //@{
  203. // Field masks
  204. #define RT_MASK_DIR 0x80 ///< Request direction bit mask
  205. #define RT_MASK_TYPE 0x60 ///< Request type bit mask
  206. #define RT_MASK_RECIP 0x1F ///< Request recipient bit mask
  207. // Direction field
  208. #define RT_DIR_IN 0x80 ///< IN Request
  209. #define RT_DIR_OUT 0x00 ///< OUT Request
  210. // Type field
  211. #define RT_TYPE_STD 0x00 ///< Standard Request
  212. #define RT_TYPE_CLASS 0x20 ///< Class Request
  213. #define RT_TYPE_VEND 0x40 ///< Vendor Request
  214. // Recipient field
  215. #define RT_RECIP_DEV 0x00 ///< Device Request
  216. #define RT_RECIP_IF 0x01 ///< Interface Request
  217. #define RT_RECIP_EP 0x02 ///< Endpoint Request
  218. #define RT_RECIP_OTHER 0x03 ///< Other Request
  219. // Type + direction
  220. #define RT_STD_OUT (RT_TYPE_STD | RT_DIR_OUT) ///< Standard request, direction is OUT
  221. #define RT_STD_IN (RT_TYPE_STD | RT_DIR_IN) ///< Standard request, direction is IN
  222. #define RT_VEND_OUT (RT_TYPE_VEND | RT_DIR_OUT) ///< Vendor request, direction is OUT
  223. #define RT_VEND_IN (RT_TYPE_VEND | RT_DIR_IN) ///< Vendor request, direction is IN
  224. #define RT_CLASS_OUT (RT_TYPE_CLASS | RT_DIR_OUT) ///< Class request, direction is OUT
  225. #define RT_CLASS_IN (RT_TYPE_CLASS | RT_DIR_IN) ///< Class request, direction is IN
  226. // Direction + recepient
  227. #define RT_OUT_DEVICE (RT_DIR_OUT | RT_RECIP_DEV) ///< Request made to device, direction is OUT
  228. #define RT_IN_DEVICE (RT_DIR_IN | RT_RECIP_DEV) ///< Request made to device, direction is IN
  229. #define RT_OUT_INTERFACE (RT_DIR_OUT | RT_RECIP_IF) ///< Request made to interface, direction is OUT
  230. #define RT_IN_INTERFACE (RT_DIR_IN | RT_RECIP_IF) ///< Request made to interface, direction is IN
  231. #define RT_OUT_ENDPOINT (RT_DIR_OUT | RT_RECIP_EP) ///< Request made to endpoint, direction is OUT
  232. #define RT_IN_ENDPOINT (RT_DIR_IN | RT_RECIP_EP) ///< Request made to endpoint, direction is IN
  233. //@}
  234. //-------------------------------------------------------------------------------------------------------
  235. //-------------------------------------------------------------------------------------------------------
  236. /// \name Vendor and Class Request Hooks
  237. /// Unused hooks must stall endpoint 0.
  238. //@{
  239. /// Hook which is called upon reception of a class request with OUT data phase
  240. void usbcrHookProcessOut(void);
  241. /// Hook which is called upon reception of a class request with IN data phase
  242. void usbcrHookProcessIn(void);
  243. /// Hook which is called upon reception of a vendor request with OUT data phase
  244. void usbvrHookProcessOut(void);
  245. /// Hook which is called upon reception of a vendor request with IN data phase
  246. void usbvrHookProcessIn(void);
  247. //@}
  248. //-------------------------------------------------------------------------------------------------------
  249. //-------------------------------------------------------------------------------------------------------
  250. /// \name Endpoint Access Macros
  251. /// Note that the endpoint control registers are indexed, meaning that an endpoint must be selected
  252. /// before the control operations listed below can be used. Interrupts using any of these macros, must
  253. /// save the current selection and restore it upon return.
  254. //@{
  255. /// Selects which IN/OUT endpoint (by index 0 to 5) to operate on
  256. #define USBFW_SELECT_ENDPOINT(n) (USBINDEX = (n))
  257. /// Gets the currently selected IN/OUT endpoint
  258. #define USBFW_GET_SELECTED_ENDPOINT() (USBINDEX)
  259. /// Stalls the selected IN endpoint
  260. #define USBFW_STALL_IN_ENDPOINT() st (\
  261. USBCSIL = USBCSIL_SEND_STALL; \
  262. usbfwData.pEpInStatus[USBINDEX - 1] = EP_HALT; )
  263. /// Returns the stall condition for the selected IN endpoint
  264. #define USBFW_IN_ENDPOINT_STALLED() (USBCSIL & USBCSIL_SEND_STALL)
  265. /// Flushes the FIFO for the selected IN endpoint (flush twice when using double-buffering)
  266. #define USBFW_FLUSH_IN_ENDPOINT() st (\
  267. USBCSIL = USBCSIL_FLUSH_PACKET; \
  268. while (USBCSIL & USBCSIL_FLUSH_PACKET); )
  269. /// Arms the selected IN endpoint, so that contents of the endpoint FIFO can be sent to the host
  270. #define USBFW_ARM_IN_ENDPOINT() (USBCSIL = USBCSIL_INPKT_RDY)
  271. /// Is the selected IN endpoint disarmed?
  272. #define USBFW_IN_ENDPOINT_DISARMED() !(USBCSIL & USBCSIL_INPKT_RDY)
  273. /// Is the FIFO for the selected IN endpoint empty?
  274. #define USBFW_IN_ENDPOINT_FIFO_EMPTY() !(USBCSIL & USBCSIL_PKT_PRESENT)
  275. /// Stalls the selected OUT endpoint
  276. #define USBFW_STALL_OUT_ENDPOINT() st ( \
  277. USBCSOL = USBCSOL_SEND_STALL; \
  278. usbfwData.pEpOutStatus[USBINDEX - 1] = EP_HALT; \
  279. }
  280. /// Returns the stall condition for the selected OUT endpoint
  281. #define USBFW_OUT_ENDPOINT_STALLED() (USBCSOL & USBCSOL_SEND_STALL)
  282. /// Flushes the FIFO for the selected OUT endpoint (flush twice when using double-buffering)
  283. #define USBFW_FLUSH_OUT_ENDPOINT() st(\
  284. USBCSOL = USBCSOL_FLUSH_PACKET; \
  285. while (USBCSOL & USBCSOL_FLUSH_PACKET); )
  286. /// Arms the selected OUT endpoint, so that the FIFO can receive data from the host
  287. #define USBFW_ARM_OUT_ENDPOINT() (USBCSOL = 0)
  288. /// Is the selected OUT endpoint disarmed? If so, there is data waiting in the FIFO
  289. #define USBFW_OUT_ENDPOINT_DISARMED() (USBCSOL & USBCSOL_OUTPKT_RDY)
  290. /// Returns the number of bytes currently in the FIFO of the selected OUT endpoint, low byte
  291. #define USBFW_GET_OUT_ENDPOINT_COUNT_LOW() (USBCNTL)
  292. /// Returns the number of bytes currently in the FIFO of the selected OUT endpoint, high byte
  293. #define USBFW_GET_OUT_ENDPOINT_COUNT_HIGH() (USBCNTH)
  294. //@}
  295. //-------------------------------------------------------------------------------------------------------
  296. // Little endian
  297. #define LOBYTEPTR(w) ( (uint8 __generic *)(&(w)) + 1 )
  298. // Big endian
  299. //#define LOBYTEPTR(w) ( (uint8 __generic *)&(w) )
  300. //-------------------------------------------------------------------------------------------------------
  301. // Function prototypes
  302. void usbfwInit(void);
  303. void usbfwResetHandler(void);
  304. void usbfwSetupHandler(void);
  305. void usbfwSetAllEpStatus(EP_STATUS status);
  306. void usbfwWriteFifo(uint8 volatile __xdata *pFifo, uint8 count, void __generic *pData);
  307. void usbfwReadFifo(uint8 volatile __xdata *pFifo, uint8 count, void __generic *pData);
  308. //-------------------------------------------------------------------------------------------------------
  309. //@}
  310. /*
  311. +------------------------------------------------------------------------------
  312. | Copyright 2004-2007 Texas Instruments Incorporated. All rights reserved.
  313. |
  314. | IMPORTANT: Your use of this Software is limited to those specific rights
  315. | granted under the terms of a software license agreement between the user who
  316. | downloaded the software, his/her employer (which must be your employer) and
  317. | Texas Instruments Incorporated (the "License"). You may not use this Software
  318. | unless you agree to abide by the terms of the License. The License limits
  319. | your use, and you acknowledge, that the Software may not be modified, copied
  320. | or distributed unless embedded on a Texas Instruments microcontroller or used
  321. | solely and exclusively in conjunction with a Texas Instruments radio
  322. | frequency transceiver, which is integrated into your product. Other than for
  323. | the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  324. | works of, modify, distribute, perform, display or sell this Software and/or
  325. | its documentation for any purpose.
  326. |
  327. | YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  328. | PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  329. | INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  330. | NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  331. | TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  332. | NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  333. | LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING
  334. | BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
  335. | CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
  336. | SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  337. | (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  338. |
  339. | Should you have any questions regarding your right to use this Software,
  340. | contact Texas Instruments Incorporated at www.TI.com.
  341. |
  342. +------------------------------------------------------------------------------
  343. */
  344. #endif