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.

usb.c 16KB

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