usb_standard_requests.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. /***********************************************************************************
  2. Filename: usb_standard_request.c
  3. Description: Handle USB standard requests.
  4. ***********************************************************************************/
  5. /// \addtogroup module_usb_standard_requests
  6. /// @{
  7. #include "usb_firmware_library_headers.h"
  8. #include "hal_types.h"
  9. #include "hal_board.h"
  10. /** \brief Processes the \ref GET_STATUS request (returns status for the specified recipient)
  11. *
  12. * The recipient bits in \ref USB_SETUP_HEADER.requestType specify the desired recipient. This is either the
  13. * (one and only) device, a specific interface, or a specific endpoint. Some of the status bits can be
  14. * changed with the SET_FEATURE and CLEAR_FEATURE requests.
  15. *
  16. * <b>Parameters</b>:
  17. * - VALUE: Always 0
  18. * - INDEX: Depends upon the recipient:
  19. * - DEVICE: Always 0
  20. * - INTERFACE: Interface number
  21. * - ENDPOINT: Endpoint address
  22. * - LENGTH: Always 2
  23. *
  24. * <b>Data (IN)</b>:
  25. * Depends upon the recipient (the bit field illustrations are MSB first, LSB last):
  26. * - DEVICE: <tt>00000000.000000RS</tt>, where R(1) = DEVICE_REMOTE_WAKEUP and S(0) = SELF_POWERED
  27. * - INTERFACE: <tt>00000000.00000000</tt> (all bits are reserved)
  28. * - ENDPOINT: <tt>00000000.0000000H</tt>, where H(0) = ENDPOINT_HALT
  29. */
  30. void usbsrGetStatus(void)
  31. {
  32. uint8 endpoint;
  33. static uint16 __xdata status;
  34. // Common sanity check
  35. if (usbSetupHeader.value || HI_UINT16(usbSetupHeader.index) || (usbSetupHeader.length != 2)) {
  36. usbfwData.ep0Status = EP_STALL;
  37. // Return status for device, interface, or endpoint
  38. } else {
  39. switch (usbSetupHeader.requestType) {
  40. // Device status:
  41. // Bit 0: Self powered
  42. // Bit 1: Remote wake-up allowed
  43. case RT_IN_DEVICE:
  44. // Sanity check
  45. if (LO_UINT16(usbSetupHeader.index)) {
  46. usbfwData.ep0Status = EP_STALL;
  47. // Get the bit values from the USBFW_DATA struct
  48. } else {
  49. // Self powered?
  50. status = usbfwData.selfPowered ? 0x0001 : 0x0000;
  51. // Remote wakeup?
  52. if (usbfwData.remoteWakeup) status |= 0x0002;
  53. }
  54. break;
  55. // Interface status:
  56. // All bits are reserved
  57. case RT_IN_INTERFACE:
  58. // Sanity check
  59. if (usbfwData.usbState != DEV_CONFIGURED) {
  60. usbfwData.ep0Status = EP_STALL;
  61. } else {
  62. status = 0x0000;
  63. }
  64. break;
  65. // Endpoint status:
  66. // Bit 0: Endpoint halted
  67. case RT_IN_ENDPOINT:
  68. endpoint = LO_UINT16(usbSetupHeader.index) & 0x7F;
  69. // Sanity check
  70. if ((usbfwData.usbState != DEV_CONFIGURED) || (endpoint > 5)) {
  71. usbfwData.ep0Status = EP_STALL;
  72. // Translate endpoint address to status index and return the status
  73. } else {
  74. // IN
  75. if (LO_UINT16(usbSetupHeader.index) & 0x80) {
  76. status = (usbfwData.pEpInStatus[endpoint - 1] == EP_HALT) ? 0x0001 : 0x0000;
  77. // OUT
  78. } else {
  79. status = (usbfwData.pEpOutStatus[endpoint - 1] == EP_HALT) ? 0x0001 : 0x0000;
  80. }
  81. }
  82. break;
  83. default:
  84. usbfwData.ep0Status = EP_STALL;
  85. break;
  86. }
  87. if (usbfwData.ep0Status != EP_STALL) {
  88. // Send it
  89. usbSetupData.pBuffer = (uint8 __generic *)&status;
  90. usbSetupData.bytesLeft = 2;
  91. usbfwData.ep0Status = EP_TX;
  92. }
  93. }
  94. } // usbsrGetStatus
  95. /** \brief Internal function used for the very similar \ref SET_FEATURE and \ref CLEAR_FEATURE requests
  96. *
  97. * This function either sets or clears the specified feature on the specified recipient.
  98. *
  99. * \param[in] set
  100. * When TRUE, the feature is set. When FALSE, the feature is cleared.
  101. *
  102. * \return
  103. * TRUE if the selected feature is supported by the USB library. FALSE to indicate that
  104. * \ref usbsrHookClearFeature() or \ref usbsrHookSetFeature() must be called.
  105. */
  106. static uint8 ChangeFeature(uint8 set)
  107. {
  108. uint8 endpoint;
  109. // Sanity check
  110. if (usbSetupHeader.length || (usbfwData.usbState != DEV_CONFIGURED) && (usbSetupHeader.index != 0)) {
  111. usbfwData.ep0Status = EP_STALL;
  112. // Handle based on recipient
  113. } else {
  114. switch (usbSetupHeader.requestType & RT_MASK_RECIP) {
  115. // Device
  116. case RT_RECIP_DEV:
  117. // Sanity check
  118. if (LO_UINT16(usbSetupHeader.value) != DEVICE_REMOTE_WAKEUP) {
  119. return FALSE;
  120. } else {
  121. usbfwData.remoteWakeup = set;
  122. usbsrHookProcessEvent(set ? USBSR_EVENT_REMOTE_WAKEUP_ENABLED : USBSR_EVENT_REMOTE_WAKEUP_DISABLED, 0);
  123. }
  124. break;
  125. // Endpoint
  126. case RT_RECIP_IF:
  127. return FALSE;
  128. // Endpoint
  129. case RT_RECIP_EP:
  130. endpoint = LO_UINT16(usbSetupHeader.index) & 0x7F;
  131. // Sanity check
  132. if (LO_UINT16(usbSetupHeader.value) != ENDPOINT_HALT) {
  133. return FALSE;
  134. } else if (endpoint > 5) {
  135. usbfwData.ep0Status = EP_STALL;
  136. } else {
  137. USBFW_SELECT_ENDPOINT(endpoint);
  138. // IN
  139. if (LO_UINT16(usbSetupHeader.index) & 0x80) {
  140. USBCSIL = set ? USBCSIL_SEND_STALL : USBCSIL_CLR_DATA_TOG;
  141. usbfwData.pEpInStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE;
  142. usbsrHookProcessEvent(set ? USBSR_EVENT_EPIN_STALL_SET : USBSR_EVENT_EPIN_STALL_CLEARED, endpoint);
  143. // OUT
  144. } else {
  145. USBCSOL = set ? USBCSOL_SEND_STALL : USBCSOL_CLR_DATA_TOG;
  146. usbfwData.pEpOutStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE;
  147. usbsrHookProcessEvent(set ? USBSR_EVENT_EPOUT_STALL_SET : USBSR_EVENT_EPOUT_STALL_CLEARED, endpoint);
  148. }
  149. USBFW_SELECT_ENDPOINT(0);
  150. }
  151. break;
  152. default:
  153. usbfwData.ep0Status = EP_STALL;
  154. break;
  155. }
  156. }
  157. return TRUE;
  158. } // ChangeFeature
  159. /** \brief Processes the \ref CLEAR_FEATURE request (clears or disables a specific feature)
  160. *
  161. * The feature selector value must be appropriate to the recipient.
  162. *
  163. * <b>Parameters</b>:
  164. * - VALUE: Feature selector:
  165. * - \c DEVICE_REMOTE_WAKEUP(1): Enable remote wakeup
  166. * - \c ENDPOINT_HALT(0): Clear the halt feature for the specified endpoint (not endpoint 0!)
  167. * - INDEX: Depends upon the recipient:
  168. * - DEVICE: Always 0
  169. * - INTERFACE: Interface number
  170. * - ENDPOINT: Endpoint address
  171. * - LENGTH: Always 0
  172. */
  173. void usbsrClearFeature()
  174. {
  175. if (!ChangeFeature(FALSE)) {
  176. usbsrHookClearFeature();
  177. }
  178. } // usbsrClearFeature
  179. /** \brief Processes the \ref SET_FEATURE request (sets or enables a specific feature)
  180. *
  181. * The feature selector value must be appropriate to the recipient.
  182. *
  183. * <b>Parameters</b>:
  184. * - VALUE: Feature selector:
  185. * - \c DEVICE_REMOTE_WAKEUP(1): Enable remote wakeup
  186. * - \c ENDPOINT_HALT(0): Set the halt feature for the specified endpoint (not endpoint 0!)
  187. * - INDEX: Depends upon the recipient:
  188. * - DEVICE: Always 0
  189. * - INTERFACE: Interface number
  190. * - ENDPOINT: Endpoint address
  191. * - LENGTH: Always 0
  192. */
  193. void usbsrSetFeature(void)
  194. {
  195. if (!ChangeFeature(TRUE)) {
  196. usbsrHookSetFeature();
  197. }
  198. } // usbsrSetFeature
  199. /** \brief Processes the \ref SET_ADDRESS request (sets the device address for all future device
  200. * accesses)
  201. *
  202. * If the value is between 1 and 127 and the device is in the default state, it will enter the address
  203. * state. If it already is in the address state, it starts to use the newly-specified address.
  204. *
  205. * If the value is 0 and the device is in the address state, it will enter the default state. If it
  206. * already is in the default state, nothing happens.
  207. *
  208. * <b>Parameters</b>:
  209. * - VALUE: The device address (0-127)
  210. * - INDEX: Always 0
  211. * - LENGTH: Always 0
  212. */
  213. void usbsrSetAddress(void)
  214. {
  215. // Sanity check
  216. if (usbSetupHeader.index || usbSetupHeader.length || HI_UINT16(usbSetupHeader.value) || (LO_UINT16(usbSetupHeader.value) & 0x80)) {
  217. usbfwData.ep0Status = EP_STALL;
  218. // Update the device address
  219. } else {
  220. USBADDR = LO_UINT16(usbSetupHeader.value);
  221. if (LO_UINT16(usbSetupHeader.value) != 0) {
  222. if (usbfwData.usbState == DEV_DEFAULT) usbfwData.usbState = DEV_ADDRESS;
  223. } else {
  224. if (usbfwData.usbState == DEV_ADDRESS) usbfwData.usbState = DEV_DEFAULT;
  225. }
  226. }
  227. } // usbsrSetAddress
  228. /** \brief Processes the \ref GET_DESCRIPTOR request (returns the specified USB descriptor)
  229. *
  230. * The \ref module_usb_descriptor_parser module is used to locate device, configuration and string
  231. * descriptors. Note that configuration descriptors also include interface, endpoint and other
  232. * "similar" descriptor types (e.g. HID descriptor), with the total descriptor length specified by
  233. * the \ref USB_CONFIGURATION_DESCRIPTOR.wTotalLength field.
  234. *
  235. * Other descriptor types that are not returned with the configuration descriptor, must be defined in
  236. * the usbDescriptorMarker.pUsbDescLut lookup-table. This table specifies the values of the VALUE and INDEX fields, and
  237. * gives a pointer to the descriptor along with it's length.
  238. *
  239. * <b>Parameters</b>:
  240. * - VALUE.MSB: Descriptor type
  241. * - VALUE.LSB: Descriptor index
  242. * - INDEX: 0, or language ID for string descriptors (currently not supported)
  243. * - LENGTH: Descriptor length (either the requested number of bytes, or the length of the descriptor,
  244. * whichever is the smallest)
  245. *
  246. * <b>Data (IN)</b>:
  247. * The descriptor(s)
  248. */
  249. void usbsrGetDescriptor(void)
  250. {
  251. uint8 n;
  252. // Which descriptor?
  253. switch (HI_UINT16(usbSetupHeader.value)) {
  254. // Device descriptor
  255. case DESC_TYPE_DEVICE:
  256. usbSetupData.pBuffer = (uint8 __code*) usbdpGetDeviceDesc();
  257. usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
  258. break;
  259. // Configuration descriptor
  260. case DESC_TYPE_CONFIG:
  261. usbSetupData.pBuffer = (uint8 __code*) usbdpGetConfigurationDesc(0, LO_UINT16(usbSetupHeader.value));
  262. usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_CONFIG_LENGTH_LSB_IDX] +
  263. usbSetupData.pBuffer[DESC_CONFIG_LENGTH_MSB_IDX] * 256;
  264. break;
  265. // String descriptor
  266. case DESC_TYPE_STRING:
  267. // TODO: Implement language ID
  268. usbSetupData.pBuffer = (uint8 *)usbdpGetStringDesc(LO_UINT16(usbSetupHeader.value));
  269. usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
  270. break;
  271. // Other descriptor type
  272. default:
  273. // Perform a table search (on index and value)
  274. usbSetupData.pBuffer = NULL;
  275. for (n = 0; n < ((uint16)usbDescriptorMarker.pUsbDescLutEnd - (uint16)usbDescriptorMarker.pUsbDescLut) / sizeof(DESC_LUT_INFO); n++) {
  276. if ((usbDescriptorMarker.pUsbDescLut[n].valueMsb == HI_UINT16(usbSetupHeader.value))
  277. && (usbDescriptorMarker.pUsbDescLut[n].valueLsb == LO_UINT16(usbSetupHeader.value))
  278. && (usbDescriptorMarker.pUsbDescLut[n].indexMsb == HI_UINT16(usbSetupHeader.index))
  279. && (usbDescriptorMarker.pUsbDescLut[n].indexLsb == LO_UINT16(usbSetupHeader.index)) )
  280. {
  281. usbSetupData.pBuffer = usbDescriptorMarker.pUsbDescLut[n].pDescStart;
  282. usbSetupData.bytesLeft = usbDescriptorMarker.pUsbDescLut[n].length;
  283. }
  284. }
  285. }
  286. // Stall EP0 if no descriptor was found
  287. if (usbSetupData.pBuffer == NULL) usbfwData.ep0Status = EP_STALL;
  288. if (usbfwData.ep0Status != EP_STALL) {
  289. // Limit the returned descriptor size (the PC wants to know about sizes before
  290. // polling the complete descriptors)
  291. if (usbSetupData.bytesLeft > usbSetupHeader.length) {
  292. usbSetupData.bytesLeft = usbSetupHeader.length;
  293. }
  294. usbfwData.ep0Status = EP_TX;
  295. }
  296. } // usbsrGetDescriptor
  297. /** \brief Internally used function that configures all endpoints for the specified interface
  298. *
  299. * The new endpoint setup overwrites the old, without any warning. Unused endpoints keep their current
  300. * setup. The user is responsible for ensuring that no endpoint buffers overwrite each other, and that
  301. * interfaces do not cause conflicts. The pUsbDblbufLutInfo table must contain an entry for each
  302. * interface descriptor to define endpoint double-buffering.
  303. *
  304. * \param[in] *pInterface
  305. * A pointer to the interface descriptor
  306. */
  307. static void ConfigureEndpoints(USB_INTERFACE_DESCRIPTOR __code *pInterface)
  308. {
  309. uint8 n;
  310. uint16 maxpRegValue;
  311. uint8 csRegValue;
  312. uint8 endpoint;
  313. USB_ENDPOINT_DESCRIPTOR __code *pEndpoint;
  314. DBLBUF_LUT_INFO __code *pUsbDblbufLutInfo;
  315. // Locate the double buffer settings
  316. if (pInterface->bNumEndpoints) {
  317. pUsbDblbufLutInfo = (DBLBUF_LUT_INFO __code*) usbDescriptorMarker.pUsbDblbufLut;
  318. while (pUsbDblbufLutInfo->pInterface != pInterface) {
  319. pUsbDblbufLutInfo++;
  320. }
  321. }
  322. // For each endpoint in this interface
  323. for (n = 0; n < pInterface->bNumEndpoints; n++) {
  324. if (pEndpoint = usbdpFindNext(DESC_TYPE_ENDPOINT, 0)) {
  325. // Get the endpoint index
  326. endpoint = pEndpoint->bEndpointAddress & 0x0F;
  327. USBFW_SELECT_ENDPOINT(endpoint);
  328. csRegValue = 0x00;
  329. maxpRegValue = (pEndpoint->wMaxPacketSize + 7) >> 3;
  330. // For IN endpoints...
  331. if (pEndpoint->bEndpointAddress & 0x80) {
  332. // Clear data toggle, and flush twice (due to double buffering)
  333. USBCSIL = USBCSIL_CLR_DATA_TOG | USBCSIL_FLUSH_PACKET;
  334. USBCSIL = USBCSIL_FLUSH_PACKET;
  335. // USBCSIH
  336. if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSIH_ISO; // ISO flag
  337. if (pUsbDblbufLutInfo->inMask & (1 << endpoint)) csRegValue |= USBCSIH_IN_DBL_BUF; // Double buffering
  338. USBCSIH = csRegValue;
  339. // Max transfer size
  340. USBMAXI = maxpRegValue;
  341. // Endpoint status
  342. usbfwData.pEpInStatus[endpoint - 1] = EP_IDLE;
  343. // For OUT endpoints...
  344. } else {
  345. // Clear data toggle, and flush twice (due to double buffering)
  346. USBCSOL = USBCSOL_CLR_DATA_TOG | USBCSOL_FLUSH_PACKET;
  347. USBCSOL = USBCSOL_FLUSH_PACKET;
  348. // USBCSOH
  349. if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSOH_ISO; // ISO flag
  350. if (pUsbDblbufLutInfo->outMask & (1 << endpoint)) csRegValue |= USBCSOH_OUT_DBL_BUF; // Double buffering
  351. USBCSOH = csRegValue;
  352. // Max transfer size
  353. USBMAXO = maxpRegValue;
  354. // Endpoint status
  355. usbfwData.pEpOutStatus[endpoint - 1] = EP_IDLE;
  356. }
  357. USBFW_SELECT_ENDPOINT(0);
  358. }
  359. }
  360. } // ConfigureEndpoints
  361. /** \brief Processes the \ref GET_CONFIGURATION request (returns the current device configuration value)
  362. *
  363. * If the returned value is 0, the device is not configured (not in the configured state)
  364. *
  365. * <b>Parameters</b>:
  366. * - VALUE: Always 0
  367. * - INDEX: Always 0
  368. * - LENGTH: Always 1
  369. *
  370. * <b>Data (IN)</b>:
  371. * The non-zero \ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue of the currently selected
  372. * configuration.
  373. */
  374. void usbsrGetConfiguration(void)
  375. {
  376. // Sanity check
  377. if (usbSetupHeader.value || usbSetupHeader.index || (usbSetupHeader.length != 1)) {
  378. usbfwData.ep0Status = EP_STALL;
  379. // Return the current configuration
  380. } else {
  381. usbSetupData.pBuffer = &usbfwData.configurationValue;
  382. usbSetupData.bytesLeft = 1;
  383. usbfwData.ep0Status = EP_TX;
  384. }
  385. } // usbsrGetConfiguration
  386. /** \brief Processes the \ref SET_CONFIGURATION request (sets the device configuration)
  387. *
  388. * The configuration value must either be 0, in which case the device enters the address state, or it
  389. * must match a configuration value from one of the USB configuration descriptors. If there is a match,
  390. * the device enters the configured state.
  391. *
  392. * This request resets all interfaces to alternate setting 0, and uses the \c ConfigureEndpoints()
  393. * function to automatically setup all endpoint registers.
  394. *
  395. * <b>Parameters</b>:
  396. * - VALUE: The configuration value (0-255)
  397. * - INDEX: Always 0
  398. * - LENGTH: Always 0
  399. */
  400. void usbsrSetConfiguration(void)
  401. {
  402. uint8 n;
  403. USB_CONFIGURATION_DESCRIPTOR __code *pConfiguration;
  404. USB_INTERFACE_DESCRIPTOR __code *pInterface;
  405. // Sanity check
  406. if ((usbfwData.usbState == DEV_DEFAULT) || usbSetupHeader.index || usbSetupHeader.length || HI_UINT16(usbSetupHeader.value)) {
  407. usbfwData.ep0Status = EP_STALL;
  408. // Default endpoint setup
  409. } else {
  410. usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGING, 0);
  411. // Configure relevant endpoints
  412. if (LO_UINT16(usbSetupHeader.value)) {
  413. // Find the correct configuration descriptor...
  414. pConfiguration = usbdpGetConfigurationDesc(LO_UINT16(usbSetupHeader.value), 0);
  415. // If it exists...
  416. if (pConfiguration) {
  417. usbfwData.usbState = DEV_CONFIGURED;
  418. usbfwData.configurationValue = LO_UINT16(usbSetupHeader.value);
  419. // For each interface...
  420. for (n = 0; n < pConfiguration->bNumInterfaces; n++) {
  421. usbfwData.pAlternateSetting[n] = 0x00;
  422. // Look only for alternate setting 0
  423. do {
  424. pInterface = usbdpFindNext(DESC_TYPE_INTERFACE, 0);
  425. } while (pInterface->bAlternateSetting != usbfwData.pAlternateSetting[n]);
  426. // Configure all endpoints in this interface
  427. ConfigureEndpoints(pInterface);
  428. }
  429. // If not, then stall the endpoint
  430. } else {
  431. usbfwData.ep0Status = EP_STALL;
  432. }
  433. // Unconfigure endpoints
  434. } else {
  435. usbfwData.configurationValue = LO_UINT16(usbSetupHeader.value);
  436. usbfwData.usbState = DEV_ADDRESS;
  437. usbfwSetAllEpStatus(EP_HALT);
  438. }
  439. usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGED, 0);
  440. }
  441. } // usbsrSetConfiguration
  442. /** \brief Processes the \ref GET_INTERFACE request (returns the selected alternate setting for the
  443. * specified interface)
  444. *
  445. * Some USB devices have configurations with mutually exclusive interface settings. This request allows
  446. * the host to determine the currently selected alternate setting.
  447. *
  448. * <b>Parameters</b>:
  449. * - VALUE: Always 0
  450. * - INDEX: Interface number
  451. * - LENGTH: Always 1
  452. *
  453. * <b>Data (IN)</b>:
  454. * The alternate setting for the selected interface
  455. */
  456. void usbsrGetInterface(void)
  457. {
  458. // Sanity check
  459. if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_IN_INTERFACE) || usbSetupHeader.value || (usbSetupHeader.length != 1)) {
  460. usbfwData.ep0Status = EP_STALL;
  461. // Return the current alternate setting
  462. } else {
  463. usbSetupData.pBuffer = &usbfwData.pAlternateSetting[usbSetupHeader.index];
  464. usbSetupData.bytesLeft = 1;
  465. usbfwData.ep0Status = EP_TX;
  466. }
  467. } // usbsrGetInterface
  468. /** \brief Processes the \ref SET_INTERFACE request (selects an alternate setting for the specified
  469. * interface)
  470. *
  471. * Some USB devices have configurations with mutually exclusive interface settings. This request allows
  472. * the host to select the desired alternate setting.
  473. *
  474. * This function uses the \c ConfigureEndpoints() to automatically setup the relevant endpoint
  475. * registers.
  476. *
  477. * <b>Parameters</b>:
  478. * - VALUE: Alternate setting
  479. * - INDEX: Interface number
  480. * - LENGTH: Always 0
  481. */
  482. void usbsrSetInterface(void)
  483. {
  484. USB_INTERFACE_DESCRIPTOR __code *pInterface;
  485. // Sanity check
  486. if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_OUT_INTERFACE) || usbSetupHeader.length) {
  487. usbfwData.ep0Status = EP_STALL;
  488. // Verify that the desired alternate setting is available, and then make the switch
  489. } else {
  490. if (pInterface = usbdpGetInterfaceDesc(usbfwData.configurationValue, usbSetupHeader.index, usbSetupHeader.value)) {
  491. usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGING, usbSetupHeader.index);
  492. usbfwData.pAlternateSetting[usbSetupHeader.index] = usbSetupHeader.value;
  493. // Configure all endpoints in this interface
  494. ConfigureEndpoints(pInterface);
  495. usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGED, usbSetupHeader.index);
  496. // This interface does not exist
  497. } else {
  498. usbfwData.ep0Status = EP_STALL;
  499. }
  500. }
  501. } // usbsrSetInterface
  502. //@}
  503. /*
  504. +------------------------------------------------------------------------------
  505. | Copyright 2004-2010 Texas Instruments Incorporated. All rights reserved.
  506. |
  507. | IMPORTANT: Your use of this Software is limited to those specific rights
  508. | granted under the terms of a software license agreement between the user who
  509. | downloaded the software, his/her employer (which must be your employer) and
  510. | Texas Instruments Incorporated (the "License"). You may not use this Software
  511. | unless you agree to abide by the terms of the License. The License limits
  512. | your use, and you acknowledge, that the Software may not be modified, copied
  513. | or distributed unless embedded on a Texas Instruments microcontroller or used
  514. | solely and exclusively in conjunction with a Texas Instruments radio
  515. | frequency transceiver, which is integrated into your product. Other than for
  516. | the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  517. | works of, modify, distribute, perform, display or sell this Software and/or
  518. | its documentation for any purpose.
  519. |
  520. | YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  521. | PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  522. | INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  523. | NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  524. | TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  525. | NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  526. | LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING
  527. | BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
  528. | CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
  529. | SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  530. | (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  531. |
  532. | Should you have any questions regarding your right to use this Software,
  533. | contact Texas Instruments Incorporated at www.TI.com.
  534. |
  535. +------------------------------------------------------------------------------
  536. */