usbh_std.c 32 KB

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