usb_dev_enum.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. #include "include.h"
  2. #include "usb_com.h"
  3. #include "usb_desc.h"
  4. #include "usb_hid.h"
  5. #include "usb_vendor.h"
  6. #include "usb_audio.h"
  7. ude_cb_t ude_cb;
  8. u8 cfg_desc_buf[0x100] AT(.usb_buf.device.desc.buf);
  9. void ude_state_reset(ude_cb_t *ude)
  10. {
  11. ude->devaddr = 0;
  12. ude->cfgval = 0;
  13. }
  14. //Get Status
  15. static bool do_get_status(uint status)
  16. {
  17. u8 buf[2];
  18. buf[0] = status;
  19. buf[1] = 0;
  20. return usb_ep0_start_transfer(buf, 2);
  21. }
  22. //Get Device Status
  23. static bool do_get_device_status(void)
  24. {
  25. if (0 == ude_cb.devaddr) { //判断地址是否设置
  26. return false;
  27. }
  28. return do_get_status(0);
  29. }
  30. //Get Interface Status
  31. static bool do_get_interface_status(void)
  32. {
  33. if (0 == ude_cb.cfgval) { //判断是否已配置
  34. return false;
  35. }
  36. return do_get_status(0);
  37. }
  38. //Get EndPoint Status
  39. static bool do_get_ep_status(spb_wrap_t *spb)
  40. {
  41. epcb_t *ep;
  42. uint req_epnum = BYTE0(spb->index);
  43. uint status = 0;
  44. if (0 == ude_cb.devaddr) { //判断地址是否设置
  45. return false;
  46. }
  47. if (0 == ude_cb.cfgval && 0 != req_epnum) {
  48. return false;
  49. }
  50. //查询Endpoint的Stall状态
  51. uint temp = BYTE0(spb->index);
  52. uint8_t index = temp & 0x7f;
  53. uint8_t dir = temp & BIT(7) ? 1:0;
  54. ep = usb_ep_get_for_index(index, dir);
  55. status = ep->halt;
  56. return do_get_status(status);
  57. }
  58. //Clear Feature
  59. static bool do_clear_feature_for_endpoint(spb_wrap_t *spb)
  60. {
  61. if (0 == ude_cb.devaddr) { //判断地址是否设置
  62. return false;
  63. }
  64. uint req_epnum = BYTE0(spb->index);
  65. if (0 == ude_cb.cfgval && 0 != req_epnum) {
  66. return false;
  67. }
  68. if (FT_EP_STALL != spb->val) {
  69. return false;
  70. }
  71. uint temp = BYTE0(spb->index);
  72. uint8_t index = temp & 0x7f;
  73. uint8_t dir = temp & BIT(7) ? 1:0;
  74. epcb_t *ep = usb_ep_get_for_index(index, dir);
  75. usb_ep_clear(ep);
  76. return true;
  77. }
  78. //Set Feature
  79. static bool do_set_feature_for_endpoint(spb_wrap_t *spb)
  80. {
  81. printf("-->do_set_feature_for_endpoint\n");
  82. uint req_epnum = BYTE0(spb->index);
  83. if (0 == ude_cb.cfgval && 0 != req_epnum) {
  84. return false;
  85. }
  86. if (FT_EP_STALL != spb->val) {
  87. return false;
  88. }
  89. uint temp = BYTE0(spb->index);
  90. uint8_t index = temp & 0x7f;
  91. uint8_t dir = temp & BIT(7) ? 1:0;
  92. epcb_t *ep = usb_ep_get_for_index(index, dir);
  93. usb_ep_halt(ep);
  94. return true;
  95. }
  96. static bool do_set_feature_for_device(spb_wrap_t *spb)
  97. {
  98. printf("-->do_set_feature_for_device\n");
  99. uint req_epnum = BYTE0(spb->index);
  100. if (0 == ude_cb.cfgval && 0 != req_epnum) {
  101. return false;
  102. }
  103. if (FT_DEV_REM_WAKEUP != spb->val) {
  104. return false;
  105. }
  106. usb_device_suspend_enable();
  107. return true;
  108. }
  109. static bool do_clear_feature_for_device(spb_wrap_t *spb)
  110. {
  111. printf("-->do_clear_feature_for_device\n");
  112. if (0 == ude_cb.devaddr) { //判断地址是否设置
  113. return false;
  114. }
  115. uint req_epnum = BYTE0(spb->index);
  116. if (0 == ude_cb.cfgval && 0 != req_epnum) {
  117. return false;
  118. }
  119. if (FT_DEV_REM_WAKEUP != spb->val) {
  120. return false;
  121. }
  122. return true;
  123. }
  124. //Get Descriptor通用
  125. static bool do_transfer_descriptor(spb_wrap_t *spb, const void *buf, uint len)
  126. {
  127. uint inlen = spb->len;
  128. if (inlen > len) {
  129. inlen = len;
  130. }
  131. return usb_ep0_start_transfer((uint8_t*)buf, inlen);
  132. }
  133. //Get String Descriptor
  134. static bool do_get_string_descriptor(spb_wrap_t *spb)
  135. {
  136. uint index = BYTE0(spb->val);
  137. u8 *buf = NULL;
  138. u8 length = 0;
  139. switch (index) {
  140. case STR_LANGUAGE_ID:
  141. buf = usb_get_lang_id_str_descriptor(&length);
  142. return do_transfer_descriptor(spb, buf, length);
  143. case STR_MANUFACTURER:
  144. buf = usb_get_manufacturer_str_descriptor(&length);
  145. return do_transfer_descriptor(spb, buf, length);
  146. case STR_PRODUCT:
  147. buf = usb_get_product_str_descriptor(&length);
  148. return do_transfer_descriptor(spb, buf, length);
  149. case STR_SERIAL_NUM:
  150. buf = usb_get_serial_str_descriptor(&length);
  151. return do_transfer_descriptor(spb, buf, length);
  152. default:
  153. return false;
  154. }
  155. }
  156. //获取配置描述符,并自动裁剪
  157. AT(.usbdev.com)
  158. void get_config_descriptor(void)
  159. {
  160. u16 cfg_desc_len;
  161. u8 *desc_ptr = &cfg_desc_buf[0];
  162. u8 *buf = NULL;
  163. u8 length = 0;
  164. //copy general config descriptor
  165. buf = usb_get_cfg_descriptor(&length);
  166. if (length) {
  167. memcpy(desc_ptr, buf, length);
  168. desc_ptr += length;
  169. } else {
  170. // unexpected case
  171. printf("[Error] you must be rewrite 'usb_get_cfg_descriptor' and return valid cfg desc.\n");
  172. return;
  173. }
  174. #if USB_AUDIO_EN
  175. buf = usb_audio_itf_header_desc_get(&length);
  176. if (length) {
  177. memcpy(desc_ptr, buf, length);
  178. desc_ptr += length;
  179. }
  180. #if USB_SPEAKER_EN
  181. buf = usb_audio_itf_speaker_stream_desc_get(&length);
  182. if (length) {
  183. memcpy(desc_ptr, buf, length);
  184. desc_ptr += length;
  185. }
  186. #endif // USB_SPEAKER_EN
  187. #if USB_MIC_EN
  188. buf = usb_audio_itf_mic_stream_desc_get(&length);
  189. if (length) {
  190. memcpy(desc_ptr, buf, length);
  191. desc_ptr += length;
  192. }
  193. #endif // USB_MIC_EN
  194. #endif
  195. #if USB_HID_EN
  196. buf = usb_hid_itf_desc_get(&length);
  197. if (length) {
  198. memcpy(desc_ptr, buf, length);
  199. desc_ptr += length;
  200. }
  201. #endif // USB_HID_EN
  202. #if USB_VENDOR_EN
  203. buf = usb_vendor_itf_desc_get(&length);
  204. if (length) {
  205. memcpy(desc_ptr, buf, length);
  206. desc_ptr += length;
  207. }
  208. #endif
  209. cfg_desc_len = (u32)desc_ptr - (u32)cfg_desc_buf;
  210. cfg_desc_buf[2] = (u8)cfg_desc_len; //update total size of config descriptor
  211. cfg_desc_buf[3] = (u8)(cfg_desc_len >> 8);
  212. printf("desc: %d\n", cfg_desc_len);
  213. if (cfg_desc_len > sizeof(cfg_desc_buf)) {
  214. printf("--->err: cfg_desc_buf overflow!\n");
  215. while(1);
  216. }
  217. }
  218. //Get Descriptor
  219. AT(.usbdev.com)
  220. static bool do_get_descriptor(spb_wrap_t *spb)
  221. {
  222. uint desc_type = BYTE1(spb->val);
  223. u8 *buf = NULL;
  224. u8 length = 0;
  225. switch (desc_type) {
  226. case DEVICE_DESCRIPTOR:
  227. //1: 设备描述符
  228. buf = usb_get_device_descriptor(&length);
  229. return do_transfer_descriptor(spb, buf, length);
  230. case CONFIGURATION_DESCRIPTOR:
  231. //2: 配置描述符
  232. get_config_descriptor();
  233. return do_transfer_descriptor(spb, cfg_desc_buf, ((u16)cfg_desc_buf[3] << 8) | cfg_desc_buf[2]);
  234. case STRING_DESCRIPTOR:
  235. //3: 字符串描述符
  236. return do_get_string_descriptor(spb);
  237. case INTERFACE_DESCRIPTOR:
  238. //4: 接口描述符
  239. break;
  240. case ENDPOINT_DESCRIPTOR:
  241. //5: 端点描述符
  242. break;
  243. case HID_DESCRIPTOR:
  244. break;
  245. case HID_REPORT_DESCRIPTOR:
  246. printf("usb_hid_report_desc_get:%x\n",spb->index);
  247. #if USB_HID_EN
  248. if (spb->index == USB_HID_ITF_INDEX) {
  249. buf = usb_hid_report_desc_get(&length);
  250. return do_transfer_descriptor(spb, buf, length);
  251. }
  252. #endif
  253. #if USB_VENDOR_EN
  254. if (spb->index == USB_VENDOR_ITF_INDEX) {
  255. buf = usb_vendor_report_desc_get(&length);
  256. return do_transfer_descriptor(spb, buf, length);
  257. }
  258. #endif
  259. default:
  260. break;
  261. }
  262. return false;
  263. }
  264. //Get Configuration
  265. static bool do_get_configuration(void)
  266. {
  267. if (0 == ude_cb.devaddr) { //判断地址是否设置
  268. return false;
  269. }
  270. return usb_ep0_start_transfer(&ude_cb.cfgval, 1);
  271. }
  272. //Set Configuration
  273. static bool do_set_configuration(spb_wrap_t *spb)
  274. {
  275. if (0 == ude_cb.devaddr) { //判断地址是否设置
  276. return false;
  277. }
  278. if (spb->val > 1) {
  279. return false;
  280. }
  281. ude_cb.cfgval = spb->val;
  282. #if USB_HID_EN
  283. ude_hid_setvalid(true);
  284. #endif
  285. #if USB_VENDOR_EN
  286. ude_vendor_setvalid(true);
  287. #endif
  288. return true;
  289. }
  290. //Get Interface
  291. static bool do_get_interface(spb_wrap_t *spb)
  292. {
  293. u8 buf[1] = {0};
  294. if (0 == ude_cb.devaddr) { //判断地址是否设置
  295. return false;
  296. }
  297. #if USB_MIC_EN
  298. if (USB_AUDIO_STREAM_MIC_ITF_INDEX == (u8)spb->index) {
  299. buf[0] = uda_get_isocin_flag();
  300. }
  301. #endif
  302. #if USB_SPEAKER_EN
  303. if (USB_AUDIO_STREAM_SPEAKER_ITF_INDEX == (u8)spb->index) {
  304. buf[0] = uda_get_isocout_flag();
  305. }
  306. #endif
  307. return usb_ep0_start_transfer(buf, 1);
  308. }
  309. //Set Interface
  310. static bool do_set_interface(spb_wrap_t *spb)
  311. {
  312. if (0 == ude_cb.devaddr) { //判断地址是否设置
  313. return false;
  314. }
  315. #if USB_MIC_EN
  316. if (USB_AUDIO_STREAM_MIC_ITF_INDEX == spb->index) {
  317. //每次开启和关闭MIC之前,都会set interface
  318. if (spb->val) {
  319. //start mic
  320. printf("start mic\n");
  321. uda_set_isocin_flag(1);
  322. } else {
  323. //stop mic
  324. printf("stop mic\n");
  325. uda_set_isocin_flag(0);
  326. }
  327. }
  328. #endif
  329. #if USB_SPEAKER_EN
  330. if (USB_AUDIO_STREAM_SPEAKER_ITF_INDEX == spb->index) {
  331. //每次开启和关闭speaker之前,都会set interface
  332. if (spb->val) {
  333. printf("start speaker\n");
  334. uda_set_isocout_flag(1);
  335. } else {
  336. printf("stop speaker\n");
  337. uda_set_isocout_flag(0);
  338. }
  339. }
  340. #endif
  341. return true;
  342. }
  343. static bool usb_set_address(spb_wrap_t *spb)
  344. {
  345. ude_cb.devaddr = BYTE0(spb->val);
  346. return true;
  347. }
  348. //处理标准命令,主机数据方向为in
  349. AT(.usbdev.com)
  350. static bool do_standard_in(spb_wrap_t *spb)
  351. {
  352. switch (spb->recipient) {
  353. case ST_REQ_DEVICE:
  354. switch (spb->req) {
  355. case UR_GET_STATUS:
  356. //00: GetStatus
  357. return do_get_device_status();
  358. case UR_GET_DESCRIPTOR:
  359. //06: GetDescriptor
  360. return do_get_descriptor(spb);
  361. case UR_GET_CONFIGURATION:
  362. //08: GetConfiguration
  363. return do_get_configuration();
  364. default:
  365. break;
  366. }
  367. break;
  368. case ST_REQ_INTERFACE:
  369. switch (spb->req) {
  370. case UR_GET_STATUS:
  371. if (spb->req == UR_GET_STATUS) {
  372. return do_get_interface_status();
  373. }
  374. break;
  375. case UR_GET_INTERFACE:
  376. //0a: GetInterface
  377. return do_get_interface(spb);
  378. case UR_GET_DESCRIPTOR:
  379. //06: GetDescriptor
  380. return do_get_descriptor(spb);
  381. default:
  382. break;
  383. }
  384. break;
  385. case ST_REQ_ENDPOINT:
  386. switch (spb->req) {
  387. case UR_GET_STATUS:
  388. if (spb->req == UR_GET_STATUS) {
  389. return do_get_ep_status(spb);
  390. }
  391. break;
  392. default:
  393. break;
  394. }
  395. break;
  396. default:
  397. break;
  398. }
  399. return false;
  400. }
  401. //处理类命令,主机数据为向为in
  402. AT(.usbdev.com)
  403. static bool do_class_in(spb_wrap_t *spb)
  404. {
  405. switch (spb->recipient) {
  406. case ST_REQ_DEVICE:
  407. break;
  408. case ST_REQ_INTERFACE:
  409. switch (spb->req) {
  410. #if USB_AUDIO_EN
  411. case UA_GET_CUR:
  412. case UA_GET_MIN:
  413. case UA_GET_MAX:
  414. case UA_GET_RES:
  415. if (BYTE1(spb->index) == UA_SPEAKER_UNIT_ID) {
  416. #if USB_SPEAKER_EN
  417. //Speaker Get Feature Unit Control Request
  418. if (BYTE1(spb->val) == UA_MUTE_CTL) {
  419. //Mute Control
  420. printf("do_get_spk_mute\n");
  421. return uda_get_spk_mute();
  422. } else if (BYTE1(spb->val) == UA_VOL_CTL){
  423. //Volume Control
  424. printf("do_get_spk_volume\n");
  425. return uda_get_spk_volume(spb->req);
  426. }
  427. #endif
  428. } else if(BYTE1(spb->index) == UA_MIC_UNIT_ID){
  429. #if USB_MIC_EN
  430. //MIC Get Feature Unit Control Request
  431. if (BYTE1(spb->val) == UA_MUTE_CTL) {
  432. //Mute Control
  433. printf("do_get_mic_mute\n");
  434. return uda_get_mic_mute();
  435. } else if (BYTE1(spb->val) == UA_VOL_CTL) {
  436. //Volume Control
  437. printf("do_get_mic_volume\n");
  438. return uda_get_mic_volume(spb->req);
  439. }
  440. #endif
  441. }
  442. break;
  443. #endif
  444. default:
  445. break;
  446. }
  447. break;
  448. case ST_REQ_ENDPOINT:
  449. break;
  450. default:
  451. break;
  452. }
  453. return false;
  454. }
  455. //处理标准命令,主机数据方向为out
  456. AT(.usbdev.com)
  457. static bool do_standard_out(spb_wrap_t *spb)
  458. {
  459. switch (spb->recipient) {
  460. case ST_REQ_DEVICE:
  461. switch (spb->req) {
  462. case UR_SET_ADDRESS:
  463. //05: SetAddress
  464. return usb_set_address(spb);
  465. case UR_SET_CONFIGURATION:
  466. //09: SetConfiguration
  467. return do_set_configuration(spb);
  468. case UR_CLEAR_FEATURE:
  469. return do_clear_feature_for_device(spb);
  470. case UR_SET_FEATURE:
  471. return do_set_feature_for_device(spb);
  472. default:
  473. break;
  474. }
  475. break;
  476. case ST_REQ_INTERFACE:
  477. switch (spb->req) {
  478. case UR_SET_INTERFACE:
  479. //0b: SetInterface
  480. return do_set_interface(spb);
  481. default:
  482. break;
  483. }
  484. break;
  485. case ST_REQ_ENDPOINT:
  486. switch (spb->req) {
  487. case UR_CLEAR_FEATURE:
  488. return do_clear_feature_for_endpoint(spb);
  489. case UR_SET_FEATURE:
  490. return do_set_feature_for_endpoint(spb);
  491. default:
  492. break;
  493. }
  494. break;
  495. default:
  496. break;
  497. }
  498. return false;
  499. }
  500. static bool do_class_out(spb_wrap_t *spb, uint8_t *data, uint16_t data_len)
  501. {
  502. if ((spb->reqtype == 0x21) && (spb->req == UA_SET_CUR)) {
  503. if (BYTE1(spb->index) == UA_SPEAKER_UNIT_ID) {
  504. if (BYTE1(spb->val) == UA_MUTE_CTL) {
  505. //Speaker SET MUTE
  506. #if USB_SPEAKER_EN
  507. uda_set_spk_mute(data[0]);
  508. #endif // USB_SPEAKER_EN
  509. } else if (BYTE1(spb->val) == UA_VOL_CTL) {
  510. //Speaker SET VOLUME
  511. #if USB_SPEAKER_EN
  512. uda_set_spk_volume(GET_LE16(&data[0]));
  513. #endif // USB_SPEAKER_EN
  514. }
  515. } else if (BYTE1(spb->index) == UA_MIC_UNIT_ID) {
  516. if (BYTE1(spb->val) == UA_MUTE_CTL) {
  517. //MIC SET MUTE
  518. #if USB_MIC_EN
  519. uda_set_mic_mute(data[0]);
  520. #endif // USB_MIC_EN
  521. } else if (BYTE1(spb->val) == UA_VOL_CTL) {
  522. //MIC SET VOLUME
  523. #if USB_MIC_EN
  524. uda_set_mic_volume(GET_LE16(&data[0]));
  525. #endif // USB_MIC_EN
  526. }
  527. }
  528. }
  529. return true;
  530. }
  531. AT(.usbdev.com)
  532. bool usb_ep0_ctl_callback(spb_wrap_t *spb, uint8_t *data, uint16_t data_len)
  533. {
  534. //printf("ep0_rx: \n");
  535. //print_r(spb, sizeof(spb_wrap_t));
  536. if (spb->dir == EP_DIR_IN) {
  537. if (spb->type == ST_TYPE_STANDARD) {
  538. return do_standard_in(spb); //Standard in
  539. } else if (spb->type == ST_TYPE_CLASS) {
  540. return do_class_in(spb); //Class in
  541. } else {
  542. return false;
  543. }
  544. } else {
  545. bool res;
  546. if (spb->type == ST_TYPE_STANDARD) {
  547. res = do_standard_out(spb); //Standard out
  548. } else if (spb->type == ST_TYPE_CLASS) {
  549. res = do_class_out(spb, data, data_len); //Class out
  550. } else {
  551. return false;
  552. }
  553. return res;
  554. }
  555. return false;
  556. }