usbh_std.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /*!
  2. \file usbh_std.c
  3. \brief USB 2.0 standard function definition
  4. \version 2017-06-06, V1.0.0, firmware for GD32F3x0
  5. \version 2019-06-01, V2.0.0, firmware for GD32F3x0
  6. */
  7. /*
  8. Copyright (c) 2019, GigaDevice Semiconductor Inc.
  9. Redistribution and use in source and binary forms, with or without modification,
  10. are permitted provided that the following conditions are met:
  11. 1. Redistributions of source code must retain the above copyright notice, this
  12. list of conditions and the following disclaimer.
  13. 2. Redistributions in binary form must reproduce the above copyright notice,
  14. this list of conditions and the following disclaimer in the documentation
  15. and/or other materials provided with the distribution.
  16. 3. Neither the name of the copyright holder nor the names of its contributors
  17. may be used to endorse or promote products derived from this software without
  18. specific prior written permission.
  19. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  25. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  28. OF SUCH DAMAGE.
  29. */
  30. #include "usbh_core.h"
  31. #include "usbh_usr.h"
  32. #include "usbh_std.h"
  33. #include "usbh_ctrl.h"
  34. uint8_t local_buffer[64];
  35. uint8_t usbh_cfg_desc[512];
  36. uint8_t enum_polling_handle_flag = 0U;
  37. static void enum_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  38. static void enum_get_full_dev_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  39. static void enum_set_addr_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  40. static void enum_get_cfg_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  41. static void enum_get_full_cfg_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  42. static void enum_get_mfc_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  43. static void enum_get_product_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  44. static void enum_get_serialnum_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  45. static void enum_set_configuration_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  46. static void enum_dev_configured_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  47. /* the enumeration state handle function array */
  48. void (*enum_state_handle[]) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) =
  49. {
  50. enum_idle_handle,
  51. enum_set_addr_handle,
  52. enum_get_full_dev_desc_handle,
  53. enum_get_cfg_desc_handle,
  54. enum_get_full_cfg_desc_handle,
  55. enum_get_mfc_string_desc_handle,
  56. enum_get_product_string_desc_handle,
  57. enum_get_serialnum_string_desc_handle,
  58. enum_set_configuration_handle,
  59. enum_dev_configured_handle,
  60. };
  61. /* the enumeration state handle table */
  62. state_table_struct enum_handle_table[ENUM_HANDLE_TABLE_SIZE] =
  63. {
  64. /* the current state the current event the next state the event function */
  65. {ENUM_IDLE, ENUM_EVENT_SET_ADDR, ENUM_SET_ADDR, only_state_move },
  66. {ENUM_SET_ADDR, ENUN_EVENT_GET_FULL_DEV_DESC, ENUM_GET_FULL_DEV_DESC, only_state_move },
  67. {ENUM_GET_FULL_DEV_DESC, ENUN_EVENT_GET_CFG_DESC, ENUM_GET_CFG_DESC, only_state_move },
  68. {ENUM_GET_CFG_DESC, ENUN_EVENT_GET_FULL_CFG_DESC, ENUM_GET_FULL_CFG_DESC, only_state_move },
  69. {ENUM_GET_FULL_CFG_DESC, ENUN_EVENT_GET_MFC_STRING_DESC, ENUM_GET_MFC_STRING_DESC, only_state_move },
  70. {ENUM_GET_MFC_STRING_DESC, ENUN_EVENT_GET_PRODUCT_STRING_DESC, ENUM_GET_PRODUCT_STRING_DESC, only_state_move },
  71. {ENUM_GET_PRODUCT_STRING_DESC, ENUN_EVENT_GET_SERIALNUM_STRING_DESC, ENUM_GET_SERIALNUM_STRING_DESC, only_state_move },
  72. {ENUM_GET_SERIALNUM_STRING_DESC, ENUN_EVENT_SET_CONFIGURATION, ENUM_SET_CONFIGURATION, only_state_move },
  73. {ENUM_SET_CONFIGURATION, ENUN_EVENT_DEV_CONFIGURED, ENUM_DEV_CONFIGURED, only_state_move },
  74. {ENUM_DEV_CONFIGURED, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun },
  75. };
  76. /*!
  77. \brief the polling function of enumeration state
  78. \param[in] pudev: pointer to USB device
  79. \param[in] puhost: pointer to USB host
  80. \param[in] pustate: pointer to USB state driver
  81. \param[out] none
  82. \retval usb host status
  83. */
  84. usbh_status_enum enum_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
  85. {
  86. usbh_status_enum exe_state = USBH_BUSY;
  87. usbh_state_handle_struct *p_state;
  88. p_state = (usbh_state_handle_struct *)pustate;
  89. if (0U == enum_polling_handle_flag) {
  90. enum_polling_handle_flag = 1U;
  91. scd_table_push(p_state);
  92. scd_state_move(p_state, ENUM_IDLE);
  93. }
  94. /* start the enumeration state handle */
  95. scd_begin(p_state,ENUM_FSM_ID);
  96. if (0 == p_state->usbh_current_state_stack_top) {
  97. enum_state_handle[p_state->usbh_current_state](pudev, puhost, p_state);
  98. } else {
  99. enum_state_handle[p_state->stack[1].state](pudev, puhost, p_state);
  100. }
  101. /* determine the enumeration whether to complete */
  102. if (ENUM_DEV_CONFIGURED == puhost->usbh_backup_state.enum_backup_state) {
  103. puhost->usbh_backup_state.enum_backup_state = ENUM_IDLE;
  104. enum_polling_handle_flag = 0U;
  105. exe_state = USBH_OK;
  106. }
  107. return exe_state;
  108. }
  109. /*!
  110. \brief the handle function of ENUM_IDLE state
  111. \param[in] pudev: pointer to USB device
  112. \param[in] puhost: pointer to USB host
  113. \param[in] pustate: pointer to USB state driver
  114. \param[out] none
  115. \retval none
  116. */
  117. static void enum_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate)
  118. {
  119. puhost->usbh_backup_state.enum_backup_state = ENUM_IDLE;
  120. if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
  121. usbh_enum_desc_get(pudev,
  122. puhost,
  123. pudev->host.rx_buffer,
  124. USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
  125. USB_DEVDESC,
  126. 8U);
  127. if ((void *)0 != pudev->mdelay) {
  128. pudev->mdelay(100U);
  129. }
  130. }
  131. if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
  132. usbh_device_desc_parse(&puhost->device.dev_desc, pudev->host.rx_buffer, 8U);
  133. puhost->control.ep0_size = puhost->device.dev_desc.bMaxPacketSize0;
  134. /* issue reset */
  135. usb_port_reset(pudev);
  136. /* modify control channels configuration for maxpacket size */
  137. usbh_channel_modify (pudev,
  138. puhost->control.hc_out_num,
  139. 0U,
  140. 0U,
  141. 0U,
  142. (uint16_t)puhost->control.ep0_size);
  143. usbh_channel_modify (pudev,
  144. puhost->control.hc_in_num,
  145. 0U,
  146. 0U,
  147. 0U,
  148. (uint16_t)puhost->control.ep0_size);
  149. scd_event_handle(pudev,
  150. puhost,
  151. pustate,
  152. ENUM_EVENT_SET_ADDR,
  153. pustate->usbh_current_state);
  154. }
  155. }
  156. /*!
  157. \brief the handle function of ENUM_GET_FULL_DEV_DESC state
  158. \param[in] pudev: pointer to USB device
  159. \param[in] puhost: pointer to USB host
  160. \param[in] pustate: pointer to USB state driver
  161. \param[out] none
  162. \retval none
  163. */
  164. static void enum_get_full_dev_desc_handle (usb_core_handle_struct *pudev,
  165. usbh_host_struct *puhost,
  166. usbh_state_handle_struct *pustate)
  167. {
  168. puhost->usbh_backup_state.enum_backup_state = ENUM_GET_FULL_DEV_DESC;
  169. if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
  170. usbh_enum_desc_get(pudev,
  171. puhost,
  172. pudev->host.rx_buffer,
  173. USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
  174. USB_DEVDESC,
  175. USB_DEVDESC_SIZE);
  176. }
  177. if(USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)){
  178. usbh_device_desc_parse(&puhost->device.dev_desc, pudev->host.rx_buffer, USB_DEVDESC_SIZE);
  179. puhost->usr_cb->device_desc_available(&puhost->device.dev_desc);
  180. scd_event_handle(pudev,
  181. puhost,
  182. pustate,
  183. ENUN_EVENT_GET_CFG_DESC,
  184. pustate->usbh_current_state);
  185. }
  186. }
  187. /*!
  188. \brief the handle function of ENUM_SET_ADDR state
  189. \param[in] pudev: pointer to USB device
  190. \param[in] puhost: pointer to USB host
  191. \param[in] pustate: pointer to USB state driver
  192. \param[out] none
  193. \retval none
  194. */
  195. static void enum_set_addr_handle (usb_core_handle_struct *pudev,
  196. usbh_host_struct *puhost,
  197. usbh_state_handle_struct *pustate)
  198. {
  199. puhost->usbh_backup_state.enum_backup_state = ENUM_SET_ADDR;
  200. if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
  201. usbh_enum_addr_set(pudev, puhost,USBH_DEVICE_ADDRESS);
  202. if ((void *)0 != pudev->mdelay) {
  203. pudev->mdelay(100U);
  204. }
  205. }
  206. if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
  207. if ((void *)0 != pudev->mdelay) {
  208. pudev->mdelay(2U);
  209. }
  210. puhost->device.address = USBH_DEVICE_ADDRESS;
  211. /* user callback for device address assigned */
  212. puhost->usr_cb->device_address_set();
  213. /* modify control channels to update device address */
  214. usbh_channel_modify (pudev,
  215. puhost->control.hc_in_num,
  216. puhost->device.address,
  217. 0U,
  218. 0U,
  219. 0U);
  220. usbh_channel_modify (pudev,
  221. puhost->control.hc_out_num,
  222. puhost->device.address,
  223. 0U,
  224. 0U,
  225. 0U);
  226. scd_event_handle(pudev,
  227. puhost,
  228. pustate,
  229. ENUN_EVENT_GET_FULL_DEV_DESC,
  230. pustate->usbh_current_state);
  231. }
  232. }
  233. /*!
  234. \brief the handle function of ENUM_GET_CFG_DESC state
  235. \param[in] pudev: pointer to USB device
  236. \param[in] puhost: pointer to USB host
  237. \param[in] pustate: pointer to USB state driver
  238. \param[out] none
  239. \retval none
  240. */
  241. static void enum_get_cfg_desc_handle (usb_core_handle_struct *pudev,
  242. usbh_host_struct *puhost,
  243. usbh_state_handle_struct *pustate)
  244. {
  245. uint16_t index = 0U;
  246. puhost->usbh_backup_state.enum_backup_state = ENUM_GET_CFG_DESC;
  247. if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
  248. usbh_enum_desc_get(pudev,
  249. puhost,
  250. pudev->host.rx_buffer,
  251. USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
  252. USB_CFGDESC,
  253. USB_CFGDESC_SIZE);
  254. }
  255. if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
  256. /* save configuration descriptor for class parsing usage */
  257. for (; index < USB_CFGDESC_SIZE; index ++) {
  258. usbh_cfg_desc[index] = pudev->host.rx_buffer[index];
  259. }
  260. /* commands successfully sent and response received */
  261. usbh_cfg_desc_parse (&puhost->device.cfg_desc,
  262. puhost->device.itf_desc,
  263. puhost->device.ep_desc,
  264. pudev->host.rx_buffer,
  265. USB_CFGDESC_SIZE);
  266. scd_event_handle(pudev,
  267. puhost,
  268. pustate,
  269. ENUN_EVENT_GET_FULL_CFG_DESC,
  270. pustate->usbh_current_state);
  271. }
  272. }
  273. /*!
  274. \brief the handle function of ENUM_GET_FULL_CFG_DESC state
  275. \param[in] pudev: pointer to USB device
  276. \param[in] puhost: pointer to USB host
  277. \param[in] pustate: pointer to USB state driver
  278. \param[out] none
  279. \retval none
  280. */
  281. static void enum_get_full_cfg_desc_handle (usb_core_handle_struct *pudev,
  282. usbh_host_struct *puhost,
  283. usbh_state_handle_struct *pustate)
  284. {
  285. uint16_t index = 0U;
  286. puhost->usbh_backup_state.enum_backup_state = ENUM_GET_FULL_CFG_DESC;
  287. if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
  288. usbh_enum_desc_get (pudev, puhost, pudev->host.rx_buffer,
  289. USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
  290. USB_CFGDESC, puhost->device.cfg_desc.wTotalLength);
  291. }
  292. if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
  293. /* save configuration descriptor for class parsing usage */
  294. for (; index < puhost->device.cfg_desc.wTotalLength; index ++) {
  295. usbh_cfg_desc[index] = pudev->host.rx_buffer[index];
  296. }
  297. /* commands successfully sent and response received */
  298. usbh_cfg_desc_parse (&puhost->device.cfg_desc,
  299. puhost->device.itf_desc,
  300. puhost->device.ep_desc,
  301. pudev->host.rx_buffer,
  302. puhost->device.cfg_desc.wTotalLength);
  303. /* User callback for configuration descriptors available */
  304. puhost->usr_cb->configuration_desc_available(&puhost->device.cfg_desc,
  305. puhost->device.itf_desc,
  306. puhost->device.ep_desc[0]);
  307. scd_event_handle(pudev,
  308. puhost,
  309. pustate,
  310. ENUN_EVENT_GET_MFC_STRING_DESC,
  311. pustate->usbh_current_state);
  312. }
  313. }
  314. /*!
  315. \brief the handle function of ENUM_GET_MFC_STRING_DESC state
  316. \param[in] pudev: pointer to USB device
  317. \param[in] puhost: pointer to USB host
  318. \param[in] pustate: pointer to USB state driver
  319. \param[out] none
  320. \retval none
  321. */
  322. static void enum_get_mfc_string_desc_handle (usb_core_handle_struct *pudev,
  323. usbh_host_struct *puhost,
  324. usbh_state_handle_struct *pustate)
  325. {
  326. puhost->usbh_backup_state.enum_backup_state = ENUM_GET_MFC_STRING_DESC;
  327. if (0U != puhost->device.dev_desc.iManufacturer) {
  328. if(CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
  329. usbh_enum_desc_get(pudev,
  330. puhost,
  331. pudev->host.rx_buffer,
  332. USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
  333. USB_STRDESC | puhost->device.dev_desc.iManufacturer,
  334. 0xffU);
  335. }
  336. if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
  337. usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
  338. puhost->usr_cb->manufacturer_string(local_buffer);
  339. scd_event_handle(pudev,
  340. puhost,
  341. pustate,
  342. ENUN_EVENT_GET_PRODUCT_STRING_DESC,
  343. pustate->usbh_current_state);
  344. }
  345. } else {
  346. puhost->usr_cb->manufacturer_string("N/A");
  347. scd_state_move((usbh_state_handle_struct *)pustate, ENUM_GET_PRODUCT_STRING_DESC);
  348. }
  349. }
  350. /*!
  351. \brief the handle function of ENUM_GET_PRODUCT_STRING_DESC state
  352. \param[in] pudev: pointer to USB device
  353. \param[in] puhost: pointer to USB host
  354. \param[in] pustate: pointer to USB state driver
  355. \param[out] none
  356. \retval none
  357. */
  358. static void enum_get_product_string_desc_handle (usb_core_handle_struct *pudev,
  359. usbh_host_struct *puhost,
  360. usbh_state_handle_struct *pustate)
  361. {
  362. puhost->usbh_backup_state.enum_backup_state = ENUM_GET_PRODUCT_STRING_DESC;
  363. if (0U != puhost->device.dev_desc.iProduct) {
  364. if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
  365. usbh_enum_desc_get(pudev,
  366. puhost,
  367. pudev->host.rx_buffer,
  368. USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
  369. USB_STRDESC | puhost->device.dev_desc.iProduct,
  370. 0xffU);
  371. }
  372. if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
  373. usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
  374. /* user callback for product string */
  375. puhost->usr_cb->product_string(local_buffer);
  376. scd_event_handle(pudev,
  377. puhost,
  378. pustate,
  379. ENUN_EVENT_GET_SERIALNUM_STRING_DESC,
  380. pustate->usbh_current_state);
  381. }
  382. } else {
  383. puhost->usr_cb->product_string("N/A");
  384. scd_event_handle(pudev,
  385. puhost,
  386. pustate,
  387. ENUN_EVENT_GET_SERIALNUM_STRING_DESC,
  388. pustate->usbh_current_state);
  389. }
  390. }
  391. /*!
  392. \brief the handle function of ENUM_GET_SERIALNUM_STRING_DESC state
  393. \param[in] pudev: pointer to USB device
  394. \param[in] puhost: pointer to USB host
  395. \param[in] pustate: pointer to USB state driver
  396. \param[out] none
  397. \retval none
  398. */
  399. static void enum_get_serialnum_string_desc_handle (usb_core_handle_struct *pudev,
  400. usbh_host_struct *puhost,
  401. usbh_state_handle_struct *pustate)
  402. {
  403. puhost->usbh_backup_state.enum_backup_state = ENUM_GET_SERIALNUM_STRING_DESC;
  404. if (0U != puhost->device.dev_desc.iSerialNumber) {
  405. if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) {
  406. usbh_enum_desc_get(pudev,
  407. puhost,
  408. pudev->host.rx_buffer,
  409. USB_REQTYPE_DEVICE | USB_STANDARD_REQ,
  410. USB_STRDESC | puhost->device.dev_desc.iSerialNumber,
  411. 0xffU);
  412. }
  413. if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)){
  414. usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU);
  415. /* user callback for product string */
  416. puhost->usr_cb->serial_num_string(local_buffer);
  417. scd_event_handle(pudev,
  418. puhost,
  419. pustate,
  420. ENUN_EVENT_SET_CONFIGURATION,
  421. pustate->usbh_current_state);
  422. }
  423. } else {
  424. puhost->usr_cb->serial_num_string("N/A");
  425. scd_event_handle(pudev,
  426. puhost,
  427. pustate,
  428. ENUN_EVENT_SET_CONFIGURATION,
  429. pustate->usbh_current_state);
  430. }
  431. }
  432. /*!
  433. \brief the handle function of ENUM_SET_CONFIGURATION state
  434. \param[in] pudev: pointer to USB device
  435. \param[in] puhost: pointer to USB host
  436. \param[in] pustate: pointer to USB state driver
  437. \param[out] none
  438. \retval none
  439. */
  440. static void enum_set_configuration_handle (usb_core_handle_struct *pudev,
  441. usbh_host_struct *puhost,
  442. usbh_state_handle_struct *pustate)
  443. {
  444. puhost->usbh_backup_state.enum_backup_state = ENUM_SET_CONFIGURATION;
  445. if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state ) {
  446. usbh_enum_cfg_set(pudev, puhost, (uint16_t)puhost->device.cfg_desc.bConfigurationValue);
  447. }
  448. if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) {
  449. scd_event_handle(pudev,
  450. puhost,
  451. pustate,
  452. ENUN_EVENT_DEV_CONFIGURED,
  453. pustate->usbh_current_state);
  454. }
  455. }
  456. /*!
  457. \brief the handle function of ENUM_DEV_CONFIGURED state
  458. \param[in] pudev: pointer to USB device
  459. \param[in] puhost: pointer to USB host
  460. \param[in] pustate: pointer to USB state driver
  461. \param[out] none
  462. \retval none
  463. */
  464. static void enum_dev_configured_handle (usb_core_handle_struct *pudev,
  465. usbh_host_struct *puhost,
  466. usbh_state_handle_struct *pustate)
  467. {
  468. puhost->usbh_backup_state.enum_backup_state = ENUM_DEV_CONFIGURED;
  469. scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state);
  470. }
  471. /*!
  472. \brief get descriptor in usb host enumeration stage
  473. \param[in] pudev: pointer to USB device
  474. \param[in] puhost: pointer to USB host
  475. \param[in] buf: buffer to store the descriptor
  476. \param[in] ReqType: descriptor type
  477. \param[in] ValueIdx: wValue for the GetDescriptr request
  478. \param[in] Len: length of the descriptor
  479. \param[out] none
  480. \retval none
  481. */
  482. void usbh_enum_desc_get(usb_core_handle_struct *pudev,
  483. usbh_host_struct *puhost,
  484. uint8_t *buf,
  485. uint8_t req_type,
  486. uint16_t value_idx,
  487. uint16_t len)
  488. {
  489. usb_setup_union *pSetup = &(puhost->control.setup);
  490. pSetup->b.bmRequestType = USB_DIR_IN | req_type;
  491. pSetup->b.bRequest = USBREQ_GET_DESCRIPTOR;
  492. pSetup->b.wValue = value_idx;
  493. if (USB_STRDESC == (value_idx & 0xff00U)){
  494. pSetup->b.wIndex = 0x0409U;
  495. } else {
  496. pSetup->b.wIndex = 0U;
  497. }
  498. pSetup->b.wLength = len;
  499. puhost->control.buff = buf;
  500. puhost->control.length = len;
  501. }
  502. /*!
  503. \brief set address in usb host enumeration stage
  504. \param[in] pudev: pointer to USB device
  505. \param[in] puhost: pointer to USB host
  506. \param[in] device_address: the device address
  507. \param[out] none
  508. \retval none
  509. */
  510. void usbh_enum_addr_set(usb_core_handle_struct *pudev,
  511. usbh_host_struct *puhost,
  512. uint8_t device_address)
  513. {
  514. usb_setup_union *p_setup = &(puhost->control.setup);
  515. p_setup->b.bmRequestType = USB_DIR_OUT | USB_REQTYPE_DEVICE | USB_STANDARD_REQ;
  516. p_setup->b.bRequest = USBREQ_SET_ADDRESS;
  517. p_setup->b.wValue = (uint16_t)device_address;
  518. p_setup->b.wIndex = 0U;
  519. p_setup->b.wLength = 0U;
  520. puhost->control.buff = 0U;
  521. puhost->control.length = 0U;
  522. }
  523. /*!
  524. \brief set configuration in usb host enumeration stage
  525. \param[in] pudev: pointer to USB device
  526. \param[in] puhost: pointer to USB host
  527. \param[in] cfg_idx: the index of the configuration
  528. \param[out] none
  529. \retval none
  530. */
  531. void usbh_enum_cfg_set(usb_core_handle_struct *pudev,
  532. usbh_host_struct *puhost,
  533. uint16_t cfg_idx)
  534. {
  535. usb_setup_union *p_setup = &(puhost->control.setup);
  536. p_setup->b.bmRequestType = USB_DIR_OUT | USB_REQTYPE_DEVICE | USB_STANDARD_REQ;
  537. p_setup->b.bRequest = USBREQ_SET_CONFIGURATION;
  538. p_setup->b.wValue = cfg_idx;
  539. p_setup->b.wIndex = 0U;
  540. p_setup->b.wLength = 0U;
  541. puhost->control.buff = 0;
  542. puhost->control.length = 0U;
  543. }
  544. /*!
  545. \brief parse the device descriptor
  546. \param[in] dev_desc: device_descriptor destinaton address
  547. \param[in] buf: buffer where the source descriptor is available
  548. \param[in] len: length of the descriptor
  549. \param[out] none
  550. \retval none
  551. */
  552. void usbh_device_desc_parse (usb_descriptor_device_struct *dev_desc, uint8_t *buf, uint16_t len)
  553. {
  554. dev_desc->Header.bLength = *(uint8_t *)(buf + 0);
  555. dev_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
  556. dev_desc->bcdUSB = SWAPBYTE(buf + 2);
  557. dev_desc->bDeviceClass = *(uint8_t *)(buf + 4);
  558. dev_desc->bDeviceSubClass = *(uint8_t *)(buf + 5);
  559. dev_desc->bDeviceProtocol = *(uint8_t *)(buf + 6);
  560. dev_desc->bMaxPacketSize0 = *(uint8_t *)(buf + 7);
  561. if (len > 8U){
  562. /* for 1st time after device connection, host may issue only 8 bytes for device descriptor length */
  563. dev_desc->idVendor = SWAPBYTE(buf + 8);
  564. dev_desc->idProduct = SWAPBYTE(buf + 10);
  565. dev_desc->bcdDevice = SWAPBYTE(buf + 12);
  566. dev_desc->iManufacturer = *(uint8_t *)(buf + 14);
  567. dev_desc->iProduct = *(uint8_t *)(buf + 15);
  568. dev_desc->iSerialNumber = *(uint8_t *)(buf + 16);
  569. dev_desc->bNumberConfigurations = *(uint8_t *)(buf + 17);
  570. }
  571. }
  572. /*!
  573. \brief parse the configuration descriptor
  574. \param[in] cfg_desc: configuration descriptor address
  575. \param[in] itf_desc: interface descriptor address
  576. \param[in] ep_desc: endpoint descriptor address
  577. \param[in] buf: buffer where the source descriptor is available
  578. \param[in] len: length of the descriptor
  579. \param[out] none
  580. \retval none
  581. */
  582. void usbh_cfg_desc_parse (usb_descriptor_configuration_struct *cfg_desc,
  583. usb_descriptor_interface_struct *itf_desc,
  584. usb_descriptor_endpoint_struct ep_desc[][USBH_MAX_EP_NUM],
  585. uint8_t *buf,
  586. uint16_t len)
  587. {
  588. usb_descriptor_interface_struct *pitf = NULL;
  589. usb_descriptor_interface_struct temp_pitf;
  590. usb_descriptor_endpoint_struct *pep = NULL;
  591. usb_descriptor_header_struct *pdesc = (usb_descriptor_header_struct *)buf;
  592. uint8_t itf_ix = 0U;
  593. uint8_t ep_ix = 0U;
  594. uint16_t ptr = 0U;
  595. static uint8_t prev_itf = 0U;
  596. static uint16_t prev_ep_size = 0U;
  597. /* parse configuration descriptor */
  598. cfg_desc->Header.bLength = *(uint8_t *)(buf + 0);
  599. cfg_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
  600. cfg_desc->wTotalLength = SWAPBYTE(buf + 2);
  601. cfg_desc->bNumInterfaces = *(uint8_t *)(buf + 4);
  602. cfg_desc->bConfigurationValue = *(uint8_t *)(buf + 5);
  603. cfg_desc->iConfiguration = *(uint8_t *)(buf + 6);
  604. cfg_desc->bmAttributes = *(uint8_t *)(buf + 7);
  605. cfg_desc->bMaxPower = *(uint8_t *)(buf + 8);
  606. if (len > USB_CFGDESC_SIZE) {
  607. ptr = USB_CFG_DESC_LEN;
  608. if (cfg_desc->bNumInterfaces <= USBH_MAX_INTERFACES_NUM) {
  609. pitf = (usb_descriptor_interface_struct *)0;
  610. for (; ptr < cfg_desc->wTotalLength; ) {
  611. pdesc = usbh_next_desc_get((uint8_t *)pdesc, &ptr);
  612. if (USB_DESCTYPE_INTERFACE == pdesc->bDescriptorType) {
  613. itf_ix = *((uint8_t *)pdesc + 2U);
  614. pitf = &itf_desc[itf_ix];
  615. if (*((uint8_t *)pdesc + 3U) < 3U) {
  616. usbh_interface_desc_parse (&temp_pitf, (uint8_t *)pdesc);
  617. /* parse endpoint descriptors relative to the current interface */
  618. if (temp_pitf.bNumEndpoints <= USBH_MAX_EP_NUM) {
  619. for (ep_ix = 0U; ep_ix < temp_pitf.bNumEndpoints;) {
  620. pdesc = usbh_next_desc_get((void* )pdesc, &ptr);
  621. if (USB_DESCTYPE_ENDPOINT == pdesc->bDescriptorType) {
  622. pep = &ep_desc[itf_ix][ep_ix];
  623. if (prev_itf != itf_ix) {
  624. prev_itf = itf_ix;
  625. usbh_interface_desc_parse (pitf, (uint8_t *)&temp_pitf);
  626. } else {
  627. if (prev_ep_size > SWAPBYTE((uint8_t *)pdesc + 4)) {
  628. break;
  629. } else {
  630. usbh_interface_desc_parse (pitf, (uint8_t *)&temp_pitf);
  631. }
  632. }
  633. usbh_endpoint_desc_parse (pep, (uint8_t *)pdesc);
  634. prev_ep_size = SWAPBYTE((uint8_t *)pdesc + 4);
  635. ep_ix++;
  636. }
  637. }
  638. }
  639. }
  640. }
  641. }
  642. }
  643. prev_ep_size = 0U;
  644. prev_itf = 0U;
  645. }
  646. }
  647. /*!
  648. \brief parse the interface descriptor
  649. \param[in] itf_desc: interface descriptor destination
  650. \param[in] buf: buffer where the descriptor data is available
  651. \param[out] none
  652. \retval none
  653. */
  654. void usbh_interface_desc_parse (usb_descriptor_interface_struct *itf_desc, uint8_t *buf)
  655. {
  656. itf_desc->Header.bLength = *(uint8_t *)(buf + 0);
  657. itf_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
  658. itf_desc->bInterfaceNumber = *(uint8_t *)(buf + 2);
  659. itf_desc->bAlternateSetting = *(uint8_t *)(buf + 3);
  660. itf_desc->bNumEndpoints = *(uint8_t *)(buf + 4);
  661. itf_desc->bInterfaceClass = *(uint8_t *)(buf + 5);
  662. itf_desc->bInterfaceSubClass = *(uint8_t *)(buf + 6);
  663. itf_desc->bInterfaceProtocol = *(uint8_t *)(buf + 7);
  664. itf_desc->iInterface = *(uint8_t *)(buf + 8);
  665. }
  666. /*!
  667. \brief parse the endpoint descriptor
  668. \param[in] ep_desc: endpoint descriptor destination address
  669. \param[in] buf: buffer where the parsed descriptor stored
  670. \param[out] none
  671. \retval none
  672. */
  673. void usbh_endpoint_desc_parse (usb_descriptor_endpoint_struct *ep_desc, uint8_t *buf)
  674. {
  675. ep_desc->Header.bLength = *(uint8_t *)(buf + 0);
  676. ep_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1);
  677. ep_desc->bEndpointAddress = *(uint8_t *)(buf + 2);
  678. ep_desc->bmAttributes = *(uint8_t *)(buf + 3);
  679. ep_desc->wMaxPacketSize = SWAPBYTE(buf + 4);
  680. ep_desc->bInterval = *(uint8_t *)(buf + 6);
  681. }
  682. /*!
  683. \brief parse the string descriptor
  684. \param[in] psrc: source pointer containing the descriptor data
  685. \param[in] pdest: destination address pointer
  686. \param[in] len: length of the descriptor
  687. \param[out] none
  688. \retval none
  689. */
  690. void usbh_string_desc_parse (uint8_t* psrc, uint8_t* pdest, uint16_t len)
  691. {
  692. uint16_t strlength;
  693. uint16_t idx;
  694. /* the unicode string descriptor is not null-terminated. the string length is
  695. computed by substracting two from the value of the first byte of the descriptor.
  696. */
  697. /* check which is lower size, the size of string or the length of bytes read from the device */
  698. if (USB_DESCTYPE_STRING == psrc[1]){
  699. /* make sure the descriptor is string type */
  700. /* psrc[0] contains size of descriptor, subtract 2 to get the length of string */
  701. strlength = ((((uint16_t)psrc[0] - 2U) <= len) ? ((uint16_t)psrc[0] - 2U) : len);
  702. psrc += 2; /* adjust the offset ignoring the string len and descriptor type */
  703. for (idx = 0U; idx < strlength; idx += 2U) {
  704. /* copy only the string and ignore the unicode id, hence add the src */
  705. *pdest = psrc[idx];
  706. pdest++;
  707. }
  708. *pdest = 0U; /* mark end of string */
  709. }
  710. }
  711. /*!
  712. \brief get the next descriptor header
  713. \param[in] pbuf: pointer to buffer where the cfg descriptor is available
  714. \param[in] ptr: data popinter inside the configuration descriptor
  715. \param[out] none
  716. \retval next descriptor header
  717. */
  718. usb_descriptor_header_struct *usbh_next_desc_get (uint8_t *pbuf, uint16_t *ptr)
  719. {
  720. uint8_t len = ((usb_descriptor_header_struct *)pbuf)->bLength;
  721. usb_descriptor_header_struct *pnext;
  722. *ptr += len;
  723. pnext = (usb_descriptor_header_struct *)((uint8_t *)pbuf + len);
  724. return(pnext);
  725. }