usbh_core.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /*!
  2. \file usbh_core.c
  3. \brief this file implements the functions for the core state machine process
  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_hcs.h"
  33. #include "usbh_core.h"
  34. #include "usbh_int.h"
  35. #include "stdio.h"
  36. #include "usbh_std.h"
  37. #include "usbh_ctrl.h"
  38. #include "usb_core.h"
  39. extern class_polling_fun_cb_struct class_polling_cb;
  40. uint8_t usbh_sof (usb_core_handle_struct *pudev);
  41. uint8_t usbh_connected (usb_core_handle_struct *pudev);
  42. uint8_t usbh_disconnected (usb_core_handle_struct *pudev);
  43. usbh_hcd_int_cb_struct usbh_hcd_int_cb =
  44. {
  45. usbh_sof,
  46. usbh_connected,
  47. usbh_disconnected,
  48. };
  49. usbh_hcd_int_cb_struct *usbh_hcd_int_fops = &usbh_hcd_int_cb;
  50. extern usbh_state_handle_struct usbh_state_core;
  51. static void host_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  52. static void host_dev_attached_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  53. static void host_dev_detached_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  54. static void host_detect_dev_speed_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  55. static void host_enum_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  56. static void host_class_request_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  57. static void host_class_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  58. static void host_user_input_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  59. static void host_suspended_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  60. static void host_error_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate);
  61. static usbh_status_enum class_req_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
  62. static usbh_status_enum class_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate);
  63. /* the host state handle function array */
  64. void (*host_state_handle[]) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) =
  65. {
  66. host_idle_handle,
  67. host_dev_attached_handle,
  68. host_dev_detached_handle,
  69. host_detect_dev_speed_handle,
  70. host_enum_handle,
  71. host_class_request_handle,
  72. host_class_handle,
  73. host_user_input_handle,
  74. host_suspended_handle,
  75. host_error_handle,
  76. };
  77. /* the host state handle table */
  78. state_table_struct host_handle_table[HOST_HANDLE_TABLE_SIZE] =
  79. {
  80. /* the current state the current event the next state the event function */
  81. {HOST_IDLE, HOST_EVENT_ATTACHED, HOST_DEV_ATTACHED, only_state_move },
  82. {HOST_DEV_ATTACHED, HOST_EVENT_ENUM, HOST_ENUMERATION, only_state_move },
  83. {HOST_ENUMERATION, HOST_EVENT_USER_INPUT, HOST_USER_INPUT, only_state_move },
  84. {HOST_USER_INPUT, HOST_EVENT_CLASS_REQ, HOST_CLASS_REQUEST, only_state_move },
  85. {HOST_CLASS_REQUEST, HOST_EVENT_CLASS, HOST_CLASS, only_state_move },
  86. {HOST_CLASS, HOST_EVENT_ERROR, HOST_ERROR, only_state_move },
  87. {HOST_ERROR, HOST_EVENT_IDLE, HOST_IDLE, only_state_move },
  88. {HOST_DEV_DETACHED, HOST_EVENT_IDLE, HOST_IDLE, only_state_move },
  89. {HOST_CLASS_REQUEST, HOST_EVENT_ERROR, HOST_ERROR, only_state_move },
  90. };
  91. /*!
  92. \brief the polling function of host state
  93. \param[in] pudev: pointer to usb device
  94. \param[in] puhost: pointer to usb host
  95. \param[in] pustate: pointer to usb state driver
  96. \param[out] none
  97. \retval none
  98. */
  99. usbh_status_enum host_state_polling_fun (usb_core_handle_struct *pudev,
  100. usbh_host_struct *puhost,
  101. void *pustate)
  102. {
  103. usbh_state_handle_struct *p_state = (usbh_state_handle_struct *)pustate;
  104. scd_begin(p_state, HOST_FSM_ID);
  105. if (-1 == p_state->usbh_current_state_stack_top) {
  106. uint8_t cur_state = p_state->usbh_current_state;
  107. if ((0U == hcd_is_device_connected(pudev)) && (HOST_IDLE != cur_state)) {
  108. if (HOST_DEV_DETACHED != cur_state) {
  109. p_state->usbh_current_state = HOST_DEV_DETACHED;
  110. cur_state = HOST_DEV_DETACHED;
  111. }
  112. }
  113. host_state_handle[cur_state](pudev, puhost, p_state);
  114. } else {
  115. uint8_t stack0_state = p_state->stack[0].state;
  116. if ((0U == hcd_is_device_connected(pudev)) && (HOST_IDLE != stack0_state)) {
  117. if (HOST_DEV_DETACHED != stack0_state) {
  118. p_state->stack[0].state = HOST_DEV_DETACHED;
  119. stack0_state = HOST_DEV_DETACHED;
  120. p_state->usbh_current_state = HOST_DEV_DETACHED;
  121. }
  122. }
  123. host_state_handle[stack0_state](pudev, puhost, p_state);
  124. }
  125. return USBH_OK;
  126. }
  127. /*!
  128. \brief the handle function of HOST_IDLE state
  129. \param[in] pudev: pointer to usb device
  130. \param[in] puhost: pointer to usb host
  131. \param[in] pustate: pointer to usb state driver
  132. \param[out] none
  133. \retval none
  134. */
  135. static void host_idle_handle (usb_core_handle_struct *pudev,
  136. usbh_host_struct *puhost,
  137. usbh_state_handle_struct *pustate)
  138. {
  139. if (hcd_is_device_connected(pudev)) {
  140. scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ATTACHED, pustate->usbh_current_state);
  141. if ((void *)0 != pudev->mdelay) {
  142. pudev->mdelay(100U);
  143. }
  144. }
  145. }
  146. /*!
  147. \brief the handle function of HOST_DEV_ATTACHED state
  148. \param[in] pudev: pointer to usb device
  149. \param[in] puhost: pointer to usb host
  150. \param[in] pustate: pointer to usb state driver
  151. \param[out] none
  152. \retval none
  153. */
  154. static void host_dev_attached_handle (usb_core_handle_struct *pudev,
  155. usbh_host_struct *puhost,
  156. usbh_state_handle_struct *pustate)
  157. {
  158. puhost->usr_cb->device_connected();
  159. puhost->control.hc_out_num = usbh_channel_alloc(pudev, 0x00U);
  160. puhost->control.hc_in_num = usbh_channel_alloc(pudev, 0x80U);
  161. /* reset usb device */
  162. if (0U == usb_port_reset(pudev)) {
  163. puhost->usr_cb->device_reset();
  164. /* wait for USB USBH_ISR_PrtEnDisableChange()
  165. * host is now ready to start the enumeration
  166. */
  167. puhost->device.speed = (uint8_t)USB_CURRENT_SPEED_GET();
  168. puhost->usr_cb->device_speed_detected(puhost->device.speed);
  169. /* open in control pipes */
  170. usbh_channel_open (pudev,
  171. puhost->control.hc_in_num,
  172. puhost->device.address,
  173. puhost->device.speed,
  174. USB_EPTYPE_CTRL,
  175. (uint16_t)puhost->control.ep0_size);
  176. /* open out control pipes */
  177. usbh_channel_open (pudev,
  178. puhost->control.hc_out_num,
  179. puhost->device.address,
  180. puhost->device.speed,
  181. USB_EPTYPE_CTRL,
  182. (uint16_t)puhost->control.ep0_size);
  183. scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ENUM, pustate->usbh_current_state);
  184. }
  185. }
  186. /*!
  187. \brief the handle function of HOST_ENUMERATION state
  188. \param[in] pudev: pointer to usb device
  189. \param[in] puhost: pointer to usb host
  190. \param[in] pustate: pointer to usb state driver
  191. \param[out] none
  192. \retval none
  193. */
  194. static void host_enum_handle (usb_core_handle_struct *pudev,
  195. usbh_host_struct *puhost,
  196. usbh_state_handle_struct *pustate)
  197. {
  198. if (USBH_OK == enum_state_polling_fun(pudev, puhost, pustate)) {
  199. puhost->usr_cb->enumeration_finish();
  200. scd_event_handle(pudev,
  201. puhost,
  202. pustate,
  203. HOST_EVENT_USER_INPUT,
  204. pustate->usbh_current_state);
  205. }
  206. }
  207. /*!
  208. \brief the handle function of HOST_USER_INPUT state
  209. \param[in] pudev: pointer to usb device
  210. \param[in] puhost: pointer to usb host
  211. \param[in] pustate: pointer to usb state driver
  212. \param[out] none
  213. \retval none
  214. */
  215. static void host_user_input_handle (usb_core_handle_struct *pudev,
  216. usbh_host_struct *puhost,
  217. usbh_state_handle_struct *pustate)
  218. {
  219. if (USBH_USER_RESP_OK == puhost->usr_cb->user_input()) {
  220. if (USBH_OK == (puhost->class_init(pudev, puhost))) {
  221. scd_event_handle(pudev,
  222. puhost,
  223. pustate,
  224. HOST_EVENT_CLASS_REQ,
  225. pustate->usbh_current_state);
  226. }
  227. }
  228. }
  229. /*!
  230. \brief the handle function of HOST_CLASS_REQUEST state
  231. \param[in] pudev: pointer to usb device
  232. \param[in] puhost: pointer to usb host
  233. \param[in] pustate: pointer to usb state driver
  234. \param[out] none
  235. \retval none
  236. */
  237. static void host_class_request_handle (usb_core_handle_struct *pudev,
  238. usbh_host_struct *puhost,
  239. usbh_state_handle_struct *pustate)
  240. {
  241. if (USBH_OK == class_req_state_polling_fun(pudev, puhost, pustate)) {
  242. scd_event_handle(pudev, puhost, pustate, HOST_EVENT_CLASS, pustate->usbh_current_state);
  243. }
  244. }
  245. /*!
  246. \brief the handle function of HOST_CLASS state
  247. \param[in] pudev: pointer to usb device
  248. \param[in] puhost: pointer to usb host
  249. \param[in] pustate: pointer to usb state driver
  250. \param[out] none
  251. \retval none
  252. */
  253. static void host_class_handle (usb_core_handle_struct *pudev,
  254. usbh_host_struct *puhost,
  255. usbh_state_handle_struct *pustate)
  256. {
  257. class_state_polling_fun(pudev, puhost, pustate);
  258. }
  259. /*!
  260. \brief the handle function of HOST_SUSPENDED state
  261. \param[in] pudev: pointer to usb device
  262. \param[in] puhost: pointer to usb host
  263. \param[in] pustate: pointer to usb state driver
  264. \param[out] none
  265. \retval none
  266. */
  267. static void host_suspended_handle (usb_core_handle_struct *pudev,
  268. usbh_host_struct *puhost,
  269. usbh_state_handle_struct *pustate)
  270. {
  271. /* no operation */
  272. }
  273. /*!
  274. \brief the handle function of HOST_ERROR 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 host_error_handle (usb_core_handle_struct *pudev,
  282. usbh_host_struct *puhost,
  283. usbh_state_handle_struct *pustate)
  284. {
  285. /* re-initilaize host for new enumeration */
  286. usbh_deinit (pudev, puhost,&usbh_state_core);
  287. puhost->usr_cb->deinit();
  288. puhost->class_deinit(pudev, &puhost->device);
  289. scd_event_handle(pudev, puhost, pustate, HOST_EVENT_IDLE, pustate->usbh_current_state);
  290. }
  291. /*!
  292. \brief the handle function of HOST_DEV_DETACHED state
  293. \param[in] pudev: pointer to usb device
  294. \param[in] puhost: pointer to usb host
  295. \param[in] pustate: pointer to usb state driver
  296. \param[out] none
  297. \retval none
  298. */
  299. static void host_dev_detached_handle (usb_core_handle_struct *pudev,
  300. usbh_host_struct *puhost,
  301. usbh_state_handle_struct *pustate)
  302. {
  303. /* manage user disconnect operations*/
  304. puhost->usr_cb->device_disconnected();
  305. /* re-initilaize host for new enumeration */
  306. usbh_deinit(pudev, puhost,&usbh_state_core);
  307. puhost->usr_cb->deinit();
  308. puhost->class_deinit(pudev, &puhost->device);
  309. usbh_allchannel_dealloc(pudev);
  310. scd_event_handle(pudev, puhost, pustate, HOST_EVENT_IDLE, pustate->usbh_current_state);
  311. }
  312. /*!
  313. \brief the handle function of HOST_DETECT_DEV_SPEED state
  314. \param[in] pudev: pointer to usb device
  315. \param[in] puhost: pointer to usb host
  316. \param[in] pustate: pointer to usb state driver
  317. \param[out] none
  318. \retval none
  319. */
  320. static void host_detect_dev_speed_handle (usb_core_handle_struct *pudev,
  321. usbh_host_struct *puhost,
  322. usbh_state_handle_struct *pustate)
  323. {
  324. /* no operation */
  325. }
  326. /*!
  327. \brief usb connect callback function from the interrupt.
  328. \param[in] pudev: pointer to usb device
  329. \param[out] none
  330. \retval operation status
  331. */
  332. uint8_t usbh_connected (usb_core_handle_struct *pudev)
  333. {
  334. pudev->host.connect_status = 1U;
  335. return 0U;
  336. }
  337. /*!
  338. \brief usb disconnect callback function from the interrupt.
  339. \param[in] pudev: pointer to usb device
  340. \param[out] none
  341. \retval operation status
  342. */
  343. uint8_t usbh_disconnected (usb_core_handle_struct *pudev)
  344. {
  345. pudev->host.connect_status = 0U;
  346. return 0U;
  347. }
  348. /*!
  349. \brief usb sof callback function from the interrupt.
  350. \param[in] pudev: pointer to usb device
  351. \param[out] none
  352. \retval operation status
  353. */
  354. uint8_t usbh_sof (usb_core_handle_struct *pudev)
  355. {
  356. /* this callback could be used to implement a scheduler process */
  357. return 0U;
  358. }
  359. /*!
  360. \brief initialize the host portion of the driver.
  361. \param[in] pudev: pointer to usb device
  362. \param[in] core_id: usb otg core identifier(high-speed or full-speed)
  363. \param[out] none
  364. \retval operation status
  365. */
  366. uint32_t hcd_init(usb_core_handle_struct *pudev, usb_core_id_enum core_id)
  367. {
  368. pudev->host.connect_status = 0U;
  369. pudev->host.host_channel[0].endp_mps = 8U;
  370. usb_core_select(pudev, core_id);
  371. #ifndef DUAL_ROLE_MODE_ENABLED
  372. USB_GLOBAL_INT_DISABLE();
  373. usb_core_init(pudev);
  374. /* force host mode*/
  375. usb_mode_set(pudev, HOST_MODE);
  376. usb_hostcore_init(pudev);
  377. USB_GLOBAL_INT_ENABLE();
  378. #endif
  379. return 0U;
  380. }
  381. /*!
  382. \brief check if the device is connected.
  383. \param[in] pudev: pointer to usb device
  384. \param[out] none
  385. \retval device connection status. 1 -> connected and 0 -> disconnected
  386. */
  387. uint32_t hcd_is_device_connected(usb_core_handle_struct *pudev)
  388. {
  389. return (uint32_t)(pudev->host.connect_status);
  390. }
  391. /*!
  392. \brief this function returns the last URBstate
  393. \param[in] pudev: pointer to usb device
  394. \param[in] channel_num: host channel number which is in (0..7)
  395. \param[out] none
  396. \retval urb_state_enum
  397. */
  398. urb_state_enum hcd_urb_state_get (usb_core_handle_struct *pudev, uint8_t channel_num)
  399. {
  400. return pudev->host.host_channel[channel_num].urb_state;
  401. }
  402. /*!
  403. \brief this function returns the last URBstate
  404. \param[in] pudev: pointer to usb device
  405. \param[in] channel_num: host channel number which is in (0..7)
  406. \param[out] none
  407. \retval No. of data bytes transferred
  408. */
  409. uint32_t hcd_xfer_count_get (usb_core_handle_struct *pudev, uint8_t channel_num)
  410. {
  411. return pudev->host.host_channel[channel_num].xfer_count;
  412. }
  413. /*!
  414. \brief de-initialize host
  415. \param[in] pudev: pointer to usb device
  416. \param[in] puhost: pointer to usb host
  417. \param[out] none
  418. \retval host status
  419. */
  420. usbh_status_enum usbh_deinit(usb_core_handle_struct *pudev,
  421. usbh_host_struct *puhost,
  422. usbh_state_handle_struct* pustate)
  423. {
  424. /* software init */
  425. puhost->control.ep0_size = USB_MAX_EP0_SIZE;
  426. puhost->device.address = USBH_DEVICE_ADDRESS_DEFAULT;
  427. puhost->device.speed = HPRT_PRTSPD_FULL_SPEED;
  428. usbh_channel_free(pudev, puhost->control.hc_in_num);
  429. usbh_channel_free(pudev, puhost->control.hc_out_num);
  430. scd_init(pustate);
  431. scd_table_regist(pustate, host_handle_table, HOST_FSM_ID, HOST_HANDLE_TABLE_SIZE);
  432. scd_table_regist(pustate, enum_handle_table, ENUM_FSM_ID, ENUM_HANDLE_TABLE_SIZE);
  433. scd_table_regist(pustate, ctrl_handle_table, CTRL_FSM_ID, CTRL_HANDLE_TABLE_SIZE);
  434. scd_begin(pustate,HOST_FSM_ID);
  435. scd_state_move(pustate, HOST_IDLE);
  436. return USBH_OK;
  437. }
  438. /*!
  439. \brief state core driver init
  440. \param[in] pustate: pointer to usb state driver
  441. \param[out] none
  442. \retval none
  443. */
  444. void scd_init(usbh_state_handle_struct* pustate)
  445. {
  446. /* init the state core */
  447. pustate->usbh_current_state = 0U;
  448. pustate->usbh_current_state_table = NULL;
  449. pustate->usbh_current_state_table_size = 0U;
  450. pustate->usbh_current_state_stack_top = -1;
  451. pustate->stack->state = 0U;
  452. pustate->stack->table_size = 0U;
  453. pustate->stack->table = NULL;
  454. pustate->usbh_regist_state_table_num = 0U;
  455. pustate->usbh_regist_state_table->table = NULL;
  456. pustate->usbh_regist_state_table->table_size = 0U;
  457. pustate->usbh_regist_state_table->id = 0U;
  458. /* init the control and the enumeration polling handle flag */
  459. ctrl_polling_handle_flag = 0U;
  460. enum_polling_handle_flag = 0U;
  461. }
  462. /*!
  463. \brief state core driver table regist
  464. \param[in] pustate: pointer to usb state driver
  465. \param[in] pstate_table: pointer to the table to regist
  466. \param[in] table_id: the id of the table to regist
  467. \param[in] current_table_size: the size of the current table to regist
  468. \param[out] none
  469. \retval none
  470. */
  471. void scd_table_regist (usbh_state_handle_struct* pustate,
  472. state_table_struct* pstate_table,
  473. uint8_t table_id,
  474. uint8_t current_table_size)
  475. {
  476. usbh_state_regist_table_struct *cur_state_reg_table;
  477. cur_state_reg_table = &pustate->usbh_regist_state_table[pustate->usbh_regist_state_table_num];
  478. cur_state_reg_table->id = table_id;
  479. cur_state_reg_table->table = pstate_table;
  480. cur_state_reg_table->table_size = current_table_size;
  481. pustate->usbh_regist_state_table_num++;
  482. }
  483. /*!
  484. \brief state core driver begin
  485. \param[in] pustate: pointer to usb state driver
  486. \param[in] table_id: the id of the table to begin
  487. \param[out] none
  488. \retval none
  489. */
  490. void scd_begin(usbh_state_handle_struct* pustate, uint8_t table_id)
  491. {
  492. uint8_t i = 0U, table_num = pustate->usbh_regist_state_table_num;
  493. usbh_state_regist_table_struct *cur_state_reg_table;
  494. for (i = 0U; i < table_num; i++) {
  495. cur_state_reg_table = &pustate->usbh_regist_state_table[i];
  496. if (table_id == cur_state_reg_table->id) {
  497. pustate->usbh_current_state_table = cur_state_reg_table->table;
  498. pustate->usbh_current_state_table_size = cur_state_reg_table->table_size;
  499. break;
  500. }
  501. }
  502. }
  503. /*!
  504. \brief state core driver move state
  505. \param[in] pustate: pointer to usb state driver
  506. \param[in] state: the state to move
  507. \param[out] none
  508. \retval none
  509. */
  510. void scd_state_move(usbh_state_handle_struct* pustate, uint8_t state)
  511. {
  512. pustate->usbh_current_state = state;
  513. }
  514. /*!
  515. \brief state core driver event handle
  516. \param[in] pudev: pointer to usb device
  517. \param[in] puhost: pointer to usb host
  518. \param[in] pustate: pointer to usb state driver
  519. \param[in] event: the current event
  520. \param[in] state: the current state
  521. \param[out] none
  522. \retval host status
  523. */
  524. usbh_status_enum scd_event_handle (usb_core_handle_struct *pudev,
  525. usbh_host_struct *puhost,
  526. usbh_state_handle_struct* pustate,
  527. uint8_t event,
  528. uint8_t state)
  529. {
  530. uint8_t i = 0U;
  531. ACT_FUN event_act_fun = NULL;
  532. state_table_struct *backup_state_t = pustate->usbh_current_state_table;
  533. state_table_struct *executive_state_table = pustate->usbh_current_state_table;
  534. /* look up the table to find the action function */
  535. for (i = 0U; i < pustate->usbh_current_state_table_size; i++) {
  536. if (state == executive_state_table->cur_state) {
  537. if (event == executive_state_table->cur_event) {
  538. state = executive_state_table->next_state;
  539. event_act_fun = executive_state_table->event_action_fun;
  540. break;
  541. } else {
  542. executive_state_table++;
  543. }
  544. } else {
  545. executive_state_table++;
  546. }
  547. }
  548. pustate->usbh_current_state_table = backup_state_t;
  549. /* if the action function is not NULL, execute the action function */
  550. if (event_act_fun) {
  551. if (event_act_fun == &only_state_move) {
  552. pustate->usbh_current_state = state;
  553. } else {
  554. return event_act_fun(pudev, puhost, pustate);
  555. }
  556. }
  557. return USBH_BUSY;
  558. }
  559. /*!
  560. \brief state core driver table push
  561. \param[in] pustate: pointer to usb state driver
  562. \param[out] none
  563. \retval none
  564. */
  565. void scd_table_push(usbh_state_handle_struct* pustate)
  566. {
  567. usbh_state_stack_struct *top_state_element;
  568. if (pustate->usbh_current_state_stack_top < MAX_USBH_STATE_STACK_DEEP) {
  569. pustate->usbh_current_state_stack_top++;
  570. top_state_element = &pustate->stack[pustate->usbh_current_state_stack_top];
  571. /* put the current state table into the state stack */
  572. top_state_element->state = pustate->usbh_current_state;
  573. top_state_element->table = pustate->usbh_current_state_table;
  574. top_state_element->table_size = pustate->usbh_current_state_table_size;
  575. }
  576. }
  577. /*!
  578. \brief state core driver table pop
  579. \param[in] pustate: pointer to usb state driver
  580. \param[out] none
  581. \retval none
  582. */
  583. void scd_table_pop (usbh_state_handle_struct* pustate)
  584. {
  585. usbh_state_stack_struct *top_state_element;
  586. top_state_element = &pustate->stack[pustate->usbh_current_state_stack_top];
  587. if (pustate->usbh_current_state_stack_top > -1) {
  588. /* get the current state table from the state stack */
  589. pustate->usbh_current_state = top_state_element->state;
  590. pustate->usbh_current_state_table = top_state_element->table;
  591. pustate->usbh_current_state_table_size = top_state_element->table_size;
  592. pustate->usbh_current_state_stack_top--;
  593. }
  594. }
  595. /*!
  596. \brief the polling function of class req state
  597. \param[in] pudev: pointer to usb device
  598. \param[in] puhost: pointer to usb host
  599. \param[in] pustate: pointer to usb state driver
  600. \param[out] none
  601. \retval host status
  602. */
  603. static usbh_status_enum class_req_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
  604. {
  605. return class_polling_cb.class_req_polling(pudev, puhost, pustate);
  606. }
  607. /*!
  608. \brief the polling function of class state
  609. \param[in] pudev: pointer to usb device
  610. \param[in] puhost: pointer to usb host
  611. \param[in] pustate: pointer to usb state driver
  612. \param[out] none
  613. \retval host status
  614. */
  615. static usbh_status_enum class_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
  616. {
  617. return class_polling_cb.class_polling(pudev, puhost, pustate);
  618. }
  619. /*!
  620. \brief the function is only used to state move
  621. \param[in] pudev: pointer to usb device
  622. \param[in] puhost: pointer to usb host
  623. \param[in] pustate: pointer to usb state driver
  624. \param[out] none
  625. \retval none
  626. */
  627. usbh_status_enum only_state_move (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
  628. {
  629. return USBH_OK;
  630. }
  631. /*!
  632. \brief the function to the up state
  633. \param[in] pudev: pointer to usb device
  634. \param[in] puhost: pointer to usb host
  635. \param[in] pustate: pointer to usb state driver
  636. \param[out] none
  637. \retval none
  638. */
  639. usbh_status_enum goto_up_state_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate)
  640. {
  641. scd_table_pop((usbh_state_handle_struct *)pustate);
  642. return USBH_OK;
  643. }