usbh_std.c 33 KB

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