usbd.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396
  1. /*
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2019 Ha Thach (tinyusb.org)
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. *
  24. * This file is part of the TinyUSB stack.
  25. */
  26. #include "tusb_option.h"
  27. #if CFG_TUD_ENABLED
  28. #include "tusb.h"
  29. #include "common/tusb_private.h"
  30. #include "device/usbd.h"
  31. #include "device/usbd_pvt.h"
  32. #include "device/dcd.h"
  33. //--------------------------------------------------------------------+
  34. // USBD Configuration
  35. //--------------------------------------------------------------------+
  36. // Debug level of USBD
  37. #define USBD_DBG 2
  38. #ifndef CFG_TUD_TASK_QUEUE_SZ
  39. #define CFG_TUD_TASK_QUEUE_SZ 16
  40. #endif
  41. //--------------------------------------------------------------------+
  42. // Device Data
  43. //--------------------------------------------------------------------+
  44. // Invalid driver ID in itf2drv[] ep2drv[][] mapping
  45. enum { DRVID_INVALID = 0xFFu };
  46. typedef struct
  47. {
  48. struct TU_ATTR_PACKED
  49. {
  50. volatile uint8_t connected : 1;
  51. volatile uint8_t addressed : 1;
  52. volatile uint8_t suspended : 1;
  53. uint8_t remote_wakeup_en : 1; // enable/disable by host
  54. uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute
  55. uint8_t self_powered : 1; // configuration descriptor's attribute
  56. };
  57. volatile uint8_t cfg_num; // current active configuration (0x00 is not configured)
  58. uint8_t speed;
  59. uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid)
  60. uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each
  61. tu_edpt_state_t ep_status[CFG_TUD_ENDPPOINT_MAX][2];
  62. }usbd_device_t;
  63. static usbd_device_t _usbd_dev;
  64. //--------------------------------------------------------------------+
  65. // Class Driver
  66. //--------------------------------------------------------------------+
  67. #if CFG_TUSB_DEBUG >= 2
  68. #define DRIVER_NAME(_name) .name = _name,
  69. #else
  70. #define DRIVER_NAME(_name)
  71. #endif
  72. // Built-in class drivers
  73. static usbd_class_driver_t const _usbd_driver[] =
  74. {
  75. #if CFG_TUD_CDC
  76. {
  77. DRIVER_NAME("CDC")
  78. .init = cdcd_init,
  79. .reset = cdcd_reset,
  80. .open = cdcd_open,
  81. .control_xfer_cb = cdcd_control_xfer_cb,
  82. .xfer_cb = cdcd_xfer_cb,
  83. .sof_isr = NULL
  84. },
  85. #endif
  86. #if CFG_TUD_MSC
  87. {
  88. DRIVER_NAME("MSC")
  89. .init = mscd_init,
  90. .reset = mscd_reset,
  91. .open = mscd_open,
  92. .control_xfer_cb = mscd_control_xfer_cb,
  93. .xfer_cb = mscd_xfer_cb,
  94. .sof_isr = NULL
  95. },
  96. #endif
  97. #if CFG_TUD_HID
  98. {
  99. DRIVER_NAME("HID")
  100. .init = hidd_init,
  101. .reset = hidd_reset,
  102. .open = hidd_open,
  103. .control_xfer_cb = hidd_control_xfer_cb,
  104. .xfer_cb = hidd_xfer_cb,
  105. .sof_isr = NULL
  106. },
  107. #endif
  108. #if CFG_TUD_AUDIO
  109. {
  110. DRIVER_NAME("AUDIO")
  111. .init = audiod_init,
  112. .reset = audiod_reset,
  113. .open = audiod_open,
  114. .control_xfer_cb = audiod_control_xfer_cb,
  115. .xfer_cb = audiod_xfer_cb,
  116. .sof_isr = audiod_sof_isr
  117. },
  118. #endif
  119. #if CFG_TUD_VIDEO
  120. {
  121. DRIVER_NAME("VIDEO")
  122. .init = videod_init,
  123. .reset = videod_reset,
  124. .open = videod_open,
  125. .control_xfer_cb = videod_control_xfer_cb,
  126. .xfer_cb = videod_xfer_cb,
  127. .sof_isr = NULL
  128. },
  129. #endif
  130. #if CFG_TUD_MIDI
  131. {
  132. DRIVER_NAME("MIDI")
  133. .init = midid_init,
  134. .open = midid_open,
  135. .reset = midid_reset,
  136. .control_xfer_cb = midid_control_xfer_cb,
  137. .xfer_cb = midid_xfer_cb,
  138. .sof_isr = NULL
  139. },
  140. #endif
  141. #if CFG_TUD_VENDOR
  142. {
  143. DRIVER_NAME("VENDOR")
  144. .init = vendord_init,
  145. .reset = vendord_reset,
  146. .open = vendord_open,
  147. .control_xfer_cb = tud_vendor_control_xfer_cb,
  148. .xfer_cb = vendord_xfer_cb,
  149. .sof_isr = NULL
  150. },
  151. #endif
  152. #if CFG_TUD_USBTMC
  153. {
  154. DRIVER_NAME("TMC")
  155. .init = usbtmcd_init_cb,
  156. .reset = usbtmcd_reset_cb,
  157. .open = usbtmcd_open_cb,
  158. .control_xfer_cb = usbtmcd_control_xfer_cb,
  159. .xfer_cb = usbtmcd_xfer_cb,
  160. .sof_isr = NULL
  161. },
  162. #endif
  163. #if CFG_TUD_DFU_RUNTIME
  164. {
  165. DRIVER_NAME("DFU-RUNTIME")
  166. .init = dfu_rtd_init,
  167. .reset = dfu_rtd_reset,
  168. .open = dfu_rtd_open,
  169. .control_xfer_cb = dfu_rtd_control_xfer_cb,
  170. .xfer_cb = NULL,
  171. .sof_isr = NULL
  172. },
  173. #endif
  174. #if CFG_TUD_DFU
  175. {
  176. DRIVER_NAME("DFU")
  177. .init = dfu_moded_init,
  178. .reset = dfu_moded_reset,
  179. .open = dfu_moded_open,
  180. .control_xfer_cb = dfu_moded_control_xfer_cb,
  181. .xfer_cb = NULL,
  182. .sof_isr = NULL
  183. },
  184. #endif
  185. #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM
  186. {
  187. DRIVER_NAME("NET")
  188. .init = netd_init,
  189. .reset = netd_reset,
  190. .open = netd_open,
  191. .control_xfer_cb = netd_control_xfer_cb,
  192. .xfer_cb = netd_xfer_cb,
  193. .sof_isr = NULL,
  194. },
  195. #endif
  196. #if CFG_TUD_BTH
  197. {
  198. DRIVER_NAME("BTH")
  199. .init = btd_init,
  200. .reset = btd_reset,
  201. .open = btd_open,
  202. .control_xfer_cb = btd_control_xfer_cb,
  203. .xfer_cb = btd_xfer_cb,
  204. .sof_isr = NULL
  205. },
  206. #endif
  207. };
  208. enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) };
  209. // Additional class drivers implemented by application
  210. static usbd_class_driver_t const * _app_driver = NULL;
  211. static uint8_t _app_driver_count = 0;
  212. // virtually joins built-in and application drivers together.
  213. // Application is positioned first to allow overwriting built-in ones.
  214. static inline usbd_class_driver_t const * get_driver(uint8_t drvid)
  215. {
  216. // Application drivers
  217. if ( usbd_app_driver_get_cb )
  218. {
  219. if ( drvid < _app_driver_count ) return &_app_driver[drvid];
  220. drvid -= _app_driver_count;
  221. }
  222. // Built-in drivers
  223. if (drvid < BUILTIN_DRIVER_COUNT) return &_usbd_driver[drvid];
  224. return NULL;
  225. }
  226. #define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT)
  227. //--------------------------------------------------------------------+
  228. // DCD Event
  229. //--------------------------------------------------------------------+
  230. //static tud_sof_isr_t _sof_isr = NULL;
  231. enum { RHPORT_INVALID = 0xFFu };
  232. static uint8_t _usbd_rhport = RHPORT_INVALID;
  233. // Event queue
  234. // usbd_int_set() is used as mutex in OS NONE config
  235. OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t);
  236. static osal_queue_t _usbd_q;
  237. // Mutex for claiming endpoint, only needed when using with preempted RTOS
  238. #if CFG_TUSB_OS != OPT_OS_NONE
  239. static osal_mutex_def_t _ubsd_mutexdef;
  240. static osal_mutex_t _usbd_mutex;
  241. #endif
  242. //--------------------------------------------------------------------+
  243. // Prototypes
  244. //--------------------------------------------------------------------+
  245. static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
  246. static bool process_set_config(uint8_t rhport, uint8_t cfg_num);
  247. static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request);
  248. // from usbd_control.c
  249. void usbd_control_reset(void);
  250. void usbd_control_set_request(tusb_control_request_t const *request);
  251. void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp );
  252. bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
  253. //--------------------------------------------------------------------+
  254. // Debug
  255. //--------------------------------------------------------------------+
  256. #if CFG_TUSB_DEBUG >= 2
  257. static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
  258. {
  259. "Invalid" ,
  260. "Bus Reset" ,
  261. "Unplugged" ,
  262. "Plugged" ,
  263. "SOF" ,
  264. "Suspend" ,
  265. "Resume" ,
  266. "Setup Received" ,
  267. "Xfer Complete" ,
  268. "Func Call"
  269. };
  270. // for usbd_control to print the name of control complete driver
  271. void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback)
  272. {
  273. for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++)
  274. {
  275. usbd_class_driver_t const * driver = get_driver(i);
  276. if ( driver->control_xfer_cb == callback )
  277. {
  278. TU_LOG2(" %s control complete\r\n", driver->name);
  279. return;
  280. }
  281. }
  282. }
  283. #endif
  284. //--------------------------------------------------------------------+
  285. // Application API
  286. //--------------------------------------------------------------------+
  287. tusb_speed_t tud_speed_get(void)
  288. {
  289. return (tusb_speed_t) _usbd_dev.speed;
  290. }
  291. void tud_speed_set(tusb_speed_t speed)
  292. {
  293. _usbd_dev.speed = speed;
  294. }
  295. bool tud_connected(void)
  296. {
  297. return _usbd_dev.connected;
  298. }
  299. bool tud_mounted(void)
  300. {
  301. return _usbd_dev.cfg_num ? true : false;
  302. }
  303. bool tud_suspended(void)
  304. {
  305. return _usbd_dev.suspended;
  306. }
  307. bool tud_remote_wakeup(void)
  308. {
  309. // only wake up host if this feature is supported and enabled and we are suspended
  310. TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en );
  311. dcd_remote_wakeup(_usbd_rhport);
  312. return true;
  313. }
  314. bool tud_disconnect(void)
  315. {
  316. TU_VERIFY(dcd_disconnect);
  317. dcd_disconnect(_usbd_rhport);
  318. return true;
  319. }
  320. bool tud_connect(void)
  321. {
  322. TU_VERIFY(dcd_connect);
  323. dcd_connect(_usbd_rhport);
  324. return true;
  325. }
  326. //void tud_sof_isr_set(tud_sof_isr_t sof_isr)
  327. //{
  328. // _sof_isr = sof_isr;
  329. // dcd_sof_enable(_usbd_rhport, _sof_isr != NULL);
  330. //}
  331. //--------------------------------------------------------------------+
  332. // USBD Task
  333. //--------------------------------------------------------------------+
  334. bool tud_inited(void)
  335. {
  336. return _usbd_rhport != RHPORT_INVALID;
  337. }
  338. bool tud_init (uint8_t rhport)
  339. {
  340. // skip if already initialized
  341. if ( tud_inited() ) return true;
  342. TU_LOG2("USBD init\r\n");
  343. TU_LOG2_INT(sizeof(usbd_device_t));
  344. tu_varclr(&_usbd_dev);
  345. #if CFG_TUSB_OS != OPT_OS_NONE
  346. // Init device mutex
  347. _usbd_mutex = osal_mutex_create(&_ubsd_mutexdef);
  348. TU_ASSERT(_usbd_mutex);
  349. #endif
  350. // Init device queue & task
  351. _usbd_q = osal_queue_create(&_usbd_qdef);
  352. TU_ASSERT(_usbd_q);
  353. // Get application driver if available
  354. if ( usbd_app_driver_get_cb )
  355. {
  356. _app_driver = usbd_app_driver_get_cb(&_app_driver_count);
  357. }
  358. // Init class drivers
  359. for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++)
  360. {
  361. usbd_class_driver_t const * driver = get_driver(i);
  362. TU_LOG2("%s init\r\n", driver->name);
  363. driver->init();
  364. }
  365. _usbd_rhport = rhport;
  366. //_sof_isr = NULL;
  367. // Init device controller driver
  368. dcd_init(rhport);
  369. dcd_int_enable(rhport);
  370. return true;
  371. }
  372. static void configuration_reset(uint8_t rhport)
  373. {
  374. for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ )
  375. {
  376. get_driver(i)->reset(rhport);
  377. }
  378. tu_varclr(&_usbd_dev);
  379. memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping
  380. memset(_usbd_dev.ep2drv , DRVID_INVALID, sizeof(_usbd_dev.ep2drv )); // invalid mapping
  381. }
  382. static void usbd_reset(uint8_t rhport)
  383. {
  384. configuration_reset(rhport);
  385. usbd_control_reset();
  386. }
  387. bool tud_task_event_ready(void)
  388. {
  389. // Skip if stack is not initialized
  390. if ( !tusb_inited() ) return false;
  391. return !osal_queue_empty(_usbd_q);
  392. }
  393. /* USB Device Driver task
  394. * This top level thread manages all device controller event and delegates events to class-specific drivers.
  395. * This should be called periodically within the mainloop or rtos thread.
  396. *
  397. @code
  398. int main(void)
  399. {
  400. application_init();
  401. tusb_init();
  402. while(1) // the mainloop
  403. {
  404. application_code();
  405. tud_task(); // tinyusb device task
  406. }
  407. }
  408. @endcode
  409. */
  410. void tud_task_ext(uint32_t timeout_ms, bool in_isr)
  411. {
  412. (void) in_isr; // not implemented yet
  413. // Skip if stack is not initialized
  414. if ( !tusb_inited() ) return;
  415. // Loop until there is no more events in the queue
  416. while (1)
  417. {
  418. dcd_event_t event;
  419. if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return;
  420. #if CFG_TUSB_DEBUG >= 2
  421. if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG2("\r\n"); // extra line for setup
  422. TU_LOG2("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
  423. #endif
  424. switch ( event.event_id )
  425. {
  426. case DCD_EVENT_BUS_RESET:
  427. TU_LOG2(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
  428. usbd_reset(event.rhport);
  429. _usbd_dev.speed = event.bus_reset.speed;
  430. break;
  431. case DCD_EVENT_UNPLUGGED:
  432. TU_LOG2("\r\n");
  433. usbd_reset(event.rhport);
  434. // invoke callback
  435. if (tud_umount_cb) tud_umount_cb();
  436. break;
  437. case DCD_EVENT_PLUGGED:
  438. TU_LOG2(": %s Speed\r\n", tu_str_speed[event.plugged.speed]);
  439. tud_speed_set(event.plugged.speed);
  440. break;
  441. case DCD_EVENT_SETUP_RECEIVED:
  442. TU_LOG2_VAR(&event.setup_received);
  443. TU_LOG2("\r\n");
  444. // Mark as connected after receiving 1st setup packet.
  445. // But it is easier to set it every time instead of wasting time to check then set
  446. _usbd_dev.connected = 1;
  447. // mark both in & out control as free
  448. _usbd_dev.ep_status[0][TUSB_DIR_OUT].busy = false;
  449. _usbd_dev.ep_status[0][TUSB_DIR_OUT].claimed = 0;
  450. _usbd_dev.ep_status[0][TUSB_DIR_IN ].busy = false;
  451. _usbd_dev.ep_status[0][TUSB_DIR_IN ].claimed = 0;
  452. // Process control request
  453. if ( !process_control_request(event.rhport, &event.setup_received) )
  454. {
  455. TU_LOG2(" Stall EP0\r\n");
  456. // Failed -> stall both control endpoint IN and OUT
  457. dcd_edpt_stall(event.rhport, 0);
  458. dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK);
  459. }
  460. break;
  461. case DCD_EVENT_XFER_COMPLETE:
  462. {
  463. // Invoke the class callback associated with the endpoint address
  464. uint8_t const ep_addr = event.xfer_complete.ep_addr;
  465. uint8_t const epnum = tu_edpt_number(ep_addr);
  466. uint8_t const ep_dir = tu_edpt_dir(ep_addr);
  467. TU_LOG2("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
  468. _usbd_dev.ep_status[epnum][ep_dir].busy = false;
  469. _usbd_dev.ep_status[epnum][ep_dir].claimed = 0;
  470. if ( 0 == epnum )
  471. {
  472. usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t)event.xfer_complete.result, event.xfer_complete.len);
  473. }
  474. else
  475. {
  476. usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] );
  477. TU_ASSERT(driver, );
  478. TU_LOG2(" %s xfer callback\r\n", driver->name);
  479. driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t)event.xfer_complete.result, event.xfer_complete.len);
  480. }
  481. }
  482. break;
  483. case DCD_EVENT_SUSPEND:
  484. // NOTE: When plugging/unplugging device, the D+/D- state are unstable and
  485. // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ), which result in a series of event
  486. // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected
  487. if ( _usbd_dev.connected )
  488. {
  489. TU_LOG2(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en);
  490. if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en);
  491. }else
  492. {
  493. TU_LOG2(" Skipped\r\n");
  494. }
  495. break;
  496. case DCD_EVENT_RESUME:
  497. if ( _usbd_dev.connected )
  498. {
  499. TU_LOG2("\r\n");
  500. if (tud_resume_cb) tud_resume_cb();
  501. }else
  502. {
  503. TU_LOG2(" Skipped\r\n");
  504. }
  505. break;
  506. case USBD_EVENT_FUNC_CALL:
  507. TU_LOG2("\r\n");
  508. if ( event.func_call.func ) event.func_call.func(event.func_call.param);
  509. break;
  510. case DCD_EVENT_SOF:
  511. default:
  512. TU_BREAKPOINT();
  513. break;
  514. }
  515. #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO
  516. // return if there is no more events, for application to run other background
  517. if (osal_queue_empty(_usbd_q)) return;
  518. #endif
  519. }
  520. }
  521. //--------------------------------------------------------------------+
  522. // Control Request Parser & Handling
  523. //--------------------------------------------------------------------+
  524. // Helper to invoke class driver control request handler
  525. static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request)
  526. {
  527. usbd_control_set_complete_callback(driver->control_xfer_cb);
  528. TU_LOG2(" %s control request\r\n", driver->name);
  529. return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request);
  530. }
  531. // This handles the actual request and its response.
  532. // return false will cause its caller to stall control endpoint
  533. static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request)
  534. {
  535. usbd_control_set_complete_callback(NULL);
  536. TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID);
  537. // Vendor request
  538. if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR )
  539. {
  540. TU_VERIFY(tud_vendor_control_xfer_cb);
  541. usbd_control_set_complete_callback(tud_vendor_control_xfer_cb);
  542. return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request);
  543. }
  544. #if CFG_TUSB_DEBUG >= 2
  545. if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME)
  546. {
  547. TU_LOG2(" %s", tu_str_std_request[p_request->bRequest]);
  548. if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG2("\r\n");
  549. }
  550. #endif
  551. switch ( p_request->bmRequestType_bit.recipient )
  552. {
  553. //------------- Device Requests e.g in enumeration -------------//
  554. case TUSB_REQ_RCPT_DEVICE:
  555. if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type )
  556. {
  557. uint8_t const itf = tu_u16_low(p_request->wIndex);
  558. TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv));
  559. usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]);
  560. TU_VERIFY(driver);
  561. // forward to class driver: "non-STD request to Interface"
  562. return invoke_class_control(rhport, driver, p_request);
  563. }
  564. if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type )
  565. {
  566. // Non standard request is not supported
  567. TU_BREAKPOINT();
  568. return false;
  569. }
  570. switch ( p_request->bRequest )
  571. {
  572. case TUSB_REQ_SET_ADDRESS:
  573. // Depending on mcu, status phase could be sent either before or after changing device address,
  574. // or even require stack to not response with status at all
  575. // Therefore DCD must take full responsibility to response and include zlp status packet if needed.
  576. usbd_control_set_request(p_request); // set request since DCD has no access to tud_control_status() API
  577. dcd_set_address(rhport, (uint8_t) p_request->wValue);
  578. // skip tud_control_status()
  579. _usbd_dev.addressed = 1;
  580. break;
  581. case TUSB_REQ_GET_CONFIGURATION:
  582. {
  583. uint8_t cfg_num = _usbd_dev.cfg_num;
  584. tud_control_xfer(rhport, p_request, &cfg_num, 1);
  585. }
  586. break;
  587. case TUSB_REQ_SET_CONFIGURATION:
  588. {
  589. uint8_t const cfg_num = (uint8_t) p_request->wValue;
  590. // Only process if new configure is different
  591. if (_usbd_dev.cfg_num != cfg_num)
  592. {
  593. if ( _usbd_dev.cfg_num )
  594. {
  595. // already configured: need to clear all endpoints and driver first
  596. TU_LOG(USBD_DBG, " Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num);
  597. // close all non-control endpoints, cancel all pending transfers if any
  598. dcd_edpt_close_all(rhport);
  599. // close all drivers and current configured state except bus speed
  600. uint8_t const speed = _usbd_dev.speed;
  601. configuration_reset(rhport);
  602. _usbd_dev.speed = speed; // restore speed
  603. }
  604. // switch to new configuration if not zero
  605. if ( cfg_num ) TU_ASSERT( process_set_config(rhport, cfg_num) );
  606. }
  607. _usbd_dev.cfg_num = cfg_num;
  608. tud_control_status(rhport, p_request);
  609. }
  610. break;
  611. case TUSB_REQ_GET_DESCRIPTOR:
  612. TU_VERIFY( process_get_descriptor(rhport, p_request) );
  613. break;
  614. case TUSB_REQ_SET_FEATURE:
  615. // Only support remote wakeup for device feature
  616. TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
  617. TU_LOG(USBD_DBG, " Enable Remote Wakeup\r\n");
  618. // Host may enable remote wake up before suspending especially HID device
  619. _usbd_dev.remote_wakeup_en = true;
  620. tud_control_status(rhport, p_request);
  621. break;
  622. case TUSB_REQ_CLEAR_FEATURE:
  623. // Only support remote wakeup for device feature
  624. TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
  625. TU_LOG(USBD_DBG, " Disable Remote Wakeup\r\n");
  626. // Host may disable remote wake up after resuming
  627. _usbd_dev.remote_wakeup_en = false;
  628. tud_control_status(rhport, p_request);
  629. break;
  630. case TUSB_REQ_GET_STATUS:
  631. {
  632. // Device status bit mask
  633. // - Bit 0: Self Powered
  634. // - Bit 1: Remote Wakeup enabled
  635. uint16_t status = (_usbd_dev.self_powered ? 1 : 0) | (_usbd_dev.remote_wakeup_en ? 2 : 0);
  636. tud_control_xfer(rhport, p_request, &status, 2);
  637. }
  638. break;
  639. // Unknown/Unsupported request
  640. default: TU_BREAKPOINT(); return false;
  641. }
  642. break;
  643. //------------- Class/Interface Specific Request -------------//
  644. case TUSB_REQ_RCPT_INTERFACE:
  645. {
  646. uint8_t const itf = tu_u16_low(p_request->wIndex);
  647. TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv));
  648. usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]);
  649. TU_VERIFY(driver);
  650. // all requests to Interface (STD or Class) is forwarded to class driver.
  651. // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE
  652. if ( !invoke_class_control(rhport, driver, p_request) )
  653. {
  654. // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class
  655. // driver doesn't use alternate settings or implement this
  656. TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type);
  657. switch(p_request->bRequest)
  658. {
  659. case TUSB_REQ_GET_INTERFACE:
  660. case TUSB_REQ_SET_INTERFACE:
  661. // Clear complete callback if driver set since it can also stall the request.
  662. usbd_control_set_complete_callback(NULL);
  663. if (TUSB_REQ_GET_INTERFACE == p_request->bRequest)
  664. {
  665. uint8_t alternate = 0;
  666. tud_control_xfer(rhport, p_request, &alternate, 1);
  667. }else
  668. {
  669. tud_control_status(rhport, p_request);
  670. }
  671. break;
  672. default: return false;
  673. }
  674. }
  675. }
  676. break;
  677. //------------- Endpoint Request -------------//
  678. case TUSB_REQ_RCPT_ENDPOINT:
  679. {
  680. uint8_t const ep_addr = tu_u16_low(p_request->wIndex);
  681. uint8_t const ep_num = tu_edpt_number(ep_addr);
  682. uint8_t const ep_dir = tu_edpt_dir(ep_addr);
  683. TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) );
  684. usbd_class_driver_t const * driver = get_driver(_usbd_dev.ep2drv[ep_num][ep_dir]);
  685. if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type )
  686. {
  687. // Forward class request to its driver
  688. TU_VERIFY(driver);
  689. return invoke_class_control(rhport, driver, p_request);
  690. }
  691. else
  692. {
  693. // Handle STD request to endpoint
  694. switch ( p_request->bRequest )
  695. {
  696. case TUSB_REQ_GET_STATUS:
  697. {
  698. uint16_t status = usbd_edpt_stalled(rhport, ep_addr) ? 0x0001 : 0x0000;
  699. tud_control_xfer(rhport, p_request, &status, 2);
  700. }
  701. break;
  702. case TUSB_REQ_CLEAR_FEATURE:
  703. case TUSB_REQ_SET_FEATURE:
  704. {
  705. if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue )
  706. {
  707. if ( TUSB_REQ_CLEAR_FEATURE == p_request->bRequest )
  708. {
  709. usbd_edpt_clear_stall(rhport, ep_addr);
  710. }else
  711. {
  712. usbd_edpt_stall(rhport, ep_addr);
  713. }
  714. }
  715. if (driver)
  716. {
  717. // Some classes such as USBTMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request
  718. // We will also forward std request targeted endpoint to class drivers as well
  719. // STD request must always be ACKed regardless of driver returned value
  720. // Also clear complete callback if driver set since it can also stall the request.
  721. (void) invoke_class_control(rhport, driver, p_request);
  722. usbd_control_set_complete_callback(NULL);
  723. // skip ZLP status if driver already did that
  724. if ( !_usbd_dev.ep_status[0][TUSB_DIR_IN].busy ) tud_control_status(rhport, p_request);
  725. }
  726. }
  727. break;
  728. // Unknown/Unsupported request
  729. default: TU_BREAKPOINT(); return false;
  730. }
  731. }
  732. }
  733. break;
  734. // Unknown recipient
  735. default: TU_BREAKPOINT(); return false;
  736. }
  737. return true;
  738. }
  739. // Process Set Configure Request
  740. // This function parse configuration descriptor & open drivers accordingly
  741. static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
  742. {
  743. // index is cfg_num-1
  744. tusb_desc_configuration_t const * desc_cfg = (tusb_desc_configuration_t const *) tud_descriptor_configuration_cb(cfg_num-1);
  745. TU_ASSERT(desc_cfg != NULL && desc_cfg->bDescriptorType == TUSB_DESC_CONFIGURATION);
  746. // Parse configuration descriptor
  747. _usbd_dev.remote_wakeup_support = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP) ? 1 : 0;
  748. _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED ) ? 1 : 0;
  749. // Parse interface descriptor
  750. uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t);
  751. uint8_t const * desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength);
  752. while( p_desc < desc_end )
  753. {
  754. uint8_t assoc_itf_count = 1;
  755. // Class will always starts with Interface Association (if any) and then Interface descriptor
  756. if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) )
  757. {
  758. tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc;
  759. assoc_itf_count = desc_iad->bInterfaceCount;
  760. p_desc = tu_desc_next(p_desc); // next to Interface
  761. // IAD's first interface number and class should match with opened interface
  762. //TU_ASSERT(desc_iad->bFirstInterface == desc_itf->bInterfaceNumber &&
  763. // desc_iad->bFunctionClass == desc_itf->bInterfaceClass);
  764. }
  765. TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) );
  766. tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc;
  767. // Find driver for this interface
  768. uint16_t const remaining_len = desc_end-p_desc;
  769. uint8_t drv_id;
  770. for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++)
  771. {
  772. usbd_class_driver_t const *driver = get_driver(drv_id);
  773. uint16_t const drv_len = driver->open(rhport, desc_itf, remaining_len);
  774. if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) )
  775. {
  776. // Open successfully
  777. TU_LOG2(" %s opened\r\n", driver->name);
  778. // Some drivers use 2 or more interfaces but may not have IAD e.g MIDI (always) or
  779. // BTH (even CDC) with class in device descriptor (single interface)
  780. if ( assoc_itf_count == 1)
  781. {
  782. #if CFG_TUD_CDC
  783. if ( driver->open == cdcd_open ) assoc_itf_count = 2;
  784. #endif
  785. #if CFG_TUD_MIDI
  786. if ( driver->open == midid_open ) assoc_itf_count = 2;
  787. #endif
  788. #if CFG_TUD_BTH && CFG_TUD_BTH_ISO_ALT_COUNT
  789. if ( driver->open == btd_open ) assoc_itf_count = 2;
  790. #endif
  791. }
  792. // bind (associated) interfaces to found driver
  793. for(uint8_t i=0; i<assoc_itf_count; i++)
  794. {
  795. uint8_t const itf_num = desc_itf->bInterfaceNumber+i;
  796. // Interface number must not be used already
  797. TU_ASSERT(DRVID_INVALID == _usbd_dev.itf2drv[itf_num]);
  798. _usbd_dev.itf2drv[itf_num] = drv_id;
  799. }
  800. // bind all endpoints to found driver
  801. tu_edpt_bind_driver(_usbd_dev.ep2drv, desc_itf, drv_len, drv_id);
  802. // next Interface
  803. p_desc += drv_len;
  804. break; // exit driver find loop
  805. }
  806. }
  807. // Failed if there is no supported drivers
  808. TU_ASSERT(drv_id < TOTAL_DRIVER_COUNT);
  809. }
  810. // invoke callback
  811. if (tud_mount_cb) tud_mount_cb();
  812. return true;
  813. }
  814. // return descriptor's buffer and update desc_len
  815. static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request)
  816. {
  817. tusb_desc_type_t const desc_type = (tusb_desc_type_t) tu_u16_high(p_request->wValue);
  818. uint8_t const desc_index = tu_u16_low( p_request->wValue );
  819. switch(desc_type)
  820. {
  821. case TUSB_DESC_DEVICE:
  822. {
  823. TU_LOG2(" Device\r\n");
  824. void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb();
  825. // Only response with exactly 1 Packet if: not addressed and host requested more data than device descriptor has.
  826. // This only happens with the very first get device descriptor and EP0 size = 8 or 16.
  827. if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed &&
  828. ((tusb_control_request_t const*) p_request)->wLength > sizeof(tusb_desc_device_t))
  829. {
  830. // Hack here: we modify the request length to prevent usbd_control response with zlp
  831. // since we are responding with 1 packet & less data than wLength.
  832. tusb_control_request_t mod_request = *p_request;
  833. mod_request.wLength = CFG_TUD_ENDPOINT0_SIZE;
  834. return tud_control_xfer(rhport, &mod_request, desc_device, CFG_TUD_ENDPOINT0_SIZE);
  835. }else
  836. {
  837. return tud_control_xfer(rhport, p_request, desc_device, sizeof(tusb_desc_device_t));
  838. }
  839. }
  840. // break; // unreachable
  841. case TUSB_DESC_BOS:
  842. {
  843. TU_LOG2(" BOS\r\n");
  844. // requested by host if USB > 2.0 ( i.e 2.1 or 3.x )
  845. if (!tud_descriptor_bos_cb) return false;
  846. uintptr_t desc_bos = (uintptr_t) tud_descriptor_bos_cb();
  847. TU_ASSERT(desc_bos);
  848. // Use offsetof to avoid pointer to the odd/misaligned address
  849. uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_bos + offsetof(tusb_desc_bos_t, wTotalLength))) );
  850. return tud_control_xfer(rhport, p_request, (void*) desc_bos, total_len);
  851. }
  852. // break; // unreachable
  853. case TUSB_DESC_CONFIGURATION:
  854. case TUSB_DESC_OTHER_SPEED_CONFIG:
  855. {
  856. uintptr_t desc_config;
  857. if ( desc_type == TUSB_DESC_CONFIGURATION )
  858. {
  859. TU_LOG2(" Configuration[%u]\r\n", desc_index);
  860. desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index);
  861. }else
  862. {
  863. // Host only request this after getting Device Qualifier descriptor
  864. TU_LOG2(" Other Speed Configuration\r\n");
  865. TU_VERIFY( tud_descriptor_other_speed_configuration_cb );
  866. desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index);
  867. }
  868. TU_ASSERT(desc_config);
  869. // Use offsetof to avoid pointer to the odd/misaligned address
  870. uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))) );
  871. return tud_control_xfer(rhport, p_request, (void*) desc_config, total_len);
  872. }
  873. // break; // unreachable
  874. case TUSB_DESC_STRING:
  875. {
  876. TU_LOG2(" String[%u]\r\n", desc_index);
  877. // String Descriptor always uses the desc set from user
  878. uint8_t const* desc_str = (uint8_t const*) tud_descriptor_string_cb(desc_index, tu_le16toh(p_request->wIndex));
  879. TU_VERIFY(desc_str);
  880. // first byte of descriptor is its size
  881. return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_str, tu_desc_len(desc_str));
  882. }
  883. // break; // unreachable
  884. case TUSB_DESC_DEVICE_QUALIFIER:
  885. {
  886. TU_LOG2(" Device Qualifier\r\n");
  887. TU_VERIFY( tud_descriptor_device_qualifier_cb );
  888. uint8_t const* desc_qualifier = tud_descriptor_device_qualifier_cb();
  889. TU_VERIFY(desc_qualifier);
  890. // first byte of descriptor is its size
  891. return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_qualifier, tu_desc_len(desc_qualifier));
  892. }
  893. // break; // unreachable
  894. default: return false;
  895. }
  896. }
  897. //--------------------------------------------------------------------+
  898. // DCD Event Handler
  899. //--------------------------------------------------------------------+
  900. TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr)
  901. {
  902. switch (event->event_id)
  903. {
  904. case DCD_EVENT_UNPLUGGED:
  905. _usbd_dev.connected = 0;
  906. _usbd_dev.addressed = 0;
  907. _usbd_dev.cfg_num = 0;
  908. _usbd_dev.suspended = 0;
  909. osal_queue_send(_usbd_q, event, in_isr);
  910. break;
  911. case DCD_EVENT_SUSPEND:
  912. // NOTE: When plugging/unplugging device, the D+/D- state are unstable and
  913. // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ).
  914. // In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish
  915. // suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected
  916. if ( _usbd_dev.connected )
  917. {
  918. _usbd_dev.suspended = 1;
  919. osal_queue_send(_usbd_q, event, in_isr);
  920. }
  921. break;
  922. case DCD_EVENT_RESUME:
  923. // skip event if not connected (especially required for SAMD)
  924. if ( _usbd_dev.connected )
  925. {
  926. _usbd_dev.suspended = 0;
  927. osal_queue_send(_usbd_q, event, in_isr);
  928. }
  929. break;
  930. case DCD_EVENT_SOF:
  931. // SOF driver handler in ISR context
  932. for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++)
  933. {
  934. usbd_class_driver_t const * driver = get_driver(i);
  935. if (driver->sof_isr)
  936. {
  937. driver->sof_isr(event->rhport, event->sof.frame_count);
  938. }
  939. }
  940. // SOF user handler in ISR context
  941. // if (_sof_isr) _sof_isr(event->sof.frame_count);
  942. // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup
  943. // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational
  944. if ( _usbd_dev.suspended )
  945. {
  946. _usbd_dev.suspended = 0;
  947. dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME };
  948. osal_queue_send(_usbd_q, &event_resume, in_isr);
  949. }
  950. // skip osal queue for SOF in usbd task
  951. break;
  952. default:
  953. osal_queue_send(_usbd_q, event, in_isr);
  954. break;
  955. }
  956. }
  957. //--------------------------------------------------------------------+
  958. // USBD API For Class Driver
  959. //--------------------------------------------------------------------+
  960. void usbd_int_set(bool enabled)
  961. {
  962. if (enabled)
  963. {
  964. dcd_int_enable(_usbd_rhport);
  965. }else
  966. {
  967. dcd_int_disable(_usbd_rhport);
  968. }
  969. }
  970. // Parse consecutive endpoint descriptors (IN & OUT)
  971. bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in)
  972. {
  973. for(int i=0; i<ep_count; i++)
  974. {
  975. tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc;
  976. TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && xfer_type == desc_ep->bmAttributes.xfer);
  977. TU_ASSERT(usbd_edpt_open(rhport, desc_ep));
  978. if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN )
  979. {
  980. (*ep_in) = desc_ep->bEndpointAddress;
  981. }else
  982. {
  983. (*ep_out) = desc_ep->bEndpointAddress;
  984. }
  985. p_desc = tu_desc_next(p_desc);
  986. }
  987. return true;
  988. }
  989. // Helper to defer an isr function
  990. void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr)
  991. {
  992. dcd_event_t event =
  993. {
  994. .rhport = 0,
  995. .event_id = USBD_EVENT_FUNC_CALL,
  996. };
  997. event.func_call.func = func;
  998. event.func_call.param = param;
  999. dcd_event_handler(&event, in_isr);
  1000. }
  1001. //--------------------------------------------------------------------+
  1002. // USBD Endpoint API
  1003. //--------------------------------------------------------------------+
  1004. bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep)
  1005. {
  1006. TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX);
  1007. TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed));
  1008. return dcd_edpt_open(rhport, desc_ep);
  1009. }
  1010. bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr)
  1011. {
  1012. (void) rhport;
  1013. // TODO add this check later, also make sure we don't starve an out endpoint while suspending
  1014. // TU_VERIFY(tud_ready());
  1015. uint8_t const epnum = tu_edpt_number(ep_addr);
  1016. uint8_t const dir = tu_edpt_dir(ep_addr);
  1017. tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir];
  1018. #if TUSB_OPT_MUTEX
  1019. return tu_edpt_claim(ep_state, _usbd_mutex);
  1020. #else
  1021. return tu_edpt_claim(ep_state, NULL);
  1022. #endif
  1023. }
  1024. bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr)
  1025. {
  1026. (void) rhport;
  1027. uint8_t const epnum = tu_edpt_number(ep_addr);
  1028. uint8_t const dir = tu_edpt_dir(ep_addr);
  1029. tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir];
  1030. #if TUSB_OPT_MUTEX
  1031. return tu_edpt_release(ep_state, _usbd_mutex);
  1032. #else
  1033. return tu_edpt_release(ep_state, NULL);
  1034. #endif
  1035. }
  1036. bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
  1037. {
  1038. uint8_t const epnum = tu_edpt_number(ep_addr);
  1039. uint8_t const dir = tu_edpt_dir(ep_addr);
  1040. // TODO skip ready() check for now since enumeration also use this API
  1041. // TU_VERIFY(tud_ready());
  1042. TU_LOG2(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
  1043. // Attempt to transfer on a busy endpoint, sound like an race condition !
  1044. TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
  1045. // Set busy first since the actual transfer can be complete before dcd_edpt_xfer()
  1046. // could return and USBD task can preempt and clear the busy
  1047. _usbd_dev.ep_status[epnum][dir].busy = true;
  1048. if ( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) )
  1049. {
  1050. return true;
  1051. }else
  1052. {
  1053. // DCD error, mark endpoint as ready to allow next transfer
  1054. _usbd_dev.ep_status[epnum][dir].busy = false;
  1055. _usbd_dev.ep_status[epnum][dir].claimed = 0;
  1056. TU_LOG2("FAILED\r\n");
  1057. TU_BREAKPOINT();
  1058. return false;
  1059. }
  1060. }
  1061. // The number of bytes has to be given explicitly to allow more flexible control of how many
  1062. // bytes should be written and second to keep the return value free to give back a boolean
  1063. // success message. If total_bytes is too big, the FIFO will copy only what is available
  1064. // into the USB buffer!
  1065. bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
  1066. {
  1067. uint8_t const epnum = tu_edpt_number(ep_addr);
  1068. uint8_t const dir = tu_edpt_dir(ep_addr);
  1069. TU_LOG2(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
  1070. // Attempt to transfer on a busy endpoint, sound like an race condition !
  1071. TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
  1072. // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return
  1073. // and usbd task can preempt and clear the busy
  1074. _usbd_dev.ep_status[epnum][dir].busy = true;
  1075. if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes))
  1076. {
  1077. TU_LOG2("OK\r\n");
  1078. return true;
  1079. }else
  1080. {
  1081. // DCD error, mark endpoint as ready to allow next transfer
  1082. _usbd_dev.ep_status[epnum][dir].busy = false;
  1083. _usbd_dev.ep_status[epnum][dir].claimed = 0;
  1084. TU_LOG2("failed\r\n");
  1085. TU_BREAKPOINT();
  1086. return false;
  1087. }
  1088. }
  1089. bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
  1090. {
  1091. (void) rhport;
  1092. uint8_t const epnum = tu_edpt_number(ep_addr);
  1093. uint8_t const dir = tu_edpt_dir(ep_addr);
  1094. return _usbd_dev.ep_status[epnum][dir].busy;
  1095. }
  1096. void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
  1097. {
  1098. uint8_t const epnum = tu_edpt_number(ep_addr);
  1099. uint8_t const dir = tu_edpt_dir(ep_addr);
  1100. // only stalled if currently cleared
  1101. if ( !_usbd_dev.ep_status[epnum][dir].stalled )
  1102. {
  1103. TU_LOG(USBD_DBG, " Stall EP %02X\r\n", ep_addr);
  1104. dcd_edpt_stall(rhport, ep_addr);
  1105. _usbd_dev.ep_status[epnum][dir].stalled = true;
  1106. _usbd_dev.ep_status[epnum][dir].busy = true;
  1107. }
  1108. }
  1109. void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
  1110. {
  1111. uint8_t const epnum = tu_edpt_number(ep_addr);
  1112. uint8_t const dir = tu_edpt_dir(ep_addr);
  1113. // only clear if currently stalled
  1114. if ( _usbd_dev.ep_status[epnum][dir].stalled )
  1115. {
  1116. TU_LOG(USBD_DBG, " Clear Stall EP %02X\r\n", ep_addr);
  1117. dcd_edpt_clear_stall(rhport, ep_addr);
  1118. _usbd_dev.ep_status[epnum][dir].stalled = false;
  1119. _usbd_dev.ep_status[epnum][dir].busy = false;
  1120. }
  1121. }
  1122. bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr)
  1123. {
  1124. (void) rhport;
  1125. uint8_t const epnum = tu_edpt_number(ep_addr);
  1126. uint8_t const dir = tu_edpt_dir(ep_addr);
  1127. return _usbd_dev.ep_status[epnum][dir].stalled;
  1128. }
  1129. /**
  1130. * usbd_edpt_close will disable an endpoint.
  1131. *
  1132. * In progress transfers on this EP may be delivered after this call.
  1133. *
  1134. */
  1135. void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr)
  1136. {
  1137. TU_ASSERT(dcd_edpt_close, /**/);
  1138. TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr);
  1139. uint8_t const epnum = tu_edpt_number(ep_addr);
  1140. uint8_t const dir = tu_edpt_dir(ep_addr);
  1141. dcd_edpt_close(rhport, ep_addr);
  1142. _usbd_dev.ep_status[epnum][dir].stalled = false;
  1143. _usbd_dev.ep_status[epnum][dir].busy = false;
  1144. _usbd_dev.ep_status[epnum][dir].claimed = false;
  1145. return;
  1146. }
  1147. void usbd_sof_enable(uint8_t rhport, bool en)
  1148. {
  1149. // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more.
  1150. // Only if all drivers switched off SOF calls the SOF interrupt may be disabled
  1151. dcd_sof_enable(rhport, en);
  1152. }
  1153. #endif