usbh_ctrl.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. /**
  2. **************************************************************************
  3. * @file usbh_ctrl.c
  4. * @brief usb host control request
  5. **************************************************************************
  6. * Copyright notice & Disclaimer
  7. *
  8. * The software Board Support Package (BSP) that is made available to
  9. * download from Artery official website is the copyrighted work of Artery.
  10. * Artery authorizes customers to use, copy, and distribute the BSP
  11. * software and its related documentation for the purpose of design and
  12. * development in conjunction with Artery microcontrollers. Use of the
  13. * software is governed by this copyright notice and the following disclaimer.
  14. *
  15. * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  16. * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  17. * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  18. * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  19. * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  21. *
  22. **************************************************************************
  23. */
  24. #include "usbh_ctrl.h"
  25. #include "usbh_core.h"
  26. #include "usb_std.h"
  27. #ifdef USE_OTG_HOST_MODE
  28. /** @defgroup USBH_drivers_control
  29. * @brief usb host drivers control
  30. * @{
  31. */
  32. /** @defgroup USBH_ctrl_private_functions
  33. * @{
  34. */
  35. /* control timeout 5s */
  36. #define CTRL_TIMEOUT 10000
  37. /**
  38. * @brief usb host control send setup packet
  39. * @param uhost: to the structure of usbh_core_type
  40. * @param buffer: usb control setup send buffer
  41. * @param hc_num: channel number
  42. * @retval status: usb_sts_type status
  43. */
  44. usb_sts_type usbh_ctrl_send_setup(usbh_core_type *uhost, uint8_t *buffer, uint8_t hc_num)
  45. {
  46. uhost->hch[hc_num].dir = 0;
  47. uhost->hch[hc_num].data_pid = HCH_PID_SETUP;
  48. uhost->hch[hc_num].trans_buf = buffer;
  49. uhost->hch[hc_num].trans_len = 8; /*setup */
  50. return usbh_in_out_request(uhost, hc_num);
  51. }
  52. /**
  53. * @brief usb host control receive data from device
  54. * @param uhost: to the structure of usbh_core_type
  55. * @param buffer: usb control receive data buffer
  56. * @param length: usb control receive data length
  57. * @param hc_num: channel number
  58. * @retval status: usb_sts_type status
  59. */
  60. usb_sts_type usbh_ctrl_recv_data(usbh_core_type *uhost, uint8_t *buffer,
  61. uint16_t length, uint16_t hc_num)
  62. {
  63. uhost->hch[hc_num].dir = 1;
  64. uhost->hch[hc_num].data_pid = HCH_PID_DATA1;
  65. uhost->hch[hc_num].trans_buf = buffer;
  66. uhost->hch[hc_num].trans_len = length;
  67. return usbh_in_out_request(uhost, hc_num);
  68. }
  69. /**
  70. * @brief usb host control send data packet
  71. * @param uhost: to the structure of usbh_core_type
  72. * @param buffer: usb control send data buffer
  73. * @param length: usb control send data length
  74. * @param hc_num: channel number
  75. * @retval status: usb_sts_type status
  76. */
  77. usb_sts_type usbh_ctrl_send_data(usbh_core_type *uhost, uint8_t *buffer,
  78. uint16_t length, uint16_t hc_num)
  79. {
  80. uhost->hch[hc_num].dir = 0;
  81. uhost->hch[hc_num].trans_buf = buffer;
  82. uhost->hch[hc_num].trans_len = length;
  83. if(length == 0)
  84. {
  85. uhost->hch[uhost->ctrl.hch_out].toggle_out = 1;
  86. }
  87. if(uhost->hch[uhost->ctrl.hch_out].toggle_out == 0)
  88. {
  89. uhost->hch[hc_num].data_pid = HCH_PID_DATA0;
  90. }
  91. else
  92. {
  93. uhost->hch[hc_num].data_pid = HCH_PID_DATA1;
  94. }
  95. return usbh_in_out_request(uhost, hc_num);
  96. }
  97. /**
  98. * @brief usb host control setup request handler
  99. * @param uhost: to the structure of usbh_core_type
  100. * @retval status: usb_sts_type status
  101. */
  102. usb_sts_type usbh_ctrl_setup_handler(usbh_core_type *uhost)
  103. {
  104. usbh_ctrl_send_setup(uhost, (uint8_t *)(&uhost->ctrl.setup),
  105. uhost->ctrl.hch_out);
  106. uhost->ctrl.state = CONTROL_SETUP_WAIT;
  107. return USB_OK;
  108. }
  109. /**
  110. * @brief usb host control setup request wait handler
  111. * @param uhost: to the structure of usbh_core_type
  112. * @param timeout: pointer of wait timeout
  113. * @retval status: usb_sts_type status
  114. */
  115. usb_sts_type usbh_ctrl_setup_wait_handler(usbh_core_type *uhost, uint32_t *timeout)
  116. {
  117. urb_sts_type urb_state;
  118. usb_sts_type status = USB_WAIT;
  119. uint8_t dir;
  120. urb_state = uhost->urb_state[uhost->ctrl.hch_out];
  121. if(urb_state == URB_DONE)
  122. {
  123. dir = uhost->ctrl.setup.bmRequestType & USB_REQUEST_DIR_MASK;
  124. if(uhost->ctrl.setup.wLength != 0)
  125. {
  126. *timeout = DATA_STAGE_TIMEOUT;
  127. if(dir == USB_DIR_D2H) //in
  128. {
  129. uhost->ctrl.state = CONTROL_DATA_IN;
  130. }
  131. else //out
  132. {
  133. uhost->ctrl.state = CONTROL_DATA_OUT;
  134. }
  135. }
  136. else
  137. {
  138. *timeout = NODATA_STAGE_TIMEOUT;
  139. if(dir == USB_DIR_D2H) //no data, send status
  140. {
  141. uhost->ctrl.state = CONTROL_STATUS_OUT;
  142. }
  143. else //out
  144. {
  145. uhost->ctrl.state = CONTROL_STATUS_IN;
  146. }
  147. }
  148. uhost->ctrl.timer = uhost->timer;
  149. status = USB_OK;
  150. }
  151. else if(urb_state == URB_ERROR || urb_state == URB_NOTREADY)
  152. {
  153. uhost->ctrl.state = CONTROL_ERROR;
  154. uhost->ctrl.sts = CTRL_XACTERR;
  155. status = USB_ERROR;
  156. }
  157. else
  158. {
  159. /* wait nak timeout 5s*/
  160. if(uhost->timer - uhost->ctrl.timer > CTRL_TIMEOUT)
  161. {
  162. uhost->ctrl.state = CONTROL_ERROR;
  163. uhost->ctrl.sts = CTRL_XACTERR;
  164. status = USB_ERROR;
  165. }
  166. }
  167. return status;
  168. }
  169. /**
  170. * @brief usb host control data in request handler
  171. * @param uhost: to the structure of usbh_core_type
  172. * @retval status: usb_sts_type status
  173. */
  174. usb_sts_type usbh_ctrl_data_in_handler(usbh_core_type *uhost)
  175. {
  176. usb_sts_type status = USB_OK;
  177. usbh_ctrl_recv_data(uhost, uhost->ctrl.buffer,
  178. uhost->ctrl.len,
  179. uhost->ctrl.hch_in);
  180. uhost->ctrl.state = CONTROL_DATA_IN_WAIT;
  181. return status;
  182. }
  183. /**
  184. * @brief usb host control data in wait handler
  185. * @param uhost: to the structure of usbh_core_type
  186. * @param timeout: wait timeout
  187. * @retval status: usb_sts_type status
  188. */
  189. usb_sts_type usbh_ctrl_data_in_wait_handler(usbh_core_type *uhost, uint32_t timeout)
  190. {
  191. usb_sts_type status = USB_OK;
  192. urb_sts_type urb_state;
  193. urb_state = uhost->urb_state[uhost->ctrl.hch_in];
  194. if(urb_state == URB_DONE)
  195. {
  196. uhost->ctrl.state = CONTROL_STATUS_OUT;
  197. }
  198. else if(urb_state == URB_STALL)
  199. {
  200. uhost->ctrl.state = CONTROL_STALL;
  201. }
  202. else if(urb_state == URB_ERROR)
  203. {
  204. uhost->ctrl.state = CONTROL_ERROR;
  205. }
  206. else
  207. {
  208. /* wait nak timeout 5s*/
  209. if(uhost->timer - uhost->ctrl.timer > CTRL_TIMEOUT)
  210. {
  211. uhost->ctrl.state = CONTROL_ERROR;
  212. uhost->ctrl.sts = CTRL_XACTERR;
  213. status = USB_ERROR;
  214. }
  215. }
  216. return status;
  217. }
  218. /**
  219. * @brief usb host control data out request handler
  220. * @param uhost: to the structure of usbh_core_type
  221. * @retval status: usb_sts_type status
  222. */
  223. usb_sts_type usbh_ctrl_data_out_handler(usbh_core_type *uhost)
  224. {
  225. usb_sts_type status = USB_OK;
  226. uhost->hch[uhost->ctrl.hch_out].toggle_out = 1;
  227. usbh_ctrl_send_data(uhost, uhost->ctrl.buffer,
  228. uhost->ctrl.len,
  229. uhost->ctrl.hch_out);
  230. uhost->ctrl.state = CONTROL_DATA_OUT_WAIT;
  231. return status;
  232. }
  233. /**
  234. * @brief usb host control data out wait handler
  235. * @param uhost: to the structure of usbh_core_type
  236. * @param timeout: wait timeout
  237. * @retval status: usb_sts_type status
  238. */
  239. usb_sts_type usbh_ctrl_data_out_wait_handler(usbh_core_type *uhost, uint32_t timeout)
  240. {
  241. usb_sts_type status = USB_OK;
  242. urb_sts_type urb_state;
  243. urb_state = uhost->urb_state[uhost->ctrl.hch_out];
  244. if(urb_state == URB_DONE)
  245. {
  246. uhost->ctrl.state = CONTROL_STATUS_IN;
  247. }
  248. else if(urb_state == URB_STALL)
  249. {
  250. uhost->ctrl.state = CONTROL_STALL;
  251. }
  252. else if(urb_state == URB_ERROR)
  253. {
  254. uhost->ctrl.state = CONTROL_ERROR;
  255. }
  256. else if(urb_state == URB_NOTREADY)
  257. {
  258. uhost->ctrl.state = CONTROL_DATA_OUT;
  259. }
  260. /* wait nak timeout 5s*/
  261. if((uhost->timer - uhost->ctrl.timer > CTRL_TIMEOUT) && (urb_state == URB_NOTREADY))
  262. {
  263. uhost->ctrl.state = CONTROL_ERROR;
  264. uhost->ctrl.sts = CTRL_XACTERR;
  265. status = USB_ERROR;
  266. }
  267. return status;
  268. }
  269. /**
  270. * @brief usb host control status data in handler
  271. * @param uhost: to the structure of usbh_core_type
  272. * @retval status: usb_sts_type status
  273. */
  274. usb_sts_type usbh_ctrl_status_in_handler(usbh_core_type *uhost)
  275. {
  276. usb_sts_type status = USB_OK;
  277. usbh_ctrl_recv_data(uhost, 0, 0,
  278. uhost->ctrl.hch_in);
  279. uhost->ctrl.state = CONTROL_STATUS_IN_WAIT;
  280. return status;
  281. }
  282. /**
  283. * @brief usb host control status data in wait handler
  284. * @param uhost: to the structure of usbh_core_type
  285. * @param timeout: wait timeout
  286. * @retval status: usb_sts_type status
  287. */
  288. usb_sts_type usbh_ctrl_status_in_wait_handler(usbh_core_type *uhost, uint32_t timeout)
  289. {
  290. usb_sts_type status = USB_OK;
  291. urb_sts_type urb_state;
  292. urb_state = uhost->urb_state[uhost->ctrl.hch_in];
  293. if(urb_state == URB_DONE)
  294. {
  295. uhost->ctrl.state = CONTROL_COMPLETE;
  296. }
  297. else if(urb_state == URB_STALL)
  298. {
  299. uhost->ctrl.state = CONTROL_STALL;
  300. status = USB_NOT_SUPPORT;
  301. }
  302. else if(urb_state == URB_ERROR)
  303. {
  304. uhost->ctrl.state = CONTROL_ERROR;
  305. }
  306. else
  307. {
  308. /* wait nak timeout 5s*/
  309. if(uhost->timer - uhost->ctrl.timer > CTRL_TIMEOUT)
  310. {
  311. uhost->ctrl.state = CONTROL_ERROR;
  312. uhost->ctrl.sts = CTRL_XACTERR;
  313. status = USB_ERROR;
  314. }
  315. }
  316. return status;
  317. }
  318. /**
  319. * @brief usb host control status data out wait handler
  320. * @param uhost: to the structure of usbh_core_type
  321. * @retval status: usb_sts_type status
  322. */
  323. usb_sts_type usbh_ctrl_status_out_handler(usbh_core_type *uhost)
  324. {
  325. usb_sts_type status = USB_OK;
  326. uhost->hch[uhost->ctrl.hch_out].toggle_out ^= 1;
  327. usbh_ctrl_send_data(uhost, 0, 0, uhost->ctrl.hch_out);
  328. uhost->ctrl.state = CONTROL_STATUS_OUT_WAIT;
  329. return status;
  330. }
  331. /**
  332. * @brief usb host control status data out wait handler
  333. * @param uhost: to the structure of usbh_core_type
  334. * @param timeout: wait timeout
  335. * @retval status: usb_sts_type status
  336. */
  337. usb_sts_type usbh_ctrl_status_out_wait_handler(usbh_core_type *uhost, uint32_t timeout)
  338. {
  339. usb_sts_type status = USB_OK;
  340. urb_sts_type urb_state;
  341. urb_state = uhost->urb_state[uhost->ctrl.hch_out];
  342. if(urb_state == URB_DONE)
  343. {
  344. uhost->ctrl.state = CONTROL_COMPLETE;
  345. }
  346. else if(urb_state == URB_STALL)
  347. {
  348. uhost->ctrl.state = CONTROL_STALL;
  349. }
  350. else if(urb_state == URB_ERROR)
  351. {
  352. uhost->ctrl.state = CONTROL_ERROR;
  353. }
  354. else if(urb_state == URB_NOTREADY)
  355. {
  356. uhost->ctrl.state = CONTROL_STATUS_OUT;
  357. }
  358. /* wait nak timeout 5s*/
  359. if((uhost->timer - uhost->ctrl.timer > CTRL_TIMEOUT) && (urb_state == URB_NOTREADY))
  360. {
  361. uhost->ctrl.state = CONTROL_ERROR;
  362. uhost->ctrl.sts = CTRL_XACTERR;
  363. status = USB_ERROR;
  364. }
  365. return status;
  366. }
  367. /**
  368. * @brief usb host control error handler
  369. * @param uhost: to the structure of usbh_core_type
  370. * @retval status: usb_sts_type status
  371. */
  372. usb_sts_type usbh_ctrl_error_handler(usbh_core_type *uhost)
  373. {
  374. usb_sts_type status = USB_WAIT;
  375. if(++ uhost->ctrl.err_cnt <= USBH_MAX_ERROR_COUNT)
  376. {
  377. uhost->ctrl.state = CONTROL_SETUP;
  378. }
  379. else
  380. {
  381. uhost->ctrl.sts = CTRL_FAIL;
  382. uhost->global_state = USBH_ERROR_STATE;
  383. uhost->ctrl.err_cnt = 0;
  384. status = USB_ERROR;
  385. }
  386. return status;
  387. }
  388. /**
  389. * @brief usb host control stall handler
  390. * @param uhost: to the structure of usbh_core_type
  391. * @retval usb_sts_type
  392. */
  393. usb_sts_type usbh_ctrl_stall_handler(usbh_core_type *uhost)
  394. {
  395. return USB_NOT_SUPPORT;
  396. }
  397. /**
  398. * @brief usb host control complete handler
  399. * @param uhost: to the structure of usbh_core_type
  400. * @retval status: usb_sts_type status
  401. */
  402. usb_sts_type usbh_ctrl_complete_handler(usbh_core_type *uhost)
  403. {
  404. return USB_OK;
  405. }
  406. /**
  407. * @brief usb host control transfer loop function
  408. * @param uhost: to the structure of usbh_core_type
  409. * @retval status: usb_sts_type status
  410. */
  411. usb_sts_type usbh_ctrl_transfer_loop(usbh_core_type *uhost)
  412. {
  413. usb_sts_type status = USB_WAIT;
  414. static uint32_t timeout = 0;
  415. uhost->ctrl.sts = CTRL_START;
  416. switch(uhost->ctrl.state)
  417. {
  418. case CONTROL_SETUP:
  419. usbh_ctrl_setup_handler(uhost);
  420. uhost->ctrl.timer = uhost->timer;
  421. break;
  422. case CONTROL_SETUP_WAIT:
  423. usbh_ctrl_setup_wait_handler(uhost, &timeout);
  424. break;
  425. case CONTROL_DATA_IN:
  426. usbh_ctrl_data_in_handler(uhost);
  427. break;
  428. case CONTROL_DATA_IN_WAIT:
  429. usbh_ctrl_data_in_wait_handler(uhost, timeout);
  430. break;
  431. case CONTROL_DATA_OUT:
  432. usbh_ctrl_data_out_handler(uhost);
  433. break;
  434. case CONTROL_DATA_OUT_WAIT:
  435. usbh_ctrl_data_out_wait_handler(uhost, timeout);
  436. break;
  437. case CONTROL_STATUS_IN:
  438. usbh_ctrl_status_in_handler(uhost);
  439. break;
  440. case CONTROL_STATUS_IN_WAIT:
  441. usbh_ctrl_status_in_wait_handler(uhost, timeout);
  442. break;
  443. case CONTROL_STATUS_OUT:
  444. usbh_ctrl_status_out_handler(uhost);
  445. break;
  446. case CONTROL_STATUS_OUT_WAIT:
  447. usbh_ctrl_status_out_wait_handler(uhost, timeout);
  448. break;
  449. case CONTROL_STALL:
  450. status = usbh_ctrl_stall_handler(uhost);
  451. break;
  452. case CONTROL_ERROR:
  453. status = usbh_ctrl_error_handler(uhost);
  454. break;
  455. case CONTROL_COMPLETE:
  456. status = usbh_ctrl_complete_handler(uhost);
  457. break;
  458. default:
  459. break;
  460. }
  461. return status;
  462. }
  463. /**
  464. * @brief usb host control request
  465. * @param uhost: to the structure of usbh_core_type
  466. * @param buffer: usb request buffer
  467. * @param length: usb request length
  468. * @retval status: usb_sts_type status
  469. */
  470. usb_sts_type usbh_ctrl_request(usbh_core_type *uhost, uint8_t *buffer, uint16_t length)
  471. {
  472. usb_sts_type status = USB_OK;
  473. if(uhost->req_state == CMD_SEND)
  474. {
  475. uhost->req_state = CMD_WAIT;
  476. uhost->ctrl.buffer = buffer;
  477. uhost->ctrl.len = length;
  478. uhost->ctrl.state = CONTROL_SETUP;
  479. }
  480. return status;
  481. }
  482. /**
  483. * @brief usb host get device descriptor
  484. * @param uhost: to the structure of usbh_core_type
  485. * @param length: get descriptor request length
  486. * @param req_type: usb request type
  487. * @param wvalue: usb wvalue
  488. * @param buffer: request buffer
  489. * @retval status: usb_sts_type status
  490. */
  491. usb_sts_type usbh_get_descriptor(usbh_core_type *uhost, uint16_t length,
  492. uint8_t req_type, uint16_t wvalue,
  493. uint8_t *buffer)
  494. {
  495. usb_sts_type status;
  496. uhost->ctrl.setup.bmRequestType = USB_DIR_D2H | req_type;
  497. uhost->ctrl.setup.bRequest = USB_STD_REQ_GET_DESCRIPTOR;
  498. uhost->ctrl.setup.wValue = wvalue;
  499. uhost->ctrl.setup.wLength = length;
  500. if((wvalue & 0xFF00) == ((USB_DESCIPTOR_TYPE_STRING << 8) & 0xFF00))
  501. {
  502. uhost->ctrl.setup.wIndex = 0x0409;
  503. }
  504. else
  505. {
  506. uhost->ctrl.setup.wIndex = 0;
  507. }
  508. status = usbh_ctrl_request(uhost, buffer, length);
  509. return status;
  510. }
  511. /**
  512. * @brief usb host parse device descriptor
  513. * @param uhost: to the structure of usbh_core_type
  514. * @param buffer: usb device descriptor buffer
  515. * @param length: usb device descriptor length
  516. * @retval status: usb_sts_type status
  517. */
  518. void usbh_parse_dev_desc(usbh_core_type *uhost, uint8_t *buffer, uint16_t length)
  519. {
  520. usbh_dev_desc_type *desc = &(uhost->dev);
  521. desc->dev_desc.bLength = *(uint8_t *)(buffer + 0);
  522. desc->dev_desc.bDescriptorType = *(uint8_t *)(buffer + 1);
  523. desc->dev_desc.bcdUSB = SWAPBYTE(buffer + 2);
  524. desc->dev_desc.bDeviceClass = *(uint8_t *)(buffer + 4);
  525. desc->dev_desc.bDeviceSubClass = *(uint8_t *)(buffer + 5);
  526. desc->dev_desc.bDeviceProtocol = *(uint8_t *)(buffer + 6);
  527. desc->dev_desc.bMaxPacketSize0 = *(uint8_t *)(buffer + 7);
  528. if(length > 8)
  529. {
  530. desc->dev_desc.idVendor = SWAPBYTE(buffer + 8);
  531. desc->dev_desc.idProduct = SWAPBYTE(buffer + 10);
  532. desc->dev_desc.bcdDevice = SWAPBYTE(buffer + 12);
  533. desc->dev_desc.iManufacturer = *(uint8_t *)(buffer + 14);
  534. desc->dev_desc.iProduct = *(uint8_t *)(buffer + 15);
  535. desc->dev_desc.iSerialNumber = *(uint8_t *)(buffer + 16);
  536. desc->dev_desc.bNumConfigurations = *(uint8_t *)(buffer + 17);
  537. }
  538. }
  539. /**
  540. * @brief usb host get next header
  541. * @param buffer: usb data buffer
  542. * @param index_len: pointer of index len
  543. * @retval status: usb_sts_type status
  544. */
  545. usb_header_desc_type *usbh_get_next_header(uint8_t *buf, uint16_t *index_len)
  546. {
  547. *index_len += ((usb_header_desc_type *)buf)->bLength;
  548. return (usb_header_desc_type *)
  549. ((uint8_t *)buf + ((usb_header_desc_type *)buf)->bLength);
  550. }
  551. /**
  552. * @brief usb host parse interface descriptor
  553. * @param intf: usb interface description type
  554. * @param buf: interface description data buffer
  555. * @retval none
  556. */
  557. void usbh_parse_interface_desc(usb_interface_desc_type *intf, uint8_t *buf)
  558. {
  559. intf->bLength = *(uint8_t *)buf;
  560. intf->bDescriptorType = *(uint8_t *)(buf + 1);
  561. intf->bInterfaceNumber = *(uint8_t *)(buf + 2);
  562. intf->bAlternateSetting = *(uint8_t *)(buf + 3);
  563. intf->bNumEndpoints = *(uint8_t *)(buf + 4);
  564. intf->bInterfaceClass = *(uint8_t *)(buf + 5);
  565. intf->bInterfaceSubClass = *(uint8_t *)(buf + 6);
  566. intf->bInterfaceProtocol = *(uint8_t *)(buf + 7);
  567. intf->iInterface = *(uint8_t *)(buf + 8);
  568. }
  569. /**
  570. * @brief usb host parse endpoint descriptor
  571. * @param ept_desc: endpoint type
  572. * @param buf: endpoint description data buffer
  573. * @retval none
  574. */
  575. void usbh_parse_endpoint_desc(usb_endpoint_desc_type *ept_desc, uint8_t *buf)
  576. {
  577. ept_desc->bLength = *(uint8_t *)(buf + 0);
  578. ept_desc->bDescriptorType = *(uint8_t *)(buf + 1);
  579. ept_desc->bEndpointAddress = *(uint8_t *)(buf + 2);
  580. ept_desc->bmAttributes = *(uint8_t *)(buf + 3);
  581. ept_desc->wMaxPacketSize = SWAPBYTE(buf + 4);
  582. ept_desc->bInterval = *(uint8_t *)(buf + 6);
  583. }
  584. /**
  585. * @brief usb host parse configure descriptor
  586. * @param uhost: to the structure of usbh_core_type
  587. * @param buffer: configure buffer
  588. * @param length: configure length
  589. * @retval status: usb_sts_type status
  590. */
  591. usb_sts_type usbh_parse_configure_desc(usbh_core_type *uhost,
  592. uint8_t *buffer, uint16_t length)
  593. {
  594. usb_cfg_desc_type *cfg_desc = &(uhost->dev.cfg_desc);
  595. usb_interface_desc_type *intf_desc;
  596. usb_endpoint_desc_type *ept_desc;
  597. usb_header_desc_type *desc;
  598. uint16_t index_len;
  599. uint8_t index_intf = 0;
  600. uint8_t index_ept = 0;
  601. desc = (usb_header_desc_type *)buffer;
  602. cfg_desc->cfg.bLength = *(uint8_t *)buffer;
  603. cfg_desc->cfg.bDescriptorType = *(uint8_t *)(buffer + 1);
  604. cfg_desc->cfg.wTotalLength = SWAPBYTE(buffer + 2);
  605. cfg_desc->cfg.bNumInterfaces = *(uint8_t *)(buffer + 4);
  606. cfg_desc->cfg.bConfigurationValue = *(uint8_t *)(buffer + 5);
  607. cfg_desc->cfg.iConfiguration = *(uint8_t *)(buffer + 6);
  608. cfg_desc->cfg.bmAttributes = *(uint8_t *)(buffer + 7);
  609. cfg_desc->cfg.bMaxPower = *(uint8_t *)(buffer + 8);
  610. if(length > USB_DEVICE_CFG_DESC_LEN)
  611. {
  612. index_len = USB_DEVICE_CFG_DESC_LEN;
  613. while((index_intf < USBH_MAX_INTERFACE) && index_len < cfg_desc->cfg.wTotalLength)
  614. {
  615. desc = usbh_get_next_header((uint8_t *)desc, &index_len);
  616. if(desc->bDescriptorType == USB_DESCIPTOR_TYPE_INTERFACE)
  617. {
  618. index_ept = 0;
  619. intf_desc = &cfg_desc->interface[index_intf].interface;
  620. usbh_parse_interface_desc(intf_desc, (uint8_t *)desc);
  621. while(index_ept < intf_desc->bNumEndpoints && index_len < cfg_desc->cfg.wTotalLength)
  622. {
  623. desc = usbh_get_next_header((uint8_t *)desc, &index_len);
  624. if(desc->bDescriptorType == USB_DESCIPTOR_TYPE_ENDPOINT)
  625. {
  626. ept_desc = &(cfg_desc->interface[index_intf].endpoint[index_ept]);
  627. usbh_parse_endpoint_desc(ept_desc, (uint8_t *)desc);
  628. index_ept ++;
  629. }
  630. }
  631. index_intf ++;
  632. }
  633. }
  634. }
  635. return USB_OK;
  636. }
  637. /**
  638. * @brief usb host find interface
  639. * @param uhost: to the structure of usbh_core_type
  640. * @param class_code: class code
  641. * @param sub_class: subclass code
  642. * @param protocol: prtocol code
  643. * @retval idx: interface index
  644. */
  645. uint8_t usbh_find_interface(usbh_core_type *uhost, uint8_t class_code, uint8_t sub_class, uint8_t protocol)
  646. {
  647. uint8_t idx = 0;
  648. usb_itf_desc_type *usbitf;
  649. for(idx = 0; idx < uhost->dev.cfg_desc.cfg.bNumInterfaces; idx ++)
  650. {
  651. usbitf = &uhost->dev.cfg_desc.interface[idx];
  652. if(((usbitf->interface.bInterfaceClass == class_code) || (class_code == 0xFF)) &&
  653. ((usbitf->interface.bInterfaceSubClass == sub_class) || (sub_class == 0xFF)) &&
  654. ((usbitf->interface.bInterfaceProtocol == protocol) || (protocol == 0xFF))
  655. )
  656. {
  657. return idx;
  658. }
  659. }
  660. return 0xFF;
  661. }
  662. /**
  663. * @brief usbh parse string descriptor
  664. * @param src: string source pointer
  665. * @param dest: string destination pointer
  666. * @param length: string length
  667. * @retval none
  668. */
  669. void usbh_parse_string_desc(uint8_t *src, uint8_t *dest, uint16_t length)
  670. {
  671. uint16_t len;
  672. uint16_t i_index;
  673. if(src[1] == USB_DESCIPTOR_TYPE_STRING)
  674. {
  675. len = ((src[0] - 2) <= length ? (src[0] - 2) : length);
  676. src += 2;
  677. for(i_index = 0; i_index < len; i_index += 2)
  678. {
  679. *dest = src[i_index];
  680. dest ++;
  681. }
  682. *dest = 0;
  683. }
  684. }
  685. /**
  686. * @brief usb host get device descriptor
  687. * @param uhost: to the structure of usbh_core_type
  688. * @param length: get device descriptor length
  689. * @retval status: usb_sts_type status
  690. */
  691. usb_sts_type usbh_get_device_descriptor(usbh_core_type *uhost, uint16_t length)
  692. {
  693. usb_sts_type status = USB_WAIT;
  694. uint8_t bm_req;
  695. uint16_t wvalue;
  696. bm_req = USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
  697. wvalue = (USB_DESCIPTOR_TYPE_DEVICE << 8) & 0xFF00;
  698. status = usbh_get_descriptor(uhost, length, bm_req,
  699. wvalue, uhost->rx_buffer);
  700. return status;
  701. }
  702. /**
  703. * @brief usb host get configure descriptor
  704. * @param uhost: to the structure of usbh_core_type
  705. * @param length: get device configure length
  706. * @retval status: usb_sts_type status
  707. */
  708. usb_sts_type usbh_get_configure_descriptor(usbh_core_type *uhost, uint16_t length)
  709. {
  710. usb_sts_type status = USB_WAIT;
  711. uint8_t bm_req;
  712. uint16_t wvalue;
  713. bm_req = USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
  714. wvalue = (USB_DESCIPTOR_TYPE_CONFIGURATION << 8) & 0xFF00;
  715. status = usbh_get_descriptor(uhost, length, bm_req,
  716. wvalue, uhost->rx_buffer);
  717. return status;
  718. }
  719. /**
  720. * @brief usb host get string descriptor
  721. * @param uhost: to the structure of usbh_core_type
  722. * @param string_id: string id
  723. * @param buffer: receive data buffer
  724. * @param length: get device string length
  725. * @retval status: usb_sts_type status
  726. */
  727. usb_sts_type usbh_get_sting_descriptor(usbh_core_type *uhost, uint8_t string_id,
  728. uint8_t *buffer, uint16_t length)
  729. {
  730. usb_sts_type status = USB_WAIT;
  731. uint8_t bm_req;
  732. uint16_t wvalue;
  733. bm_req = USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
  734. wvalue = (USB_DESCIPTOR_TYPE_STRING << 8) | string_id;
  735. status = usbh_get_descriptor(uhost, length, bm_req,
  736. wvalue, uhost->rx_buffer);
  737. return status;
  738. }
  739. /**
  740. * @brief usb host set configurtion
  741. * @param uhost: to the structure of usbh_core_type
  742. * @param config: usb configuration
  743. * @retval status: usb_sts_type status
  744. */
  745. usb_sts_type usbh_set_configuration(usbh_core_type *uhost, uint16_t config)
  746. {
  747. usb_sts_type status = USB_WAIT;
  748. uint8_t bm_req;
  749. bm_req = USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
  750. uhost->ctrl.setup.bmRequestType = USB_DIR_H2D | bm_req;
  751. uhost->ctrl.setup.bRequest = USB_STD_REQ_SET_CONFIGURATION;
  752. uhost->ctrl.setup.wValue = config;
  753. uhost->ctrl.setup.wLength = 0;
  754. uhost->ctrl.setup.wIndex = 0;
  755. status = usbh_ctrl_request(uhost, 0, 0);
  756. return status;
  757. }
  758. /**
  759. * @brief usb host set device address
  760. * @param uhost: to the structure of usbh_core_type
  761. * @param address: device address
  762. * @retval status: usb_sts_type status
  763. */
  764. usb_sts_type usbh_set_address(usbh_core_type *uhost, uint8_t address)
  765. {
  766. usb_sts_type status = USB_WAIT;
  767. uint8_t bm_req;
  768. bm_req = USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
  769. uhost->ctrl.setup.bmRequestType = USB_DIR_H2D | bm_req;
  770. uhost->ctrl.setup.bRequest = USB_STD_REQ_SET_ADDRESS;
  771. uhost->ctrl.setup.wValue = (uint16_t)address;
  772. uhost->ctrl.setup.wLength = 0;
  773. uhost->ctrl.setup.wIndex = 0;
  774. status = usbh_ctrl_request(uhost, 0, 0);
  775. return status;
  776. }
  777. /**
  778. * @brief usb host set interface
  779. * @param uhost: to the structure of usbh_core_type
  780. * @param ept_num: endpoint number
  781. * @param altsetting: alter setting
  782. * @retval status: usb_sts_type status
  783. */
  784. usb_sts_type usbh_set_interface(usbh_core_type *uhost, uint8_t ept_num, uint8_t altsetting)
  785. {
  786. usb_sts_type status = USB_WAIT;
  787. uint8_t bm_req;
  788. bm_req = USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD;
  789. uhost->ctrl.setup.bmRequestType = USB_DIR_H2D | bm_req;
  790. uhost->ctrl.setup.bRequest = USB_STD_REQ_SET_INTERFACE;
  791. uhost->ctrl.setup.wValue = (uint16_t)altsetting;
  792. uhost->ctrl.setup.wLength = 0;
  793. uhost->ctrl.setup.wIndex = ept_num;
  794. status = usbh_ctrl_request(uhost, 0, 0);
  795. return status;
  796. }
  797. /**
  798. * @brief usb host set feature
  799. * @param uhost: to the structure of usbh_core_type
  800. * @param feature: feature number
  801. * @param index: index number
  802. * @retval status: usb_sts_type status
  803. */
  804. usb_sts_type usbh_set_feature(usbh_core_type *uhost, uint8_t feature, uint16_t index)
  805. {
  806. usb_sts_type status = USB_WAIT;
  807. uint8_t bm_req;
  808. bm_req = USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
  809. uhost->ctrl.setup.bmRequestType = USB_DIR_H2D | bm_req;
  810. uhost->ctrl.setup.bRequest = USB_STD_REQ_SET_FEATURE;
  811. uhost->ctrl.setup.wValue = (uint16_t)feature;
  812. uhost->ctrl.setup.wLength = 0;
  813. uhost->ctrl.setup.wIndex = index;
  814. status = usbh_ctrl_request(uhost, 0, 0);
  815. return status;
  816. }
  817. /**
  818. * @brief usb host clear device feature
  819. * @param uhost: to the structure of usbh_core_type
  820. * @param feature: feature number
  821. * @param index: index number
  822. * @retval status: usb_sts_type status
  823. */
  824. usb_sts_type usbh_clear_dev_feature(usbh_core_type *uhost, uint8_t feature, uint16_t index)
  825. {
  826. usb_sts_type status = USB_WAIT;
  827. uint8_t bm_req;
  828. bm_req = USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
  829. uhost->ctrl.setup.bmRequestType = USB_DIR_H2D | bm_req;
  830. uhost->ctrl.setup.bRequest = USB_STD_REQ_CLEAR_FEATURE;
  831. uhost->ctrl.setup.wValue = (uint16_t)feature;
  832. uhost->ctrl.setup.wLength = 0;
  833. uhost->ctrl.setup.wIndex = index;
  834. status = usbh_ctrl_request(uhost, 0, 0);
  835. return status;
  836. }
  837. /**
  838. * @brief usb host clear endpoint feature
  839. * @param uhost: to the structure of usbh_core_type
  840. * @param ept_num: endpoint number
  841. * @param hc_num: host channel number
  842. * @retval status: usb_sts_type status
  843. */
  844. usb_sts_type usbh_clear_ept_feature(usbh_core_type *uhost, uint8_t ept_num, uint8_t hc_num)
  845. {
  846. usb_sts_type status = USB_WAIT;
  847. uint8_t bm_req;
  848. if(uhost->ctrl.state == CONTROL_IDLE )
  849. {
  850. bm_req = USB_REQ_RECIPIENT_ENDPOINT | USB_REQ_TYPE_STANDARD;
  851. uhost->ctrl.setup.bmRequestType = USB_DIR_H2D | bm_req;
  852. uhost->ctrl.setup.bRequest = USB_STD_REQ_CLEAR_FEATURE;
  853. uhost->ctrl.setup.wValue = USB_FEATURE_EPT_HALT;
  854. uhost->ctrl.setup.wLength = 0;
  855. uhost->ctrl.setup.wIndex = ept_num;
  856. usbh_ctrl_request(uhost, 0, 0);
  857. }
  858. if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_IDLE) == USB_OK)
  859. {
  860. status = USB_OK;
  861. }
  862. return status;
  863. }
  864. /**
  865. * @}
  866. */
  867. /**
  868. * @}
  869. */
  870. #endif