usb_device_ch9.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
  4. * Copyright 2016-2017 NXP
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted (subject to the limitations in the disclaimer below) provided
  9. * that the following conditions are met:
  10. *
  11. * o Redistributions of source code must retain the above copyright notice, this list
  12. * of conditions and the following disclaimer.
  13. *
  14. * o Redistributions in binary form must reproduce the above copyright notice, this
  15. * list of conditions and the following disclaimer in the documentation and/or
  16. * other materials provided with the distribution.
  17. *
  18. * o Neither the name of the copyright holder nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include "usb_device_config.h"
  35. #include "usb.h"
  36. #include "usb_device.h"
  37. #include "usb_device_dci.h"
  38. #include "usb_device_ch9.h"
  39. /*******************************************************************************
  40. * Definitions
  41. ******************************************************************************/
  42. /*!
  43. * @brief Standard request callback function typedef.
  44. *
  45. * This function is used to handle the standard request.
  46. *
  47. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  48. * @param setup The pointer of the setup packet.
  49. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  50. * @param length It is an out parameter, the data length.
  51. *
  52. * @return A USB error code or kStatus_USB_Success.
  53. */
  54. typedef usb_status_t (*usb_standard_request_callback_t)(usb_device_handle handle,
  55. usb_setup_struct_t *setup,
  56. uint8_t **buffer,
  57. uint32_t *length);
  58. /*******************************************************************************
  59. * Prototypes
  60. ******************************************************************************/
  61. /*!
  62. * @brief Get the setup packet buffer.
  63. *
  64. * The function is used to get the setup packet buffer to save the setup packet data.
  65. *
  66. * @param handle The device handle.
  67. * @param setupBuffer It is an OUT parameter, return the setup buffer address to the caller.
  68. *
  69. * @return A USB error code or kStatus_USB_Success.
  70. */
  71. extern usb_status_t USB_DeviceGetSetupBuffer(usb_device_handle handle, usb_setup_struct_t **setupBuffer);
  72. /*!
  73. * @brief Handle the class request.
  74. *
  75. * The function is used to handle the class request.
  76. *
  77. * @param handle The device handle.
  78. * @param setup The setup packet buffer address.
  79. * @param length It is an OUT parameter, return the data length need to be sent to host.
  80. * @param buffer It is an OUT parameter, return the data buffer address.
  81. *
  82. * @return A USB error code or kStatus_USB_Success.
  83. */
  84. extern usb_status_t USB_DeviceProcessClassRequest(usb_device_handle handle,
  85. usb_setup_struct_t *setup,
  86. uint32_t *length,
  87. uint8_t **buffer);
  88. /*!
  89. * @brief Get the buffer to save the class specific data sent from host.
  90. *
  91. * The function is used to get the buffer to save the class specific data sent from host.
  92. * The function will be called when the device receives a setup pakcet, and the host needs to send data to the device in
  93. * the data stage.
  94. *
  95. * @param handle The device handle.
  96. * @param setup The setup packet buffer address.
  97. * @param length Pass the length the host needs to sent.
  98. * @param buffer It is an OUT parameter, return the data buffer address to save the host's data.
  99. *
  100. * @return A USB error code or kStatus_USB_Success.
  101. */
  102. extern usb_status_t USB_DeviceGetClassReceiveBuffer(usb_device_handle handle,
  103. usb_setup_struct_t *setup,
  104. uint32_t *length,
  105. uint8_t **buffer);
  106. /* standard request */
  107. /*!
  108. * @brief Get the descritpor.
  109. *
  110. * The function is used to get the descritpor, including the device descritpor, configuration descriptor, and string
  111. * descriptor, etc.
  112. *
  113. * @param handle The device handle.
  114. * @param setup The setup packet buffer address.
  115. * @param length It is an OUT parameter, return the data length need to be sent to host.
  116. * @param buffer It is an OUT parameter, return the data buffer address.
  117. *
  118. * @return A USB error code or kStatus_USB_Success.
  119. */
  120. extern usb_status_t USB_DeviceGetDescriptor(usb_device_handle handle,
  121. usb_setup_struct_t *setup,
  122. uint32_t *length,
  123. uint8_t **buffer);
  124. /*!
  125. * @brief Set the device configuration.
  126. *
  127. * The function is used to set the device configuration.
  128. *
  129. * @param handle The device handle.
  130. * @param configure The configuration value.
  131. *
  132. * @return A USB error code or kStatus_USB_Success.
  133. */
  134. extern usb_status_t USB_DeviceSetConfigure(usb_device_handle handle, uint8_t configure);
  135. /*!
  136. * @brief Get the device configuration.
  137. *
  138. * The function is used to get the device configuration.
  139. *
  140. * @param handle The device handle.
  141. * @param configure It is an OUT parameter, save the current configuration value.
  142. *
  143. * @return A USB error code or kStatus_USB_Success.
  144. */
  145. extern usb_status_t USB_DeviceGetConfigure(usb_device_handle handle, uint8_t *configure);
  146. /*!
  147. * @brief Set an interface alternate setting.
  148. *
  149. * The function is used to set an interface alternate setting.
  150. *
  151. * @param handle The device handle.
  152. * @param interface The interface index.
  153. * @param alternateSetting The new alternate setting value.
  154. *
  155. * @return A USB error code or kStatus_USB_Success.
  156. */
  157. extern usb_status_t USB_DeviceSetInterface(usb_device_handle handle, uint8_t interface, uint8_t alternateSetting);
  158. /*!
  159. * @brief Get an interface alternate setting.
  160. *
  161. * The function is used to get an interface alternate setting.
  162. *
  163. * @param handle The device handle.
  164. * @param interface The interface index.
  165. * @param alternateSetting It is an OUT parameter, save the new alternate setting value of the interface.
  166. *
  167. * @return A USB error code or kStatus_USB_Success.
  168. */
  169. extern usb_status_t USB_DeviceGetInterface(usb_device_handle handle, uint8_t interface, uint8_t *alternateSetting);
  170. /*!
  171. * @brief Configure a specified endpoint status.
  172. *
  173. * The function is used to configure a specified endpoint status, idle or halt.
  174. *
  175. * @param handle The device handle.
  176. * @param endpointAddress The endpoint address, the BIT7 is the direction, 0 - USB_OUT, 1 - USB_IN.
  177. * @param status The new status of the endpoint, 0 - idle, 1 - halt.
  178. *
  179. * @return A USB error code or kStatus_USB_Success.
  180. */
  181. extern usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle,
  182. uint8_t endpointAddress,
  183. uint8_t status);
  184. /*!
  185. * @brief Configure the device remote wakeup feature.
  186. *
  187. * The function is used to configure the device remote wakeup feature, enable or disbale the remote wakeup feature.
  188. *
  189. * @param handle The device handle.
  190. * @param enable The new feature value of the device remote wakeup, 0 - disable, 1 - enable.
  191. *
  192. * @return A USB error code or kStatus_USB_Success.
  193. */
  194. extern usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable);
  195. static usb_status_t USB_DeviceCh9GetStatus(usb_device_handle handle,
  196. usb_setup_struct_t *setup,
  197. uint8_t **buffer,
  198. uint32_t *length);
  199. static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_handle handle,
  200. usb_setup_struct_t *setup,
  201. uint8_t **buffer,
  202. uint32_t *length);
  203. static usb_status_t USB_DeviceCh9SetAddress(usb_device_handle handle,
  204. usb_setup_struct_t *setup,
  205. uint8_t **buffer,
  206. uint32_t *length);
  207. static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_handle handle,
  208. usb_setup_struct_t *setup,
  209. uint8_t **buffer,
  210. uint32_t *length);
  211. static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_handle handle,
  212. usb_setup_struct_t *setup,
  213. uint8_t **buffer,
  214. uint32_t *length);
  215. static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_handle handle,
  216. usb_setup_struct_t *setup,
  217. uint8_t **buffer,
  218. uint32_t *length);
  219. static usb_status_t USB_DeviceCh9GetInterface(usb_device_handle handle,
  220. usb_setup_struct_t *setup,
  221. uint8_t **buffer,
  222. uint32_t *length);
  223. static usb_status_t USB_DeviceCh9SetInterface(usb_device_handle handle,
  224. usb_setup_struct_t *setup,
  225. uint8_t **buffer,
  226. uint32_t *length);
  227. static usb_status_t USB_DeviceCh9SynchFrame(usb_device_handle handle,
  228. usb_setup_struct_t *setup,
  229. uint8_t **buffer,
  230. uint32_t *length);
  231. /*******************************************************************************
  232. * Variables
  233. ******************************************************************************/
  234. /* The function list to handle the standard request. */
  235. static const usb_standard_request_callback_t s_UsbDeviceStandardRequest[] = {
  236. USB_DeviceCh9GetStatus,
  237. USB_DeviceCh9SetClearFeature,
  238. (usb_standard_request_callback_t)NULL,
  239. USB_DeviceCh9SetClearFeature,
  240. (usb_standard_request_callback_t)NULL,
  241. USB_DeviceCh9SetAddress,
  242. USB_DeviceCh9GetDescriptor,
  243. (usb_standard_request_callback_t)NULL, /* USB_DeviceCh9SetDescriptor */
  244. USB_DeviceCh9GetConfiguration,
  245. USB_DeviceCh9SetConfiguration,
  246. USB_DeviceCh9GetInterface,
  247. USB_DeviceCh9SetInterface,
  248. USB_DeviceCh9SynchFrame,
  249. };
  250. /*
  251. * The internal global variable.
  252. * This variable is used in:
  253. * get status request
  254. * get configuration request
  255. * get interface request
  256. * set interface request
  257. * get sync frame request
  258. */
  259. static uint16_t s_UsbDeviceStandardRx;
  260. /*******************************************************************************
  261. * Code
  262. ******************************************************************************/
  263. /*!
  264. * @brief Handle get status request.
  265. *
  266. * This function is used to handle get status request.
  267. *
  268. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  269. * @param setup The pointer of the setup packet.
  270. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  271. * @param length It is an out parameter, the data length.
  272. *
  273. * @retval kStatus_USB_Success The requst is handled successfully.
  274. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
  275. * or, the request is unsupported.
  276. */
  277. static usb_status_t USB_DeviceCh9GetStatus(usb_device_handle handle,
  278. usb_setup_struct_t *setup,
  279. uint8_t **buffer,
  280. uint32_t *length)
  281. {
  282. usb_status_t error = kStatus_USB_InvalidRequest;
  283. uint8_t state;
  284. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  285. if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state))
  286. {
  287. return error;
  288. }
  289. if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
  290. {
  291. /* Get the device status */
  292. error = USB_DeviceGetStatus(handle, kUSB_DeviceStatusDevice, &s_UsbDeviceStandardRx);
  293. s_UsbDeviceStandardRx = s_UsbDeviceStandardRx & USB_GET_STATUS_DEVICE_MASK;
  294. s_UsbDeviceStandardRx = USB_SHORT_TO_LITTLE_ENDIAN(s_UsbDeviceStandardRx);
  295. /* The device status length must be USB_DEVICE_STATUS_SIZE. */
  296. *length = USB_DEVICE_STATUS_SIZE;
  297. }
  298. else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
  299. {
  300. /* Get the interface status */
  301. error = kStatus_USB_Success;
  302. s_UsbDeviceStandardRx = 0U;
  303. /* The interface status length must be USB_INTERFACE_STATUS_SIZE. */
  304. *length = USB_INTERFACE_STATUS_SIZE;
  305. }
  306. else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
  307. {
  308. /* Get the endpoint status */
  309. usb_device_endpoint_status_struct_t endpointStatus;
  310. endpointStatus.endpointAddress = (uint8_t)setup->wIndex;
  311. endpointStatus.endpointStatus = kUSB_DeviceEndpointStateIdle;
  312. error = USB_DeviceGetStatus(handle, kUSB_DeviceStatusEndpoint, &endpointStatus);
  313. s_UsbDeviceStandardRx = endpointStatus.endpointStatus & USB_GET_STATUS_ENDPOINT_MASK;
  314. s_UsbDeviceStandardRx = USB_SHORT_TO_LITTLE_ENDIAN(s_UsbDeviceStandardRx);
  315. /* The endpoint status length must be USB_INTERFACE_STATUS_SIZE. */
  316. *length = USB_ENDPOINT_STATUS_SIZE;
  317. }
  318. else
  319. {
  320. }
  321. *buffer = (uint8_t *)&s_UsbDeviceStandardRx;
  322. return error;
  323. }
  324. /*!
  325. * @brief Handle set or clear device feature request.
  326. *
  327. * This function is used to handle set or clear device feature request.
  328. *
  329. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  330. * @param setup The pointer of the setup packet.
  331. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  332. * @param length It is an out parameter, the data length.
  333. *
  334. * @retval kStatus_USB_Success The requst is handled successfully.
  335. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
  336. * or, the request is unsupported.
  337. */
  338. static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_handle handle,
  339. usb_setup_struct_t *setup,
  340. uint8_t **buffer,
  341. uint32_t *length)
  342. {
  343. usb_status_t error = kStatus_USB_InvalidRequest;
  344. uint8_t state;
  345. uint8_t isSet = 0U;
  346. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  347. if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state))
  348. {
  349. return error;
  350. }
  351. /* Identify the request is set or clear the feature. */
  352. if (USB_REQUEST_STANDARD_SET_FEATURE == setup->bRequest)
  353. {
  354. isSet = 1U;
  355. }
  356. if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
  357. {
  358. /* Set or Clear the device featrue. */
  359. if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP == setup->wValue)
  360. {
  361. /* Set or Clear the device remote wakeup featrue. */
  362. error = USB_DeviceConfigureRemoteWakeup(handle, isSet);
  363. }
  364. #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) && \
  365. (defined(USB_DEVICE_CONFIG_EHCI_TEST_MODE) && (USB_DEVICE_CONFIG_EHCI_TEST_MODE > 0U))
  366. else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE == setup->wValue)
  367. {
  368. state = kUSB_DeviceStateTestMode;
  369. error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
  370. }
  371. #endif
  372. else
  373. {
  374. }
  375. }
  376. else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
  377. {
  378. /* Set or Clear the endpoint featrue. */
  379. if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT == setup->wValue)
  380. {
  381. if (USB_CONTROL_ENDPOINT == (setup->wIndex & USB_ENDPOINT_NUMBER_MASK))
  382. {
  383. /* Set or Clear the control endpoint status(halt or not). */
  384. if (isSet)
  385. {
  386. USB_DeviceStallEndpoint(handle, (uint8_t)setup->wIndex);
  387. }
  388. else
  389. {
  390. USB_DeviceUnstallEndpoint(handle, (uint8_t)setup->wIndex);
  391. }
  392. }
  393. /* Set or Clear the endpoint status featrue. */
  394. error = USB_DeviceConfigureEndpointStatus(handle, setup->wIndex, isSet);
  395. }
  396. else
  397. {
  398. }
  399. }
  400. else
  401. {
  402. }
  403. return error;
  404. }
  405. /*!
  406. * @brief Handle set address request.
  407. *
  408. * This function is used to handle set address request.
  409. *
  410. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  411. * @param setup The pointer of the setup packet.
  412. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  413. * @param length It is an out parameter, the data length.
  414. *
  415. * @retval kStatus_USB_Success The requst is handled successfully.
  416. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state.
  417. */
  418. static usb_status_t USB_DeviceCh9SetAddress(usb_device_handle handle,
  419. usb_setup_struct_t *setup,
  420. uint8_t **buffer,
  421. uint32_t *length)
  422. {
  423. usb_status_t error = kStatus_USB_InvalidRequest;
  424. uint8_t state;
  425. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  426. if ((kUSB_DeviceStateAddressing != state) && (kUSB_DeviceStateAddress != state) &&
  427. (kUSB_DeviceStateDefault != state))
  428. {
  429. return error;
  430. }
  431. if (kUSB_DeviceStateAddressing != state)
  432. {
  433. /* If the device address is not setting, pass the address and the device state will change to
  434. * kUSB_DeviceStateAddressing internally. */
  435. state = setup->wValue & 0xFFU;
  436. error = USB_DeviceSetStatus(handle, kUSB_DeviceStatusAddress, &state);
  437. }
  438. else
  439. {
  440. /* If the device address is setting, set device address and the address will be write into the controller
  441. * internally. */
  442. error = USB_DeviceSetStatus(handle, kUSB_DeviceStatusAddress, NULL);
  443. /* And then change the device state to kUSB_DeviceStateAddress. */
  444. if (kStatus_USB_Success == error)
  445. {
  446. state = kUSB_DeviceStateAddress;
  447. error = USB_DeviceSetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  448. }
  449. }
  450. return error;
  451. }
  452. /*!
  453. * @brief Handle get descriptor request.
  454. *
  455. * This function is used to handle get descriptor request.
  456. *
  457. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  458. * @param setup The pointer of the setup packet.
  459. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  460. * @param length It is an out parameter, the data length.
  461. *
  462. * @retval kStatus_USB_Success The requst is handled successfully.
  463. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
  464. * or, the request is unsupported.
  465. */
  466. static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_handle handle,
  467. usb_setup_struct_t *setup,
  468. uint8_t **buffer,
  469. uint32_t *length)
  470. {
  471. uint8_t state;
  472. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  473. if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state) &&
  474. (kUSB_DeviceStateDefault != state))
  475. {
  476. return kStatus_USB_InvalidRequest;
  477. }
  478. return USB_DeviceGetDescriptor(handle, setup, length, buffer);
  479. }
  480. /*!
  481. * @brief Handle get current configuration request.
  482. *
  483. * This function is used to handle get current configuration request.
  484. *
  485. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  486. * @param setup The pointer of the setup packet.
  487. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  488. * @param length It is an out parameter, the data length.
  489. *
  490. * @retval kStatus_USB_Success The requst is handled successfully.
  491. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
  492. * or, the request is unsupported.
  493. */
  494. static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_handle handle,
  495. usb_setup_struct_t *setup,
  496. uint8_t **buffer,
  497. uint32_t *length)
  498. {
  499. uint8_t state;
  500. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  501. if ((kUSB_DeviceStateAddress != state) && ((kUSB_DeviceStateConfigured != state)))
  502. {
  503. return kStatus_USB_InvalidRequest;
  504. }
  505. *length = USB_CONFIGURE_SIZE;
  506. *buffer = (uint8_t *)&s_UsbDeviceStandardRx;
  507. return USB_DeviceGetConfigure(handle, (uint8_t *)&s_UsbDeviceStandardRx);
  508. }
  509. /*!
  510. * @brief Handle set current configuration request.
  511. *
  512. * This function is used to handle set current configuration request.
  513. *
  514. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  515. * @param setup The pointer of the setup packet.
  516. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  517. * @param length It is an out parameter, the data length.
  518. *
  519. * @retval kStatus_USB_Success The requst is handled successfully.
  520. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
  521. * or, the request is unsupported.
  522. */
  523. static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_handle handle,
  524. usb_setup_struct_t *setup,
  525. uint8_t **buffer,
  526. uint32_t *length)
  527. {
  528. uint8_t state;
  529. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  530. if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state))
  531. {
  532. return kStatus_USB_InvalidRequest;
  533. }
  534. /* The device state is changed to kUSB_DeviceStateConfigured */
  535. state = kUSB_DeviceStateConfigured;
  536. USB_DeviceSetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  537. if (!setup->wValue)
  538. {
  539. /* If the new configuration is zero, the device state is changed to kUSB_DeviceStateAddress */
  540. state = kUSB_DeviceStateAddress;
  541. USB_DeviceSetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  542. }
  543. return USB_DeviceSetConfigure(handle, setup->wValue);
  544. }
  545. /*!
  546. * @brief Handle get the alternate setting of a interface request.
  547. *
  548. * This function is used to handle get the alternate setting of a interface request.
  549. *
  550. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  551. * @param setup The pointer of the setup packet.
  552. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  553. * @param length It is an out parameter, the data length.
  554. *
  555. * @retval kStatus_USB_Success The requst is handled successfully.
  556. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
  557. * or, the request is unsupported.
  558. */
  559. static usb_status_t USB_DeviceCh9GetInterface(usb_device_handle handle,
  560. usb_setup_struct_t *setup,
  561. uint8_t **buffer,
  562. uint32_t *length)
  563. {
  564. usb_status_t error = kStatus_USB_InvalidRequest;
  565. uint8_t state;
  566. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  567. if (state != kUSB_DeviceStateConfigured)
  568. {
  569. return error;
  570. }
  571. *length = USB_INTERFACE_SIZE;
  572. *buffer = (uint8_t *)&s_UsbDeviceStandardRx;
  573. return USB_DeviceGetInterface(handle, setup->wIndex & 0xFFU, (uint8_t *)&s_UsbDeviceStandardRx);
  574. }
  575. /*!
  576. * @brief Handle set the alternate setting of a interface request.
  577. *
  578. * This function is used to handle set the alternate setting of a interface request.
  579. *
  580. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  581. * @param setup The pointer of the setup packet.
  582. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  583. * @param length It is an out parameter, the data length.
  584. *
  585. * @retval kStatus_USB_Success The requst is handled successfully.
  586. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
  587. * or, the request is unsupported.
  588. */
  589. static usb_status_t USB_DeviceCh9SetInterface(usb_device_handle handle,
  590. usb_setup_struct_t *setup,
  591. uint8_t **buffer,
  592. uint32_t *length)
  593. {
  594. uint8_t state;
  595. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  596. if (state != kUSB_DeviceStateConfigured)
  597. {
  598. return kStatus_USB_InvalidRequest;
  599. }
  600. return USB_DeviceSetInterface(handle, (setup->wIndex & 0xFFU), (setup->wValue & 0xFFU));
  601. }
  602. /*!
  603. * @brief Handle get sync frame request.
  604. *
  605. * This function is used to handle get sync frame request.
  606. *
  607. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  608. * @param setup The pointer of the setup packet.
  609. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  610. * @param length It is an out parameter, the data length.
  611. *
  612. * @retval kStatus_USB_Success The requst is handled successfully.
  613. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
  614. * or, the request is unsupported.
  615. */
  616. static usb_status_t USB_DeviceCh9SynchFrame(usb_device_handle handle,
  617. usb_setup_struct_t *setup,
  618. uint8_t **buffer,
  619. uint32_t *length)
  620. {
  621. usb_status_t error = kStatus_USB_InvalidRequest;
  622. uint8_t state;
  623. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  624. if (state != kUSB_DeviceStateConfigured)
  625. {
  626. return error;
  627. }
  628. s_UsbDeviceStandardRx = setup->wIndex;
  629. /* Get the sync frame value */
  630. error = USB_DeviceGetStatus(handle, kUSB_DeviceStatusSynchFrame, &s_UsbDeviceStandardRx);
  631. *buffer = (uint8_t *)&s_UsbDeviceStandardRx;
  632. *length = sizeof(s_UsbDeviceStandardRx);
  633. return error;
  634. }
  635. /*!
  636. * @brief Send the reponse to the host.
  637. *
  638. * This function is used to send the reponse to the host.
  639. *
  640. * There are two cases this function will be called.
  641. * Case one when a setup packet is received in control endpoint callback function:
  642. * 1. If there is not data phase in the setup transfer, the function will prime an IN transfer with the data
  643. * length is zero for status phase.
  644. * 2. If there is an IN data phase, the function will prime an OUT transfer with the actual length to need to
  645. * send for data phase. And then prime an IN transfer with the data length is zero for status phase.
  646. * 3. If there is an OUT data phase, the function will prime an IN transfer with the actual length to want to
  647. * receive for data phase.
  648. *
  649. * Case two when is not a setup packet received in control endpoint callback function:
  650. * 1. The function will prime an IN transfer with data length is zero for status phase.
  651. *
  652. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  653. * @param setup The pointer of the setup packet.
  654. * @param error The error code returned from the standard request fucntion.
  655. * @param stage The stage of the control transfer.
  656. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
  657. * @param length It is an out parameter, the data length.
  658. *
  659. * @return A USB error code or kStatus_USB_Success.
  660. */
  661. static usb_status_t USB_DeviceControlCallbackFeedback(usb_device_handle handle,
  662. usb_setup_struct_t *setup,
  663. usb_status_t error,
  664. usb_device_control_read_write_sequence_t stage,
  665. uint8_t **buffer,
  666. uint32_t *length)
  667. {
  668. usb_status_t errorCode = kStatus_USB_Error;
  669. uint8_t direction = USB_IN;
  670. if (kStatus_USB_InvalidRequest == error)
  671. {
  672. /* Stall the control pipe when the request is unsupported. */
  673. if ((!((setup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD)) &&
  674. ((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT) && (setup->wLength) &&
  675. (kUSB_DeviceControlPipeSetupStage == stage))
  676. {
  677. direction = USB_OUT;
  678. }
  679. errorCode = USB_DeviceStallEndpoint(
  680. handle,
  681. (USB_CONTROL_ENDPOINT) | (uint8_t)((uint32_t)direction << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
  682. }
  683. else
  684. {
  685. if (*length > setup->wLength)
  686. {
  687. *length = setup->wLength;
  688. }
  689. errorCode = USB_DeviceSendRequest(handle, (USB_CONTROL_ENDPOINT), *buffer, *length);
  690. if ((kStatus_USB_Success == errorCode) &&
  691. (USB_REQUEST_TYPE_DIR_IN == (setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK)))
  692. {
  693. errorCode = USB_DeviceRecvRequest(handle, (USB_CONTROL_ENDPOINT), (uint8_t *)NULL, 0U);
  694. }
  695. }
  696. return errorCode;
  697. }
  698. /*!
  699. * @brief Control endpoint callback function.
  700. *
  701. * This callback function is used to notify uplayer the tranfser result of a transfer.
  702. * This callback pointer is passed when a sepcified endpoint initialied by calling API USB_DeviceInitEndpoint.
  703. *
  704. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  705. * @param message The result of a transfer, includes transfer buffer, transfer length and whether is in setup
  706. * phase for control pipe.
  707. * @param callbackParam The paramter for this callback. It is same with
  708. * usb_device_endpoint_callback_struct_t::callbackParam.
  709. *
  710. * @return A USB error code or kStatus_USB_Success.
  711. */
  712. usb_status_t USB_DeviceControlCallback(usb_device_handle handle,
  713. usb_device_endpoint_callback_message_struct_t *message,
  714. void *callbackParam)
  715. {
  716. usb_setup_struct_t *deviceSetup;
  717. uint8_t *setupOutBuffer;
  718. uint8_t *buffer = (uint8_t *)NULL;
  719. uint32_t length = 0U;
  720. usb_status_t error = kStatus_USB_InvalidRequest;
  721. uint8_t state;
  722. if (USB_UNINITIALIZED_VAL_32 == message->length)
  723. {
  724. return error;
  725. }
  726. USB_DeviceGetSetupBuffer(handle, &deviceSetup);
  727. USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
  728. if (message->isSetup)
  729. {
  730. if ((USB_SETUP_PACKET_SIZE != message->length) || (NULL == message->buffer))
  731. {
  732. /* If a invalid setup is received, the control pipes should be de-init and init again.
  733. * Due to the IP can not meet this require, it is revesed for feature.
  734. */
  735. /*
  736. USB_DeviceDeinitEndpoint(handle,
  737. USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
  738. USB_DeviceDeinitEndpoint(handle,
  739. USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
  740. USB_DeviceControlPipeInit(handle);
  741. */
  742. return error;
  743. }
  744. /* Receive a setup request */
  745. usb_setup_struct_t *setup = (usb_setup_struct_t *)(message->buffer);
  746. /* Copy the setup packet to the application buffer */
  747. deviceSetup->wValue = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wValue);
  748. deviceSetup->wIndex = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex);
  749. deviceSetup->wLength = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wLength);
  750. deviceSetup->bRequest = setup->bRequest;
  751. deviceSetup->bmRequestType = setup->bmRequestType;
  752. if ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD)
  753. {
  754. /* Handle the standard request */
  755. if (s_UsbDeviceStandardRequest[deviceSetup->bRequest] != (usb_standard_request_callback_t)NULL)
  756. {
  757. error = s_UsbDeviceStandardRequest[deviceSetup->bRequest](handle, deviceSetup, &buffer, &length);
  758. }
  759. }
  760. else
  761. {
  762. if ((deviceSetup->wLength) &&
  763. ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
  764. {
  765. /* Class or vendor request with the OUT data phase. */
  766. if ((deviceSetup->wLength) &&
  767. ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS))
  768. {
  769. /* Get data buffer to receive the data from the host. */
  770. length = deviceSetup->wLength;
  771. error = USB_DeviceGetClassReceiveBuffer(handle, deviceSetup, &length, &setupOutBuffer);
  772. length = 0U;
  773. }
  774. else
  775. {
  776. }
  777. if (kStatus_USB_Success == error)
  778. {
  779. /* Prime an OUT transfer */
  780. error = USB_DeviceRecvRequest(handle, USB_CONTROL_ENDPOINT, setupOutBuffer, deviceSetup->wLength);
  781. return error;
  782. }
  783. }
  784. else
  785. {
  786. /* Class or vendor request with the IN data phase. */
  787. if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS))
  788. {
  789. /* Get data buffer to response the host. */
  790. error = USB_DeviceProcessClassRequest(handle, deviceSetup, &length, &buffer);
  791. }
  792. else
  793. {
  794. }
  795. }
  796. }
  797. /* Send the reponse to the host. */
  798. error = USB_DeviceControlCallbackFeedback(handle, deviceSetup, error, kUSB_DeviceControlPipeSetupStage, &buffer,
  799. &length);
  800. }
  801. else if (kUSB_DeviceStateAddressing == state)
  802. {
  803. /* Set the device address to controller. */
  804. error = s_UsbDeviceStandardRequest[deviceSetup->bRequest](handle, deviceSetup, &buffer, &length);
  805. }
  806. #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) && \
  807. (defined(USB_DEVICE_CONFIG_EHCI_TEST_MODE) && (USB_DEVICE_CONFIG_EHCI_TEST_MODE > 0U))
  808. else if (kUSB_DeviceStateTestMode == state)
  809. {
  810. uint8_t portTestControl = (uint8_t)(deviceSetup->wIndex >> 8);
  811. /* Set the controller.into test mode. */
  812. error = USB_DeviceSetStatus(handle, kUSB_DeviceStatusTestMode, &portTestControl);
  813. }
  814. #endif
  815. else if ((message->length) && (deviceSetup->wLength) &&
  816. ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
  817. {
  818. if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS))
  819. {
  820. /* Data received in OUT phase, and notify the class driver. */
  821. error = USB_DeviceProcessClassRequest(handle, deviceSetup, &message->length, &message->buffer);
  822. }
  823. else
  824. {
  825. }
  826. /* Send the reponse to the host. */
  827. error = USB_DeviceControlCallbackFeedback(handle, deviceSetup, error, kUSB_DeviceControlPipeDataStage, &buffer,
  828. &length);
  829. }
  830. else
  831. {
  832. }
  833. return error;
  834. }
  835. /*!
  836. * @brief Control endpoint initialization function.
  837. *
  838. * This callback function is used to initialize the control pipes.
  839. *
  840. * @param handle The device handle. It equals the value returned from USB_DeviceInit.
  841. * @param param The up layer handle.
  842. *
  843. * @return A USB error code or kStatus_USB_Success.
  844. */
  845. usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle)
  846. {
  847. usb_device_endpoint_init_struct_t epInitStruct;
  848. usb_device_endpoint_callback_struct_t endpointCallback;
  849. usb_status_t error;
  850. endpointCallback.callbackFn = USB_DeviceControlCallback;
  851. endpointCallback.callbackParam = handle;
  852. epInitStruct.zlt = 1U;
  853. epInitStruct.transferType = USB_ENDPOINT_CONTROL;
  854. epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
  855. epInitStruct.maxPacketSize = USB_CONTROL_MAX_PACKET_SIZE;
  856. /* Initialize the control IN pipe */
  857. error = USB_DeviceInitEndpoint(handle, &epInitStruct, &endpointCallback);
  858. if (kStatus_USB_Success != error)
  859. {
  860. return error;
  861. }
  862. epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
  863. /* Initialize the control OUT pipe */
  864. error = USB_DeviceInitEndpoint(handle, &epInitStruct, &endpointCallback);
  865. if (kStatus_USB_Success != error)
  866. {
  867. USB_DeviceDeinitEndpoint(handle,
  868. USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
  869. return error;
  870. }
  871. return kStatus_USB_Success;
  872. }