Teensy 4.1 core updated for C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6 jaren geleden
4 jaren geleden
5 jaren geleden
6 jaren geleden
5 jaren geleden
4 jaren geleden
4 jaren geleden
4 jaren geleden
5 jaren geleden
5 jaren geleden
4 jaren geleden
4 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  1. #include "usb_dev.h"
  2. #define USB_DESC_LIST_DEFINE
  3. #include "usb_desc.h"
  4. #include "usb_serial.h"
  5. #include "usb_seremu.h"
  6. #include "usb_rawhid.h"
  7. #include "usb_keyboard.h"
  8. #include "usb_mouse.h"
  9. #include "usb_joystick.h"
  10. #include "usb_flightsim.h"
  11. #include "usb_touch.h"
  12. #include "usb_midi.h"
  13. #include "usb_audio.h"
  14. #include "usb_mtp.h"
  15. #include "core_pins.h" // for delay()
  16. #include "avr/pgmspace.h"
  17. #include <string.h>
  18. #include "debug/printf.h"
  19. //#define LOG_SIZE 20
  20. //uint32_t transfer_log_head=0;
  21. //uint32_t transfer_log_count=0;
  22. //uint32_t transfer_log[LOG_SIZE];
  23. // device mode, page 3155
  24. #if defined(NUM_ENDPOINTS)
  25. typedef struct endpoint_struct endpoint_t;
  26. struct endpoint_struct {
  27. uint32_t config;
  28. uint32_t current;
  29. uint32_t next;
  30. uint32_t status;
  31. uint32_t pointer0;
  32. uint32_t pointer1;
  33. uint32_t pointer2;
  34. uint32_t pointer3;
  35. uint32_t pointer4;
  36. uint32_t reserved;
  37. uint32_t setup0;
  38. uint32_t setup1;
  39. transfer_t *first_transfer;
  40. transfer_t *last_transfer;
  41. void (*callback_function)(transfer_t *completed_transfer);
  42. uint32_t unused1;
  43. };
  44. /*struct transfer_struct {
  45. uint32_t next;
  46. uint32_t status;
  47. uint32_t pointer0;
  48. uint32_t pointer1;
  49. uint32_t pointer2;
  50. uint32_t pointer3;
  51. uint32_t pointer4;
  52. uint32_t callback_param;
  53. };*/
  54. #ifdef EXPERIMENTAL_INTERFACE
  55. uint8_t experimental_buffer[1152] __attribute__ ((section(".dmabuffers"), aligned(64)));
  56. #endif
  57. endpoint_t endpoint_queue_head[(NUM_ENDPOINTS+1)*2] __attribute__ ((used, aligned(4096)));
  58. transfer_t endpoint0_transfer_data __attribute__ ((used, aligned(32)));
  59. transfer_t endpoint0_transfer_ack __attribute__ ((used, aligned(32)));
  60. typedef union {
  61. struct {
  62. union {
  63. struct {
  64. uint8_t bmRequestType;
  65. uint8_t bRequest;
  66. };
  67. uint16_t wRequestAndType;
  68. };
  69. uint16_t wValue;
  70. uint16_t wIndex;
  71. uint16_t wLength;
  72. };
  73. struct {
  74. uint32_t word1;
  75. uint32_t word2;
  76. };
  77. uint64_t bothwords;
  78. } setup_t;
  79. static setup_t endpoint0_setupdata;
  80. static uint32_t endpoint0_notify_mask=0;
  81. static uint32_t endpointN_notify_mask=0;
  82. //static int reset_count=0;
  83. volatile uint8_t usb_configuration = 0; // non-zero when USB host as configured device
  84. volatile uint8_t usb_high_speed = 0; // non-zero if running at 480 Mbit/sec speed
  85. static uint8_t endpoint0_buffer[8];
  86. static uint8_t sof_usage = 0;
  87. static uint8_t usb_reboot_timer = 0;
  88. extern uint8_t usb_descriptor_buffer[]; // defined in usb_desc.c
  89. extern const uint8_t usb_config_descriptor_480[];
  90. extern const uint8_t usb_config_descriptor_12[];
  91. void (*usb_timer0_callback)(void) = NULL;
  92. void (*usb_timer1_callback)(void) = NULL;
  93. static void isr(void);
  94. static void endpoint0_setup(uint64_t setupdata);
  95. static void endpoint0_transmit(const void *data, uint32_t len, int notify);
  96. static void endpoint0_receive(void *data, uint32_t len, int notify);
  97. static void endpoint0_complete(void);
  98. static void run_callbacks(endpoint_t *ep);
  99. FLASHMEM void usb_init(void)
  100. {
  101. // TODO: only enable when VBUS detected
  102. // TODO: return to low power mode when VBUS removed
  103. // TODO: protect PMU access with MPU
  104. PMU_REG_3P0 = PMU_REG_3P0_OUTPUT_TRG(0x0F) | PMU_REG_3P0_BO_OFFSET(6)
  105. | PMU_REG_3P0_ENABLE_LINREG;
  106. usb_init_serialnumber();
  107. // assume PLL3 is already running - already done by usb_pll_start() in main.c
  108. CCM_CCGR6 |= CCM_CCGR6_USBOH3(CCM_CCGR_ON); // turn on clocks to USB peripheral
  109. printf("BURSTSIZE=%08lX\n", USB1_BURSTSIZE);
  110. //USB1_BURSTSIZE = USB_BURSTSIZE_TXPBURST(4) | USB_BURSTSIZE_RXPBURST(4);
  111. USB1_BURSTSIZE = 0x0404;
  112. printf("BURSTSIZE=%08lX\n", USB1_BURSTSIZE);
  113. printf("USB1_TXFILLTUNING=%08lX\n", USB1_TXFILLTUNING);
  114. // Before programming this register, the PHY clocks must be enabled in registers
  115. // USBPHYx_CTRLn and CCM_ANALOG_USBPHYx_PLL_480_CTRLn.
  116. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  117. //printf("USBPHY1_TX=%08lX\n", USBPHY1_TX);
  118. //printf("USBPHY1_RX=%08lX\n", USBPHY1_RX);
  119. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  120. //printf("USB1_USBMODE=%08lX\n", USB1_USBMODE);
  121. // turn on PLL3, wait for 480 MHz lock?
  122. // turn on CCM clock gates? CCGR6[CG0]
  123. #if 1
  124. if ((USBPHY1_PWD & (USBPHY_PWD_RXPWDRX | USBPHY_PWD_RXPWDDIFF | USBPHY_PWD_RXPWD1PT1
  125. | USBPHY_PWD_RXPWDENV | USBPHY_PWD_TXPWDV2I | USBPHY_PWD_TXPWDIBIAS
  126. | USBPHY_PWD_TXPWDFS)) || (USB1_USBMODE & USB_USBMODE_CM_MASK)) {
  127. // USB controller is turned on from previous use
  128. // reset needed to turn it off & start from clean slate
  129. USBPHY1_CTRL_SET = USBPHY_CTRL_SFTRST; // USBPHY1_CTRL page 3292
  130. USB1_USBCMD |= USB_USBCMD_RST; // reset controller
  131. int count=0;
  132. while (USB1_USBCMD & USB_USBCMD_RST) count++;
  133. NVIC_CLEAR_PENDING(IRQ_USB1);
  134. USBPHY1_CTRL_CLR = USBPHY_CTRL_SFTRST; // reset PHY
  135. //USB1_USBSTS = USB1_USBSTS; // TODO: is this needed?
  136. printf("USB reset took %d loops\n", count);
  137. //delay(10);
  138. //printf("\n");
  139. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  140. //printf("USBPHY1_TX=%08lX\n", USBPHY1_TX);
  141. //printf("USBPHY1_RX=%08lX\n", USBPHY1_RX);
  142. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  143. //printf("USB1_USBMODE=%08lX\n", USB1_USBMODE);
  144. delay(25);
  145. }
  146. #endif
  147. // Device Controller Initialization, page 2351 (Rev 2, 12/2019)
  148. // USBCMD pg 3216
  149. // USBSTS pg 3220
  150. // USBINTR pg 3224
  151. // DEVICEADDR pg 3227
  152. // ENDPTLISTADDR 3229
  153. // USBMODE pg 3244
  154. // ENDPTSETUPSTAT 3245
  155. // ENDPTPRIME pg 3246
  156. // ENDPTFLUSH pg 3247
  157. // ENDPTSTAT pg 3247
  158. // ENDPTCOMPLETE 3248
  159. // ENDPTCTRL0 pg 3249
  160. USBPHY1_CTRL_CLR = USBPHY_CTRL_CLKGATE;
  161. USBPHY1_PWD = 0;
  162. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  163. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  164. USB1_USBMODE = USB_USBMODE_CM(2) | USB_USBMODE_SLOM;
  165. memset(endpoint_queue_head, 0, sizeof(endpoint_queue_head));
  166. endpoint_queue_head[0].config = (64 << 16) | (1 << 15);
  167. endpoint_queue_head[1].config = (64 << 16);
  168. USB1_ENDPOINTLISTADDR = (uint32_t)&endpoint_queue_head;
  169. // Recommended: enable all device interrupts including: USBINT, USBERRINT,
  170. // Port Change Detect, USB Reset Received, DCSuspend.
  171. USB1_USBINTR = USB_USBINTR_UE | USB_USBINTR_UEE | /* USB_USBINTR_PCE | */
  172. USB_USBINTR_URE | USB_USBINTR_SLE;
  173. //_VectorsRam[IRQ_USB1+16] = &isr;
  174. attachInterruptVector(IRQ_USB1, &isr);
  175. NVIC_ENABLE_IRQ(IRQ_USB1);
  176. //printf("USB1_ENDPTCTRL0=%08lX\n", USB1_ENDPTCTRL0);
  177. //printf("USB1_ENDPTCTRL1=%08lX\n", USB1_ENDPTCTRL1);
  178. //printf("USB1_ENDPTCTRL2=%08lX\n", USB1_ENDPTCTRL2);
  179. //printf("USB1_ENDPTCTRL3=%08lX\n", USB1_ENDPTCTRL3);
  180. USB1_USBCMD = USB_USBCMD_RS;
  181. //transfer_log_head = 0;
  182. //transfer_log_count = 0;
  183. //USB1_PORTSC1 |= USB_PORTSC1_PFSC; // force 12 Mbit/sec
  184. }
  185. static void isr(void)
  186. {
  187. //printf("*");
  188. // Port control in device mode is only used for
  189. // status port reset, suspend, and current connect status.
  190. uint32_t status = USB1_USBSTS;
  191. USB1_USBSTS = status;
  192. // USB_USBSTS_SLI - set to 1 when enters a suspend state from an active state
  193. // USB_USBSTS_SRI - set at start of frame
  194. // USB_USBSTS_SRI - set when USB reset detected
  195. if (status & USB_USBSTS_UI) {
  196. //printf("data\n");
  197. uint32_t setupstatus = USB1_ENDPTSETUPSTAT;
  198. //printf("USB1_ENDPTSETUPSTAT=%X\n", setupstatus);
  199. while (setupstatus) {
  200. USB1_ENDPTSETUPSTAT = setupstatus;
  201. setup_t s;
  202. do {
  203. USB1_USBCMD |= USB_USBCMD_SUTW;
  204. s.word1 = endpoint_queue_head[0].setup0;
  205. s.word2 = endpoint_queue_head[0].setup1;
  206. } while (!(USB1_USBCMD & USB_USBCMD_SUTW));
  207. USB1_USBCMD &= ~USB_USBCMD_SUTW;
  208. //printf("setup %08lX %08lX\n", s.word1, s.word2);
  209. USB1_ENDPTFLUSH = (1<<16) | (1<<0); // page 3174
  210. while (USB1_ENDPTFLUSH & ((1<<16) | (1<<0))) ;
  211. endpoint0_notify_mask = 0;
  212. endpoint0_setup(s.bothwords);
  213. setupstatus = USB1_ENDPTSETUPSTAT; // page 3175
  214. }
  215. uint32_t completestatus = USB1_ENDPTCOMPLETE;
  216. if (completestatus) {
  217. USB1_ENDPTCOMPLETE = completestatus;
  218. //printf("USB1_ENDPTCOMPLETE=%lX\n", completestatus);
  219. if (completestatus & endpoint0_notify_mask) {
  220. endpoint0_notify_mask = 0;
  221. endpoint0_complete();
  222. }
  223. completestatus &= endpointN_notify_mask;
  224. #if 1
  225. if (completestatus) {
  226. // transmit:
  227. uint32_t tx = completestatus >> 16;
  228. while (tx) {
  229. int p=__builtin_ctz(tx);
  230. run_callbacks(endpoint_queue_head + p * 2 + 1);
  231. tx &= ~(1<<p);
  232. }
  233. // receive:
  234. uint32_t rx = completestatus & 0xffff;
  235. while(rx) {
  236. int p=__builtin_ctz(rx);
  237. run_callbacks(endpoint_queue_head + p * 2);
  238. rx &= ~(1<<p);
  239. };
  240. }
  241. #else
  242. if (completestatus) {
  243. int i; // TODO: optimize with __builtin_ctz()
  244. for (i=2; i <= NUM_ENDPOINTS; i++) {
  245. if (completestatus & (1 << i)) { // receive
  246. run_callbacks(endpoint_queue_head + i * 2);
  247. }
  248. if (completestatus & (1 << (i + 16))) { // transmit
  249. run_callbacks(endpoint_queue_head + i * 2 + 1);
  250. }
  251. }
  252. }
  253. #endif
  254. }
  255. }
  256. if (status & USB_USBSTS_URI) { // page 3164
  257. USB1_ENDPTSETUPSTAT = USB1_ENDPTSETUPSTAT; // Clear all setup token semaphores
  258. USB1_ENDPTCOMPLETE = USB1_ENDPTCOMPLETE; // Clear all the endpoint complete status
  259. while (USB1_ENDPTPRIME != 0) ; // Wait for any endpoint priming
  260. USB1_ENDPTFLUSH = 0xFFFFFFFF; // Cancel all endpoint primed status
  261. if ((USB1_PORTSC1 & USB_PORTSC1_PR)) {
  262. //printf("reset\n");
  263. } else {
  264. // we took too long to respond :(
  265. // TODO; is this ever really a problem?
  266. //printf("reset too slow\n");
  267. }
  268. #if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE)
  269. usb_serial_reset();
  270. #endif
  271. endpointN_notify_mask = 0;
  272. // TODO: Free all allocated dTDs
  273. //if (++reset_count >= 3) {
  274. // shut off USB - easier to see results in protocol analyzer
  275. //USB1_USBCMD &= ~USB_USBCMD_RS;
  276. //printf("shut off USB\n");
  277. //}
  278. }
  279. if (status & USB_USBSTS_TI0) {
  280. if (usb_timer0_callback != NULL) usb_timer0_callback();
  281. }
  282. if (status & USB_USBSTS_TI1) {
  283. if (usb_timer1_callback != NULL) usb_timer1_callback();
  284. }
  285. if (status & USB_USBSTS_PCI) {
  286. if (USB1_PORTSC1 & USB_PORTSC1_HSP) {
  287. //printf("port at 480 Mbit\n");
  288. usb_high_speed = 1;
  289. } else {
  290. //printf("port at 12 Mbit\n");
  291. usb_high_speed = 0;
  292. }
  293. }
  294. if (status & USB_USBSTS_SLI) { // page 3165
  295. //printf("suspend\n");
  296. }
  297. if (status & USB_USBSTS_UEI) {
  298. //printf("error\n");
  299. }
  300. if ((USB1_USBINTR & USB_USBINTR_SRE) && (status & USB_USBSTS_SRI)) {
  301. //printf("sof %d\n", usb_reboot_timer);
  302. if (usb_reboot_timer) {
  303. if (--usb_reboot_timer == 0) {
  304. usb_stop_sof_interrupts(NUM_INTERFACE);
  305. asm("bkpt #251"); // run bootloader
  306. }
  307. }
  308. #ifdef MIDI_INTERFACE
  309. usb_midi_flush_output();
  310. #endif
  311. #ifdef MULTITOUCH_INTERFACE
  312. usb_touchscreen_update_callback();
  313. #endif
  314. #ifdef FLIGHTSIM_INTERFACE
  315. usb_flightsim_flush_output();
  316. #endif
  317. }
  318. }
  319. void usb_start_sof_interrupts(int interface)
  320. {
  321. __disable_irq();
  322. sof_usage |= (1 << interface);
  323. uint32_t intr = USB1_USBINTR;
  324. if (!(intr & USB_USBINTR_SRE)) {
  325. USB1_USBSTS = USB_USBSTS_SRI; // clear prior SOF before SOF IRQ enable
  326. USB1_USBINTR = intr | USB_USBINTR_SRE;
  327. }
  328. __enable_irq();
  329. }
  330. void usb_stop_sof_interrupts(int interface)
  331. {
  332. sof_usage &= ~(1 << interface);
  333. if (sof_usage == 0) {
  334. USB1_USBINTR &= ~USB_USBINTR_SRE;
  335. }
  336. }
  337. /*
  338. struct transfer_struct { // table 55-60, pg 3159
  339. uint32_t next;
  340. uint32_t status;
  341. uint32_t pointer0;
  342. uint32_t pointer1;
  343. uint32_t pointer2;
  344. uint32_t pointer3;
  345. uint32_t pointer4;
  346. uint32_t unused1;
  347. };
  348. transfer_t endpoint0_transfer_data __attribute__ ((aligned(32)));;
  349. transfer_t endpoint0_transfer_ack __attribute__ ((aligned(32)));;
  350. */
  351. static uint8_t reply_buffer[8];
  352. static void endpoint0_setup(uint64_t setupdata)
  353. {
  354. setup_t setup;
  355. uint32_t endpoint, dir, ctrl;
  356. const usb_descriptor_list_t *list;
  357. setup.bothwords = setupdata;
  358. switch (setup.wRequestAndType) {
  359. case 0x0500: // SET_ADDRESS
  360. endpoint0_receive(NULL, 0, 0);
  361. USB1_DEVICEADDR = USB_DEVICEADDR_USBADR(setup.wValue) | USB_DEVICEADDR_USBADRA;
  362. return;
  363. case 0x0900: // SET_CONFIGURATION
  364. usb_configuration = setup.wValue;
  365. // configure all other endpoints
  366. #if defined(ENDPOINT2_CONFIG)
  367. USB1_ENDPTCTRL2 = ENDPOINT2_CONFIG;
  368. #endif
  369. #if defined(ENDPOINT3_CONFIG)
  370. USB1_ENDPTCTRL3 = ENDPOINT3_CONFIG;
  371. #endif
  372. #if defined(ENDPOINT4_CONFIG)
  373. USB1_ENDPTCTRL4 = ENDPOINT4_CONFIG;
  374. #endif
  375. #if defined(ENDPOINT5_CONFIG)
  376. USB1_ENDPTCTRL5 = ENDPOINT5_CONFIG;
  377. #endif
  378. #if defined(ENDPOINT6_CONFIG)
  379. USB1_ENDPTCTRL6 = ENDPOINT6_CONFIG;
  380. #endif
  381. #if defined(ENDPOINT7_CONFIG)
  382. USB1_ENDPTCTRL7 = ENDPOINT7_CONFIG;
  383. #endif
  384. #if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE)
  385. usb_serial_configure();
  386. #elif defined(SEREMU_INTERFACE)
  387. usb_seremu_configure();
  388. #endif
  389. #if defined(CDC2_STATUS_INTERFACE) && defined(CDC2_DATA_INTERFACE)
  390. usb_serial2_configure();
  391. #endif
  392. #if defined(CDC3_STATUS_INTERFACE) && defined(CDC3_DATA_INTERFACE)
  393. usb_serial3_configure();
  394. #endif
  395. #if defined(RAWHID_INTERFACE)
  396. usb_rawhid_configure();
  397. #endif
  398. #if defined(KEYBOARD_INTERFACE)
  399. usb_keyboard_configure();
  400. #endif
  401. #if defined(MOUSE_INTERFACE)
  402. usb_mouse_configure();
  403. #endif
  404. #if defined(FLIGHTSIM_INTERFACE)
  405. usb_flightsim_configure();
  406. #endif
  407. #if defined(JOYSTICK_INTERFACE)
  408. usb_joystick_configure();
  409. #endif
  410. #if defined(MULTITOUCH_INTERFACE)
  411. usb_touchscreen_configure();
  412. #endif
  413. #if defined(MIDI_INTERFACE)
  414. usb_midi_configure();
  415. #endif
  416. #if defined(AUDIO_INTERFACE)
  417. usb_audio_configure();
  418. #endif
  419. #if defined(MTP_INTERFACE)
  420. usb_mtp_configure();
  421. #endif
  422. #if defined(EXPERIMENTAL_INTERFACE)
  423. endpoint_queue_head[2].unused1 = (uint32_t)experimental_buffer;
  424. #endif
  425. endpoint0_receive(NULL, 0, 0);
  426. return;
  427. case 0x0880: // GET_CONFIGURATION
  428. reply_buffer[0] = usb_configuration;
  429. endpoint0_transmit(reply_buffer, 1, 0);
  430. return;
  431. case 0x0080: // GET_STATUS (device)
  432. reply_buffer[0] = 0;
  433. reply_buffer[1] = 0;
  434. endpoint0_transmit(reply_buffer, 2, 0);
  435. return;
  436. case 0x0082: // GET_STATUS (endpoint)
  437. endpoint = setup.wIndex & 0x7F;
  438. if (endpoint > 7) break;
  439. dir = setup.wIndex & 0x80;
  440. ctrl = *((uint32_t *)&USB1_ENDPTCTRL0 + endpoint);
  441. reply_buffer[0] = 0;
  442. reply_buffer[1] = 0;
  443. if ((dir && (ctrl & USB_ENDPTCTRL_TXS)) || (!dir && (ctrl & USB_ENDPTCTRL_RXS))) {
  444. reply_buffer[0] = 1;
  445. }
  446. endpoint0_transmit(reply_buffer, 2, 0);
  447. return;
  448. case 0x0302: // SET_FEATURE (endpoint)
  449. endpoint = setup.wIndex & 0x7F;
  450. if (endpoint > 7) break;
  451. dir = setup.wIndex & 0x80;
  452. if (dir) {
  453. *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) |= USB_ENDPTCTRL_TXS;
  454. } else {
  455. *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) |= USB_ENDPTCTRL_RXS;
  456. }
  457. endpoint0_receive(NULL, 0, 0);
  458. return;
  459. case 0x0102: // CLEAR_FEATURE (endpoint)
  460. endpoint = setup.wIndex & 0x7F;
  461. if (endpoint > 7) break;
  462. dir = setup.wIndex & 0x80;
  463. if (dir) {
  464. *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) &= ~USB_ENDPTCTRL_TXS;
  465. } else {
  466. *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) &= ~USB_ENDPTCTRL_RXS;
  467. }
  468. endpoint0_receive(NULL, 0, 0);
  469. return;
  470. case 0x0680: // GET_DESCRIPTOR
  471. case 0x0681:
  472. for (list = usb_descriptor_list; list->addr != NULL; list++) {
  473. if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
  474. uint32_t datalen;
  475. if ((setup.wValue >> 8) == 3) {
  476. // for string descriptors, use the descriptor's
  477. // length field, allowing runtime configured length.
  478. datalen = *(list->addr);
  479. } else {
  480. datalen = list->length;
  481. }
  482. if (datalen > setup.wLength) datalen = setup.wLength;
  483. // copy the descriptor, from PROGMEM to DMAMEM
  484. if (setup.wValue == 0x200) {
  485. // config descriptor needs to adapt to speed
  486. const uint8_t *src = usb_config_descriptor_12;
  487. if (usb_high_speed) src = usb_config_descriptor_480;
  488. memcpy(usb_descriptor_buffer, src, datalen);
  489. } else if (setup.wValue == 0x700) {
  490. // other speed config also needs to adapt
  491. const uint8_t *src = usb_config_descriptor_480;
  492. if (usb_high_speed) src = usb_config_descriptor_12;
  493. memcpy(usb_descriptor_buffer, src, datalen);
  494. usb_descriptor_buffer[1] = 7;
  495. } else {
  496. memcpy(usb_descriptor_buffer, list->addr, datalen);
  497. }
  498. // prep transmit
  499. arm_dcache_flush_delete(usb_descriptor_buffer, datalen);
  500. endpoint0_transmit(usb_descriptor_buffer, datalen, 0);
  501. return;
  502. }
  503. }
  504. break;
  505. #if defined(CDC_STATUS_INTERFACE)
  506. case 0x2221: // CDC_SET_CONTROL_LINE_STATE
  507. #ifdef CDC_STATUS_INTERFACE
  508. if (setup.wIndex == CDC_STATUS_INTERFACE) {
  509. usb_cdc_line_rtsdtr_millis = systick_millis_count;
  510. usb_cdc_line_rtsdtr = setup.wValue;
  511. }
  512. #endif
  513. #ifdef CDC2_STATUS_INTERFACE
  514. if (setup.wIndex == CDC2_STATUS_INTERFACE) {
  515. usb_cdc2_line_rtsdtr_millis = systick_millis_count;
  516. usb_cdc2_line_rtsdtr = setup.wValue;
  517. }
  518. #endif
  519. #ifdef CDC3_STATUS_INTERFACE
  520. if (setup.wIndex == CDC3_STATUS_INTERFACE) {
  521. usb_cdc3_line_rtsdtr_millis = systick_millis_count;
  522. usb_cdc3_line_rtsdtr = setup.wValue;
  523. }
  524. #endif
  525. // fall through to next case, to always send ZLP ACK
  526. case 0x2321: // CDC_SEND_BREAK
  527. endpoint0_receive(NULL, 0, 0);
  528. return;
  529. case 0x2021: // CDC_SET_LINE_CODING
  530. if (setup.wLength != 7) break;
  531. endpoint0_setupdata.bothwords = setupdata;
  532. endpoint0_receive(endpoint0_buffer, 7, 1);
  533. return;
  534. #endif
  535. #if defined(SEREMU_INTERFACE) || defined(KEYBOARD_INTERFACE)
  536. case 0x0921: // HID SET_REPORT
  537. if (setup.wLength <= sizeof(endpoint0_buffer)) {
  538. //printf("hid set report %x %x\n", setup.word1, setup.word2);
  539. endpoint0_setupdata.bothwords = setup.bothwords;
  540. endpoint0_buffer[0] = 0xE9;
  541. endpoint0_receive(endpoint0_buffer, setup.wLength, 1);
  542. return;
  543. }
  544. break;
  545. #endif
  546. #if defined(AUDIO_INTERFACE)
  547. case 0x0B01: // SET_INTERFACE (alternate setting)
  548. if (setup.wIndex == AUDIO_INTERFACE+1) {
  549. usb_audio_transmit_setting = setup.wValue;
  550. if (usb_audio_transmit_setting > 0) {
  551. // TODO: set up AUDIO_TX_ENDPOINT to transmit
  552. }
  553. endpoint0_receive(NULL, 0, 0);
  554. return;
  555. } else if (setup.wIndex == AUDIO_INTERFACE+2) {
  556. usb_audio_receive_setting = setup.wValue;
  557. endpoint0_receive(NULL, 0, 0);
  558. return;
  559. }
  560. break;
  561. case 0x0A81: // GET_INTERFACE (alternate setting)
  562. if (setup.wIndex == AUDIO_INTERFACE+1) {
  563. endpoint0_buffer[0] = usb_audio_transmit_setting;
  564. endpoint0_transmit(endpoint0_buffer, 1, 0);
  565. return;
  566. } else if (setup.wIndex == AUDIO_INTERFACE+2) {
  567. endpoint0_buffer[0] = usb_audio_receive_setting;
  568. endpoint0_transmit(endpoint0_buffer, 1, 0);
  569. return;
  570. }
  571. break;
  572. case 0x0121: // SET FEATURE
  573. case 0x0221:
  574. case 0x0321:
  575. case 0x0421:
  576. //printf("set_feature, word1=%x, len=%d\n", setup.word1, setup.wLength);
  577. if (setup.wLength <= sizeof(endpoint0_buffer)) {
  578. endpoint0_setupdata.bothwords = setupdata;
  579. endpoint0_receive(endpoint0_buffer, setup.wLength, 1);
  580. return; // handle these after ACK
  581. }
  582. break;
  583. case 0x81A1: // GET FEATURE
  584. case 0x82A1:
  585. case 0x83A1:
  586. case 0x84A1:
  587. if (setup.wLength <= sizeof(endpoint0_buffer)) {
  588. uint32_t len;
  589. if (usb_audio_get_feature(&setup, endpoint0_buffer, &len)) {
  590. //printf("GET feature, len=%d\n", len);
  591. endpoint0_transmit(endpoint0_buffer, len, 0);
  592. return;
  593. }
  594. }
  595. break;
  596. case 0x81A2: // GET_CUR (wValue=0, wIndex=interface, wLength=len)
  597. if (setup.wLength >= 3) {
  598. endpoint0_buffer[0] = 44100 & 255;
  599. endpoint0_buffer[1] = 44100 >> 8;
  600. endpoint0_buffer[2] = 0;
  601. endpoint0_transmit(endpoint0_buffer, 3, 0);
  602. return;
  603. }
  604. break;
  605. #endif
  606. }
  607. USB1_ENDPTCTRL0 = 0x000010001; // stall
  608. }
  609. static void endpoint0_transmit(const void *data, uint32_t len, int notify)
  610. {
  611. //printf("tx %lu\n", len);
  612. if (len > 0) {
  613. // Executing A Transfer Descriptor, page 3182
  614. endpoint0_transfer_data.next = 1;
  615. endpoint0_transfer_data.status = (len << 16) | (1<<7);
  616. uint32_t addr = (uint32_t)data;
  617. endpoint0_transfer_data.pointer0 = addr; // format: table 55-60, pg 3159
  618. endpoint0_transfer_data.pointer1 = addr + 4096;
  619. endpoint0_transfer_data.pointer2 = addr + 8192;
  620. endpoint0_transfer_data.pointer3 = addr + 12288;
  621. endpoint0_transfer_data.pointer4 = addr + 16384;
  622. // Case 1: Link list is empty, page 3182
  623. endpoint_queue_head[1].next = (uint32_t)&endpoint0_transfer_data;
  624. endpoint_queue_head[1].status = 0;
  625. USB1_ENDPTPRIME |= (1<<16);
  626. while (USB1_ENDPTPRIME) ;
  627. }
  628. endpoint0_transfer_ack.next = 1;
  629. endpoint0_transfer_ack.status = (1<<7) | (notify ? (1 << 15) : 0);
  630. endpoint0_transfer_ack.pointer0 = 0;
  631. endpoint_queue_head[0].next = (uint32_t)&endpoint0_transfer_ack;
  632. endpoint_queue_head[0].status = 0;
  633. USB1_ENDPTCOMPLETE = (1<<0) | (1<<16);
  634. USB1_ENDPTPRIME |= (1<<0);
  635. endpoint0_notify_mask = (notify ? (1 << 0) : 0);
  636. while (USB1_ENDPTPRIME) ;
  637. }
  638. static void endpoint0_receive(void *data, uint32_t len, int notify)
  639. {
  640. //printf("rx %lu\n", len);
  641. if (len > 0) {
  642. // Executing A Transfer Descriptor, page 3182
  643. endpoint0_transfer_data.next = 1;
  644. endpoint0_transfer_data.status = (len << 16) | (1<<7);
  645. uint32_t addr = (uint32_t)data;
  646. endpoint0_transfer_data.pointer0 = addr; // format: table 55-60, pg 3159
  647. endpoint0_transfer_data.pointer1 = addr + 4096;
  648. endpoint0_transfer_data.pointer2 = addr + 8192;
  649. endpoint0_transfer_data.pointer3 = addr + 12288;
  650. endpoint0_transfer_data.pointer4 = addr + 16384;
  651. // Case 1: Link list is empty, page 3182
  652. endpoint_queue_head[0].next = (uint32_t)&endpoint0_transfer_data;
  653. endpoint_queue_head[0].status = 0;
  654. USB1_ENDPTPRIME |= (1<<0);
  655. while (USB1_ENDPTPRIME) ;
  656. }
  657. endpoint0_transfer_ack.next = 1;
  658. endpoint0_transfer_ack.status = (1<<7) | (notify ? (1 << 15) : 0);
  659. endpoint0_transfer_ack.pointer0 = 0;
  660. endpoint_queue_head[1].next = (uint32_t)&endpoint0_transfer_ack;
  661. endpoint_queue_head[1].status = 0;
  662. USB1_ENDPTCOMPLETE = (1<<0) | (1<<16);
  663. USB1_ENDPTPRIME |= (1<<16);
  664. endpoint0_notify_mask = (notify ? (1 << 16) : 0);
  665. while (USB1_ENDPTPRIME) ;
  666. }
  667. /*typedef union {
  668. struct {
  669. union {
  670. struct {
  671. uint8_t bmRequestType;
  672. uint8_t bRequest;
  673. };
  674. uint16_t wRequestAndType;
  675. };
  676. uint16_t wValue;
  677. uint16_t wIndex;
  678. uint16_t wLength;
  679. };
  680. struct {
  681. uint32_t word1;
  682. uint32_t word2;
  683. };
  684. uint64_t bothwords;
  685. } setup_t; */
  686. static void endpoint0_complete(void)
  687. {
  688. setup_t setup;
  689. setup.bothwords = endpoint0_setupdata.bothwords;
  690. //printf("complete %x %x %x\n", setup.word1, setup.word2, endpoint0_buffer[0]);
  691. #ifdef CDC_STATUS_INTERFACE
  692. // 0x2021 is CDC_SET_LINE_CODING
  693. if (setup.wRequestAndType == 0x2021 && setup.wIndex == CDC_STATUS_INTERFACE) {
  694. memcpy(usb_cdc_line_coding, endpoint0_buffer, 7);
  695. printf("usb_cdc_line_coding, baud=%u\n", usb_cdc_line_coding[0]);
  696. if (usb_cdc_line_coding[0] == 134) {
  697. usb_start_sof_interrupts(NUM_INTERFACE);
  698. usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
  699. }
  700. }
  701. #endif
  702. #ifdef CDC2_STATUS_INTERFACE
  703. if (setup.wRequestAndType == 0x2021 && setup.wIndex == CDC2_STATUS_INTERFACE) {
  704. memcpy(usb_cdc2_line_coding, endpoint0_buffer, 7);
  705. printf("usb_cdc2_line_coding, baud=%u\n", usb_cdc2_line_coding[0]);
  706. if (usb_cdc2_line_coding[0] == 134) {
  707. usb_start_sof_interrupts(NUM_INTERFACE);
  708. usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
  709. }
  710. }
  711. #endif
  712. #ifdef CDC3_STATUS_INTERFACE
  713. if (setup.wRequestAndType == 0x2021 && setup.wIndex == CDC3_STATUS_INTERFACE) {
  714. memcpy(usb_cdc3_line_coding, endpoint0_buffer, 7);
  715. printf("usb_cdc3_line_coding, baud=%u\n", usb_cdc3_line_coding[0]);
  716. if (usb_cdc3_line_coding[0] == 134) {
  717. usb_start_sof_interrupts(NUM_INTERFACE);
  718. usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
  719. }
  720. }
  721. #endif
  722. #ifdef KEYBOARD_INTERFACE
  723. if (setup.word1 == 0x02000921 && setup.word2 == ((1 << 16) | KEYBOARD_INTERFACE)) {
  724. keyboard_leds = endpoint0_buffer[0];
  725. endpoint0_transmit(NULL, 0, 0);
  726. }
  727. #endif
  728. #ifdef SEREMU_INTERFACE
  729. if (setup.word1 == 0x03000921 && setup.word2 == ((4<<16)|SEREMU_INTERFACE)) {
  730. if (endpoint0_buffer[0] == 0xA9 && endpoint0_buffer[1] == 0x45
  731. && endpoint0_buffer[2] == 0xC2 && endpoint0_buffer[3] == 0x6B) {
  732. printf("seremu reboot request\n");
  733. usb_start_sof_interrupts(NUM_INTERFACE);
  734. usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
  735. } else {
  736. // any other feature report means Arduino Serial Monitor is open
  737. usb_seremu_online = 1;
  738. }
  739. }
  740. #endif
  741. #ifdef AUDIO_INTERFACE
  742. if (setup.word1 == 0x02010121 /* TODO: check setup.word2 */) {
  743. usb_audio_set_feature(&endpoint0_setupdata, endpoint0_buffer);
  744. }
  745. #endif
  746. }
  747. static void usb_endpoint_config(endpoint_t *qh, uint32_t config, void (*callback)(transfer_t *))
  748. {
  749. memset(qh, 0, sizeof(endpoint_t));
  750. qh->config = config;
  751. qh->next = 1; // Terminate bit = 1
  752. qh->callback_function = callback;
  753. }
  754. void usb_config_rx(uint32_t ep, uint32_t packet_size, int do_zlp, void (*cb)(transfer_t *))
  755. {
  756. uint32_t config = (packet_size << 16) | (do_zlp ? 0 : (1 << 29));
  757. if (ep < 2 || ep > NUM_ENDPOINTS) return;
  758. usb_endpoint_config(endpoint_queue_head + ep * 2, config, cb);
  759. if (cb) endpointN_notify_mask |= (1 << ep);
  760. }
  761. void usb_config_tx(uint32_t ep, uint32_t packet_size, int do_zlp, void (*cb)(transfer_t *))
  762. {
  763. uint32_t config = (packet_size << 16) | (do_zlp ? 0 : (1 << 29));
  764. if (ep < 2 || ep > NUM_ENDPOINTS) return;
  765. usb_endpoint_config(endpoint_queue_head + ep * 2 + 1, config, cb);
  766. if (cb) endpointN_notify_mask |= (1 << (ep + 16));
  767. }
  768. void usb_config_rx_iso(uint32_t ep, uint32_t packet_size, int mult, void (*cb)(transfer_t *))
  769. {
  770. if (mult < 1 || mult > 3) return;
  771. uint32_t config = (packet_size << 16) | (mult << 30);
  772. if (ep < 2 || ep > NUM_ENDPOINTS) return;
  773. usb_endpoint_config(endpoint_queue_head + ep * 2, config, cb);
  774. if (cb) endpointN_notify_mask |= (1 << ep);
  775. }
  776. void usb_config_tx_iso(uint32_t ep, uint32_t packet_size, int mult, void (*cb)(transfer_t *))
  777. {
  778. if (mult < 1 || mult > 3) return;
  779. uint32_t config = (packet_size << 16) | (mult << 30);
  780. if (ep < 2 || ep > NUM_ENDPOINTS) return;
  781. usb_endpoint_config(endpoint_queue_head + ep * 2 + 1, config, cb);
  782. if (cb) endpointN_notify_mask |= (1 << (ep + 16));
  783. }
  784. void usb_prepare_transfer(transfer_t *transfer, const void *data, uint32_t len, uint32_t param)
  785. {
  786. transfer->next = 1;
  787. transfer->status = (len << 16) | (1<<7);
  788. uint32_t addr = (uint32_t)data;
  789. transfer->pointer0 = addr;
  790. transfer->pointer1 = addr + 4096;
  791. transfer->pointer2 = addr + 8192;
  792. transfer->pointer3 = addr + 12288;
  793. transfer->pointer4 = addr + 16384;
  794. transfer->callback_param = param;
  795. }
  796. #if 0
  797. void usb_print_transfer_log(void)
  798. {
  799. uint32_t i, count;
  800. printf("log %d transfers\n", transfer_log_count);
  801. count = transfer_log_count;
  802. if (count > LOG_SIZE) count = LOG_SIZE;
  803. for (i=0; i < count; i++) {
  804. if (transfer_log_head == 0) transfer_log_head = LOG_SIZE;
  805. transfer_log_head--;
  806. uint32_t log = transfer_log[transfer_log_head];
  807. printf(" %c %X\n", log >> 8, (int)(log & 255));
  808. }
  809. }
  810. #endif
  811. static void schedule_transfer(endpoint_t *endpoint, uint32_t epmask, transfer_t *transfer)
  812. {
  813. // when we stop at 6, why is the last transfer missing from the USB output?
  814. //if (transfer_log_count >= 6) return;
  815. //uint32_t ret = (*(const uint8_t *)transfer->pointer0) << 8;
  816. if (endpoint->callback_function) {
  817. transfer->status |= (1<<15);
  818. }
  819. __disable_irq();
  820. //digitalWriteFast(1, HIGH);
  821. // Executing A Transfer Descriptor, page 2468 (RT1060 manual, Rev 1, 12/2018)
  822. transfer_t *last = endpoint->last_transfer;
  823. if (last) {
  824. last->next = (uint32_t)transfer;
  825. if (USB1_ENDPTPRIME & epmask) goto end;
  826. //digitalWriteFast(2, HIGH);
  827. //ret |= 0x01;
  828. uint32_t status, cyccnt=ARM_DWT_CYCCNT;
  829. do {
  830. USB1_USBCMD |= USB_USBCMD_ATDTW;
  831. status = USB1_ENDPTSTATUS;
  832. } while (!(USB1_USBCMD & USB_USBCMD_ATDTW) && (ARM_DWT_CYCCNT - cyccnt < 2400));
  833. //USB1_USBCMD &= ~USB_USBCMD_ATDTW;
  834. if (status & epmask) goto end;
  835. //ret |= 0x02;
  836. }
  837. //digitalWriteFast(4, HIGH);
  838. endpoint->next = (uint32_t)transfer;
  839. endpoint->status = 0;
  840. USB1_ENDPTPRIME |= epmask;
  841. endpoint->first_transfer = transfer;
  842. end:
  843. endpoint->last_transfer = transfer;
  844. __enable_irq();
  845. //digitalWriteFast(4, LOW);
  846. //digitalWriteFast(3, LOW);
  847. //digitalWriteFast(2, LOW);
  848. //digitalWriteFast(1, LOW);
  849. //if (transfer_log_head > LOG_SIZE) transfer_log_head = 0;
  850. //transfer_log[transfer_log_head++] = ret;
  851. //transfer_log_count++;
  852. }
  853. // ENDPTPRIME - Software should write a one to the corresponding bit when
  854. // posting a new transfer descriptor to an endpoint queue head.
  855. // Hardware automatically uses this bit to begin parsing for a
  856. // new transfer descriptor from the queue head and prepare a
  857. // transmit buffer. Hardware clears this bit when the associated
  858. // endpoint(s) is (are) successfully primed.
  859. // Momentarily set by hardware during hardware re-priming
  860. // operations when a dTD is retired, and the dQH is updated.
  861. // ENDPTSTATUS - Transmit Buffer Ready - set to one by the hardware as a
  862. // response to receiving a command from a corresponding bit
  863. // in the ENDPTPRIME register. . Buffer ready is cleared by
  864. // USB reset, by the USB DMA system, or through the ENDPTFLUSH
  865. // register. (so 0=buffer ready, 1=buffer primed for transmit)
  866. // USBCMD.ATDTW - This bit is used as a semaphore to ensure proper addition
  867. // of a new dTD to an active (primed) endpoint's linked list.
  868. // This bit is set and cleared by software.
  869. // This bit would also be cleared by hardware when state machine
  870. // is hazard region for which adding a dTD to a primed endpoint
  871. // may go unrecognized.
  872. /*struct endpoint_struct {
  873. uint32_t config;
  874. uint32_t current;
  875. uint32_t next;
  876. uint32_t status;
  877. uint32_t pointer0;
  878. uint32_t pointer1;
  879. uint32_t pointer2;
  880. uint32_t pointer3;
  881. uint32_t pointer4;
  882. uint32_t reserved;
  883. uint32_t setup0;
  884. uint32_t setup1;
  885. transfer_t *first_transfer;
  886. transfer_t *last_transfer;
  887. void (*callback_function)(transfer_t *completed_transfer);
  888. uint32_t unused1;
  889. };*/
  890. static void run_callbacks(endpoint_t *ep)
  891. {
  892. //printf("run_callbacks\n");
  893. transfer_t *first = ep->first_transfer;
  894. if (first == NULL) return;
  895. // count how many transfers are completed, then remove them from the endpoint's list
  896. uint32_t count = 0;
  897. transfer_t *t = first;
  898. while (1) {
  899. if (t->status & (1<<7)) {
  900. // found a still-active transfer, new list begins here
  901. //printf(" still active\n");
  902. ep->first_transfer = t;
  903. break;
  904. }
  905. count++;
  906. t = (transfer_t *)t->next;
  907. if ((uint32_t)t == 1) {
  908. // reached end of list, all need callbacks, new list is empty
  909. //printf(" end of list\n");
  910. ep->first_transfer = NULL;
  911. ep->last_transfer = NULL;
  912. break;
  913. }
  914. }
  915. // do all the callbacks
  916. while (count) {
  917. transfer_t *next = (transfer_t *)first->next;
  918. ep->callback_function(first);
  919. first = next;
  920. count--;
  921. }
  922. }
  923. void usb_transmit(int endpoint_number, transfer_t *transfer)
  924. {
  925. if (endpoint_number < 2 || endpoint_number > NUM_ENDPOINTS) return;
  926. endpoint_t *endpoint = endpoint_queue_head + endpoint_number * 2 + 1;
  927. uint32_t mask = 1 << (endpoint_number + 16);
  928. schedule_transfer(endpoint, mask, transfer);
  929. }
  930. void usb_receive(int endpoint_number, transfer_t *transfer)
  931. {
  932. if (endpoint_number < 2 || endpoint_number > NUM_ENDPOINTS) return;
  933. endpoint_t *endpoint = endpoint_queue_head + endpoint_number * 2;
  934. uint32_t mask = 1 << endpoint_number;
  935. schedule_transfer(endpoint, mask, transfer);
  936. }
  937. uint32_t usb_transfer_status(const transfer_t *transfer)
  938. {
  939. #if defined(USB_MTPDISK) || defined(USB_MTPDISK_SERIAL)
  940. uint32_t status, cmd;
  941. //int count=0;
  942. cmd = USB1_USBCMD;
  943. while (1) {
  944. __disable_irq();
  945. USB1_USBCMD = cmd | USB_USBCMD_ATDTW;
  946. status = transfer->status;
  947. cmd = USB1_USBCMD;
  948. __enable_irq();
  949. if (cmd & USB_USBCMD_ATDTW) return status;
  950. //if (!(cmd & USB_USBCMD_ATDTW)) continue;
  951. //if (status & 0x80) break; // for still active, only 1 reading needed
  952. //if (++count > 1) break; // for completed, check 10 times
  953. }
  954. #else
  955. return transfer->status;
  956. #endif
  957. }
  958. #else // defined(NUM_ENDPOINTS)
  959. void usb_init(void)
  960. {
  961. }
  962. #endif // defined(NUM_ENDPOINTS)