Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. #include "usb_dev.h"
  2. #define USB_DESC_LIST_DEFINE
  3. #include "usb_desc.h"
  4. #include "usb_serial.h"
  5. #include <string.h>
  6. #include "debug/printf.h"
  7. // device mode, page 3155
  8. typedef struct endpoint_struct endpoint_t;
  9. struct endpoint_struct {
  10. uint32_t config;
  11. uint32_t current;
  12. uint32_t next;
  13. uint32_t status;
  14. uint32_t pointer0;
  15. uint32_t pointer1;
  16. uint32_t pointer2;
  17. uint32_t pointer3;
  18. uint32_t pointer4;
  19. uint32_t reserved;
  20. uint32_t setup0;
  21. uint32_t setup1;
  22. transfer_t *first_transfer;
  23. transfer_t *last_transfer;
  24. void (*callback_function)(transfer_t *completed_transfer);
  25. uint32_t unused1;
  26. };
  27. /*struct transfer_struct {
  28. uint32_t next;
  29. uint32_t status;
  30. uint32_t pointer0;
  31. uint32_t pointer1;
  32. uint32_t pointer2;
  33. uint32_t pointer3;
  34. uint32_t pointer4;
  35. uint32_t callback_param;
  36. };*/
  37. endpoint_t endpoint_queue_head[(NUM_ENDPOINTS+1)*2] __attribute__ ((used, aligned(4096)));
  38. transfer_t endpoint0_transfer_data __attribute__ ((used, aligned(32)));
  39. transfer_t endpoint0_transfer_ack __attribute__ ((used, aligned(32)));
  40. typedef union {
  41. struct {
  42. union {
  43. struct {
  44. uint8_t bmRequestType;
  45. uint8_t bRequest;
  46. };
  47. uint16_t wRequestAndType;
  48. };
  49. uint16_t wValue;
  50. uint16_t wIndex;
  51. uint16_t wLength;
  52. };
  53. struct {
  54. uint32_t word1;
  55. uint32_t word2;
  56. };
  57. uint64_t bothwords;
  58. } setup_t;
  59. static setup_t endpoint0_setupdata;
  60. static uint32_t endpoint0_notify_mask=0;
  61. static uint32_t endpointN_notify_mask=0;
  62. //static int reset_count=0;
  63. volatile uint8_t usb_configuration = 0;
  64. static uint8_t endpoint0_buffer[8];
  65. static uint8_t usb_reboot_timer = 0;
  66. static void isr(void);
  67. static void endpoint0_setup(uint64_t setupdata);
  68. static void endpoint0_transmit(const void *data, uint32_t len, int notify);
  69. static void endpoint0_receive(void *data, uint32_t len, int notify);
  70. static void endpoint0_complete(void);
  71. void usb_init(void)
  72. {
  73. // TODO: only enable when VBUS detected
  74. // TODO: return to low power mode when VBUS removed
  75. // TODO: protect PMU access with MPU
  76. PMU_REG_3P0 = PMU_REG_3P0_OUTPUT_TRG(0x0F) | PMU_REG_3P0_BO_OFFSET(6)
  77. | PMU_REG_3P0_ENABLE_LINREG;
  78. usb_init_serialnumber();
  79. // assume PLL3 is already running - already done by usb_pll_start() in main.c
  80. CCM_CCGR6 |= CCM_CCGR6_USBOH3(CCM_CCGR_ON); // turn on clocks to USB peripheral
  81. // Before programming this register, the PHY clocks must be enabled in registers
  82. // USBPHYx_CTRLn and CCM_ANALOG_USBPHYx_PLL_480_CTRLn.
  83. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  84. //printf("USBPHY1_TX=%08lX\n", USBPHY1_TX);
  85. //printf("USBPHY1_RX=%08lX\n", USBPHY1_RX);
  86. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  87. //printf("USB1_USBMODE=%08lX\n", USB1_USBMODE);
  88. // turn on PLL3, wait for 480 MHz lock?
  89. // turn on CCM clock gates? CCGR6[CG0]
  90. #if 1
  91. if ((USBPHY1_PWD & (USBPHY_PWD_RXPWDRX | USBPHY_PWD_RXPWDDIFF | USBPHY_PWD_RXPWD1PT1
  92. | USBPHY_PWD_RXPWDENV | USBPHY_PWD_TXPWDV2I | USBPHY_PWD_TXPWDIBIAS
  93. | USBPHY_PWD_TXPWDFS)) || (USB1_USBMODE & USB_USBMODE_CM_MASK)) {
  94. // USB controller is turned on from previous use
  95. // reset needed to turn it off & start from clean slate
  96. USBPHY1_CTRL_SET = USBPHY_CTRL_SFTRST; // USBPHY1_CTRL page 3292
  97. USB1_USBCMD |= USB_USBCMD_RST; // reset controller
  98. int count=0;
  99. while (USB1_USBCMD & USB_USBCMD_RST) count++;
  100. NVIC_CLEAR_PENDING(IRQ_USB1);
  101. USBPHY1_CTRL_CLR = USBPHY_CTRL_SFTRST; // reset PHY
  102. //USB1_USBSTS = USB1_USBSTS; // TODO: is this needed?
  103. printf("USB reset took %d loops\n", count);
  104. //delay(10);
  105. //printf("\n");
  106. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  107. //printf("USBPHY1_TX=%08lX\n", USBPHY1_TX);
  108. //printf("USBPHY1_RX=%08lX\n", USBPHY1_RX);
  109. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  110. //printf("USB1_USBMODE=%08lX\n", USB1_USBMODE);
  111. delay(100);
  112. }
  113. #endif
  114. // Device Controller Initialization, page 3161
  115. // USBCMD pg 3216
  116. // USBSTS pg 3220
  117. // USBINTR pg 3224
  118. // DEVICEADDR pg 3227
  119. // ENDPTLISTADDR 3229
  120. // USBMODE pg 3244
  121. // ENDPTSETUPSTAT 3245
  122. // ENDPTPRIME pg 3246
  123. // ENDPTFLUSH pg 3247
  124. // ENDPTSTAT pg 3247
  125. // ENDPTCOMPLETE 3248
  126. // ENDPTCTRL0 pg 3249
  127. USBPHY1_CTRL_CLR = USBPHY_CTRL_CLKGATE;
  128. USBPHY1_PWD = 0;
  129. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  130. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  131. USB1_USBMODE = USB_USBMODE_CM(2) | USB_USBMODE_SLOM;
  132. memset(endpoint_queue_head, 0, sizeof(endpoint_queue_head));
  133. endpoint_queue_head[0].config = (64 << 16) | (1 << 15);
  134. endpoint_queue_head[1].config = (64 << 16);
  135. USB1_ENDPOINTLISTADDR = (uint32_t)&endpoint_queue_head;
  136. // Recommended: enable all device interrupts including: USBINT, USBERRINT,
  137. // Port Change Detect, USB Reset Received, DCSuspend.
  138. USB1_USBINTR = USB_USBINTR_UE | USB_USBINTR_UEE | /* USB_USBINTR_PCE | */
  139. USB_USBINTR_URE | USB_USBINTR_SLE;
  140. //_VectorsRam[IRQ_USB1+16] = &isr;
  141. attachInterruptVector(IRQ_USB1, &isr);
  142. NVIC_ENABLE_IRQ(IRQ_USB1);
  143. //printf("USB1_ENDPTCTRL0=%08lX\n", USB1_ENDPTCTRL0);
  144. //printf("USB1_ENDPTCTRL1=%08lX\n", USB1_ENDPTCTRL1);
  145. //printf("USB1_ENDPTCTRL2=%08lX\n", USB1_ENDPTCTRL2);
  146. //printf("USB1_ENDPTCTRL3=%08lX\n", USB1_ENDPTCTRL3);
  147. USB1_USBCMD |= USB_USBCMD_RS;
  148. }
  149. static void isr(void)
  150. {
  151. //printf("*");
  152. // Port control in device mode is only used for
  153. // status port reset, suspend, and current connect status.
  154. uint32_t status = USB1_USBSTS;
  155. USB1_USBSTS = status;
  156. // USB_USBSTS_SLI - set to 1 when enters a suspend state from an active state
  157. // USB_USBSTS_SRI - set at start of frame
  158. // USB_USBSTS_SRI - set when USB reset detected
  159. if (status & USB_USBSTS_UI) {
  160. //printf("data\n");
  161. uint32_t setupstatus = USB1_ENDPTSETUPSTAT;
  162. //printf("USB1_ENDPTSETUPSTAT=%X\n", setupstatus);
  163. while (setupstatus) {
  164. USB1_ENDPTSETUPSTAT = setupstatus;
  165. setup_t s;
  166. do {
  167. USB1_USBCMD |= USB_USBCMD_SUTW;
  168. s.word1 = endpoint_queue_head[0].setup0;
  169. s.word2 = endpoint_queue_head[0].setup1;
  170. } while (!(USB1_USBCMD & USB_USBCMD_SUTW));
  171. USB1_USBCMD &= ~USB_USBCMD_SUTW;
  172. //printf("setup %08lX %08lX\n", s.word1, s.word2);
  173. USB1_ENDPTFLUSH = (1<<16) | (1<<0); // page 3174
  174. while (USB1_ENDPTFLUSH & ((1<<16) | (1<<0))) ;
  175. endpoint0_notify_mask = 0;
  176. endpoint0_setup(s.bothwords);
  177. setupstatus = USB1_ENDPTSETUPSTAT; // page 3175
  178. }
  179. uint32_t completestatus = USB1_ENDPTCOMPLETE;
  180. if (completestatus) {
  181. USB1_ENDPTCOMPLETE = completestatus;
  182. //printf("USB1_ENDPTCOMPLETE=%lX\n", completestatus);
  183. if (completestatus & endpoint0_notify_mask) {
  184. endpoint0_notify_mask = 0;
  185. endpoint0_complete();
  186. }
  187. if (completestatus & endpointN_notify_mask) {
  188. // TODO: callback functions...
  189. }
  190. }
  191. }
  192. if (status & USB_USBSTS_URI) { // page 3164
  193. USB1_ENDPTSETUPSTAT = USB1_ENDPTSETUPSTAT; // Clear all setup token semaphores
  194. USB1_ENDPTCOMPLETE = USB1_ENDPTCOMPLETE; // Clear all the endpoint complete status
  195. while (USB1_ENDPTPRIME != 0) ; // Wait for any endpoint priming
  196. USB1_ENDPTFLUSH = 0xFFFFFFFF; // Cancel all endpoint primed status
  197. if ((USB1_PORTSC1 & USB_PORTSC1_PR)) {
  198. //printf("reset\n");
  199. } else {
  200. // we took too long to respond :(
  201. // TODO; is this ever really a problem?
  202. //printf("reset too slow\n");
  203. }
  204. // TODO: Free all allocated dTDs
  205. //if (++reset_count >= 3) {
  206. // shut off USB - easier to see results in protocol analyzer
  207. //USB1_USBCMD &= ~USB_USBCMD_RS;
  208. //printf("shut off USB\n");
  209. //}
  210. }
  211. if (status & USB_USBSTS_PCI) {
  212. if (USB1_PORTSC1 & USB_PORTSC1_HSP) {
  213. //printf("port at 480 Mbit\n");
  214. } else {
  215. //printf("port at 12 Mbit\n");
  216. }
  217. }
  218. if (status & USB_USBSTS_SLI) { // page 3165
  219. //printf("suspend\n");
  220. }
  221. if (status & USB_USBSTS_UEI) {
  222. //printf("error\n");
  223. }
  224. if ((USB1_USBINTR & USB_USBINTR_SRE) && (status & USB_USBSTS_SRI)) {
  225. printf("sof %d\n", usb_reboot_timer);
  226. if (usb_reboot_timer) {
  227. if (--usb_reboot_timer == 0) {
  228. asm("bkpt #251"); // run bootloader
  229. }
  230. } else {
  231. // turn off the SOF interrupt if nothing using it
  232. USB1_USBINTR &= ~USB_USBINTR_SRE;
  233. }
  234. }
  235. }
  236. /*
  237. struct transfer_struct { // table 55-60, pg 3159
  238. uint32_t next;
  239. uint32_t status;
  240. uint32_t pointer0;
  241. uint32_t pointer1;
  242. uint32_t pointer2;
  243. uint32_t pointer3;
  244. uint32_t pointer4;
  245. uint32_t unused1;
  246. };
  247. transfer_t endpoint0_transfer_data __attribute__ ((aligned(32)));;
  248. transfer_t endpoint0_transfer_ack __attribute__ ((aligned(32)));;
  249. */
  250. static void endpoint0_setup(uint64_t setupdata)
  251. {
  252. setup_t setup;
  253. uint32_t datalen = 0;
  254. const usb_descriptor_list_t *list;
  255. setup.bothwords = setupdata;
  256. switch (setup.wRequestAndType) {
  257. case 0x0500: // SET_ADDRESS
  258. endpoint0_receive(NULL, 0, 0);
  259. USB1_DEVICEADDR = USB_DEVICEADDR_USBADR(setup.wValue) | USB_DEVICEADDR_USBADRA;
  260. return;
  261. case 0x0900: // SET_CONFIGURATION
  262. usb_configuration = setup.wValue;
  263. // configure all other endpoints
  264. volatile uint32_t *reg = &USB1_ENDPTCTRL1;
  265. const uint32_t *cfg = usb_endpoint_config_table;
  266. int i;
  267. for (i=0; i < NUM_ENDPOINTS; i++) {
  268. uint32_t n = *cfg++;
  269. *reg = n;
  270. // TODO: do the TRX & RXR bits self clear??
  271. uint32_t m = n & ~(USB_ENDPTCTRL_TXR | USB_ENDPTCTRL_RXR);
  272. *reg = m;
  273. //uint32_t p = *reg;
  274. //printf(" ep=%d: cfg=%08lX - %08lX - %08lX\n", i + 1, n, m, p);
  275. reg++;
  276. }
  277. // TODO: configure all queue heads with max packet length, zlt & mult
  278. endpoint_queue_head[CDC_ACM_ENDPOINT*2+1].config = (CDC_ACM_ENDPOINT << 16);
  279. endpoint_queue_head[CDC_RX_ENDPOINT*2+0].config = (CDC_RX_SIZE << 16) | (1 << 29);
  280. endpoint_queue_head[CDC_TX_ENDPOINT*2+1].config = (CDC_TX_SIZE << 16) | (1 << 29);
  281. // TODO: de-allocate any pending transfers?
  282. endpoint0_receive(NULL, 0, 0);
  283. return;
  284. case 0x0680: // GET_DESCRIPTOR
  285. case 0x0681:
  286. //printf("desc:\n"); // yay - sending device descriptor now works!!!!
  287. for (list = usb_descriptor_list; list->addr != NULL; list++) {
  288. if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
  289. if ((setup.wValue >> 8) == 3) {
  290. // for string descriptors, use the descriptor's
  291. // length field, allowing runtime configured length.
  292. datalen = *(list->addr);
  293. } else {
  294. datalen = list->length;
  295. }
  296. if (datalen > setup.wLength) datalen = setup.wLength;
  297. endpoint0_transmit(list->addr, datalen, 0);
  298. return;
  299. }
  300. }
  301. break;
  302. case 0x2221: // CDC_SET_CONTROL_LINE_STATE
  303. usb_cdc_line_rtsdtr_millis = systick_millis_count;
  304. usb_cdc_line_rtsdtr = setup.wValue;
  305. case 0x2321: // CDC_SEND_BREAK
  306. endpoint0_receive(NULL, 0, 0);
  307. return;
  308. case 0x2021: // CDC_SET_LINE_CODING
  309. if (setup.wLength != 7) break;
  310. endpoint0_setupdata.bothwords = setupdata;
  311. endpoint0_receive(endpoint0_buffer, 7, 1);
  312. return;
  313. }
  314. USB1_ENDPTCTRL0 = 0x000010001; // stall
  315. }
  316. static void endpoint0_transmit(const void *data, uint32_t len, int notify)
  317. {
  318. //printf("tx %lu\n", len);
  319. if (len > 0) {
  320. // Executing A Transfer Descriptor, page 3182
  321. endpoint0_transfer_data.next = 1;
  322. endpoint0_transfer_data.status = (len << 16) | (1<<7);
  323. uint32_t addr = (uint32_t)data;
  324. endpoint0_transfer_data.pointer0 = addr; // format: table 55-60, pg 3159
  325. endpoint0_transfer_data.pointer1 = addr + 4096;
  326. endpoint0_transfer_data.pointer2 = addr + 8192;
  327. endpoint0_transfer_data.pointer3 = addr + 12288;
  328. endpoint0_transfer_data.pointer4 = addr + 16384;
  329. // Case 1: Link list is empty, page 3182
  330. endpoint_queue_head[1].next = (uint32_t)&endpoint0_transfer_data;
  331. endpoint_queue_head[1].status = 0;
  332. USB1_ENDPTPRIME |= (1<<16);
  333. while (USB1_ENDPTPRIME) ;
  334. }
  335. endpoint0_transfer_ack.next = 1;
  336. endpoint0_transfer_ack.status = (1<<7) | (notify ? (1 << 15) : 0);
  337. endpoint0_transfer_ack.pointer0 = 0;
  338. endpoint_queue_head[0].next = (uint32_t)&endpoint0_transfer_ack;
  339. endpoint_queue_head[0].status = 0;
  340. USB1_ENDPTPRIME |= (1<<0);
  341. endpoint0_notify_mask = (notify ? (1 << 0) : 0);
  342. while (USB1_ENDPTPRIME) ;
  343. }
  344. static void endpoint0_receive(void *data, uint32_t len, int notify)
  345. {
  346. //printf("rx %lu\n", len);
  347. if (len > 0) {
  348. // Executing A Transfer Descriptor, page 3182
  349. endpoint0_transfer_data.next = 1;
  350. endpoint0_transfer_data.status = (len << 16) | (1<<7);
  351. uint32_t addr = (uint32_t)data;
  352. endpoint0_transfer_data.pointer0 = addr; // format: table 55-60, pg 3159
  353. endpoint0_transfer_data.pointer1 = addr + 4096;
  354. endpoint0_transfer_data.pointer2 = addr + 8192;
  355. endpoint0_transfer_data.pointer3 = addr + 12288;
  356. endpoint0_transfer_data.pointer4 = addr + 16384;
  357. // Case 1: Link list is empty, page 3182
  358. endpoint_queue_head[0].next = (uint32_t)&endpoint0_transfer_data;
  359. endpoint_queue_head[0].status = 0;
  360. USB1_ENDPTPRIME |= (1<<0);
  361. while (USB1_ENDPTPRIME) ;
  362. }
  363. endpoint0_transfer_ack.next = 1;
  364. endpoint0_transfer_ack.status = (1<<7) | (notify ? (1 << 15) : 0);
  365. endpoint0_transfer_ack.pointer0 = 0;
  366. endpoint_queue_head[1].next = (uint32_t)&endpoint0_transfer_ack;
  367. endpoint_queue_head[1].status = 0;
  368. USB1_ENDPTPRIME |= (1<<16);
  369. endpoint0_notify_mask = (notify ? (1 << 16) : 0);
  370. while (USB1_ENDPTPRIME) ;
  371. }
  372. /*typedef union {
  373. struct {
  374. union {
  375. struct {
  376. uint8_t bmRequestType;
  377. uint8_t bRequest;
  378. };
  379. uint16_t wRequestAndType;
  380. };
  381. uint16_t wValue;
  382. uint16_t wIndex;
  383. uint16_t wLength;
  384. };
  385. struct {
  386. uint32_t word1;
  387. uint32_t word2;
  388. };
  389. uint64_t bothwords;
  390. } setup_t; */
  391. static void endpoint0_complete(void)
  392. {
  393. setup_t setup;
  394. setup.bothwords = endpoint0_setupdata.bothwords;
  395. //printf("complete\n");
  396. #ifdef CDC_STATUS_INTERFACE
  397. if (setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/) {
  398. memcpy(usb_cdc_line_coding, endpoint0_buffer, 7);
  399. printf("usb_cdc_line_coding, baud=%u\n", usb_cdc_line_coding[0]);
  400. if (usb_cdc_line_coding[0] == 134) {
  401. USB1_USBINTR |= USB_USBINTR_SRE;
  402. usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
  403. }
  404. }
  405. #endif
  406. }
  407. void usb_prepare_transfer(transfer_t *transfer, const void *data, uint32_t len, uint32_t param)
  408. {
  409. transfer->next = 1;
  410. transfer->status = (len << 16) | (1<<7);
  411. uint32_t addr = (uint32_t)data;
  412. transfer->pointer0 = addr;
  413. transfer->pointer1 = addr + 4096;
  414. transfer->pointer2 = addr + 8192;
  415. transfer->pointer3 = addr + 12288;
  416. transfer->pointer4 = addr + 16384;
  417. transfer->callback_param = param;
  418. }
  419. void usb_transmit(int endpoint_number, transfer_t *transfer)
  420. {
  421. // endpoint 0 reserved for control
  422. // endpoint 1 reserved for debug
  423. //printf("usb_transmit %d\n", endpoint_number);
  424. if (endpoint_number < 2 || endpoint_number > NUM_ENDPOINTS) return;
  425. endpoint_t *endpoint = &endpoint_queue_head[endpoint_number * 2 + 1];
  426. if (endpoint->callback_function) {
  427. transfer->status |= (1<<15);
  428. } else {
  429. //transfer->status |= (1<<15);
  430. // remove all inactive transfers
  431. }
  432. uint32_t mask = 1 << (endpoint_number + 16);
  433. __disable_irq();
  434. #if 0
  435. if (endpoint->last_transfer) {
  436. if (!(endpoint->last_transfer->status & (1<<7))) {
  437. endpoint->last_transfer->next = (uint32_t)transfer;
  438. } else {
  439. // Case 2: Link list is not empty, page 3182
  440. endpoint->last_transfer->next = (uint32_t)transfer;
  441. if (USB1_ENDPTPRIME & mask) {
  442. endpoint->last_transfer = transfer;
  443. __enable_irq();
  444. printf(" case 2a\n");
  445. return;
  446. }
  447. uint32_t stat;
  448. uint32_t cmd = USB1_USBCMD;
  449. do {
  450. USB1_USBCMD = cmd | USB_USBCMD_ATDTW;
  451. stat = USB1_ENDPTSTATUS;
  452. } while (!(USB1_USBCMD & USB_USBCMD_ATDTW));
  453. USB1_USBCMD = cmd & ~USB_USBCMD_ATDTW;
  454. if (stat & mask) {
  455. endpoint->last_transfer = transfer;
  456. __enable_irq();
  457. printf(" case 2b\n");
  458. return;
  459. }
  460. }
  461. } else {
  462. endpoint->first_transfer = transfer;
  463. }
  464. endpoint->last_transfer = transfer;
  465. #endif
  466. // Case 1: Link list is empty, page 3182
  467. endpoint->next = (uint32_t)transfer;
  468. endpoint->status = 0;
  469. USB1_ENDPTPRIME |= mask;
  470. while (USB1_ENDPTPRIME & mask) ;
  471. __enable_irq();
  472. //printf(" case 1\n");
  473. // ENDPTPRIME - momentarily set by hardware during hardware re-priming
  474. // operations when a dTD is retired, and the dQH is updated.
  475. // ENDPTSTAT - Transmit Buffer Ready - set to one by the hardware as a
  476. // response to receiving a command from a corresponding bit
  477. // in the ENDPTPRIME register. . Buffer ready is cleared by
  478. // USB reset, by the USB DMA system, or through the ENDPTFLUSH
  479. // register. (so 0=buffer ready, 1=buffer primed for transmit)
  480. }
  481. /*struct endpoint_struct {
  482. uint32_t config;
  483. uint32_t current;
  484. uint32_t next;
  485. uint32_t status;
  486. uint32_t pointer0;
  487. uint32_t pointer1;
  488. uint32_t pointer2;
  489. uint32_t pointer3;
  490. uint32_t pointer4;
  491. uint32_t reserved;
  492. uint32_t setup0;
  493. uint32_t setup1;
  494. transfer_t *first_transfer;
  495. transfer_t *last_transfer;
  496. void (*callback_function)(transfer_t *completed_transfer);
  497. uint32_t unused1;
  498. };*/