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.

770 lines
22KB

  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. static void run_callbacks(endpoint_t *ep);
  73. __attribute__((section(".progmem")))
  74. void usb_init(void)
  75. {
  76. // TODO: only enable when VBUS detected
  77. // TODO: return to low power mode when VBUS removed
  78. // TODO: protect PMU access with MPU
  79. PMU_REG_3P0 = PMU_REG_3P0_OUTPUT_TRG(0x0F) | PMU_REG_3P0_BO_OFFSET(6)
  80. | PMU_REG_3P0_ENABLE_LINREG;
  81. usb_init_serialnumber();
  82. // assume PLL3 is already running - already done by usb_pll_start() in main.c
  83. CCM_CCGR6 |= CCM_CCGR6_USBOH3(CCM_CCGR_ON); // turn on clocks to USB peripheral
  84. // Before programming this register, the PHY clocks must be enabled in registers
  85. // USBPHYx_CTRLn and CCM_ANALOG_USBPHYx_PLL_480_CTRLn.
  86. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  87. //printf("USBPHY1_TX=%08lX\n", USBPHY1_TX);
  88. //printf("USBPHY1_RX=%08lX\n", USBPHY1_RX);
  89. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  90. //printf("USB1_USBMODE=%08lX\n", USB1_USBMODE);
  91. // turn on PLL3, wait for 480 MHz lock?
  92. // turn on CCM clock gates? CCGR6[CG0]
  93. #if 1
  94. if ((USBPHY1_PWD & (USBPHY_PWD_RXPWDRX | USBPHY_PWD_RXPWDDIFF | USBPHY_PWD_RXPWD1PT1
  95. | USBPHY_PWD_RXPWDENV | USBPHY_PWD_TXPWDV2I | USBPHY_PWD_TXPWDIBIAS
  96. | USBPHY_PWD_TXPWDFS)) || (USB1_USBMODE & USB_USBMODE_CM_MASK)) {
  97. // USB controller is turned on from previous use
  98. // reset needed to turn it off & start from clean slate
  99. USBPHY1_CTRL_SET = USBPHY_CTRL_SFTRST; // USBPHY1_CTRL page 3292
  100. USB1_USBCMD |= USB_USBCMD_RST; // reset controller
  101. int count=0;
  102. while (USB1_USBCMD & USB_USBCMD_RST) count++;
  103. NVIC_CLEAR_PENDING(IRQ_USB1);
  104. USBPHY1_CTRL_CLR = USBPHY_CTRL_SFTRST; // reset PHY
  105. //USB1_USBSTS = USB1_USBSTS; // TODO: is this needed?
  106. printf("USB reset took %d loops\n", count);
  107. //delay(10);
  108. //printf("\n");
  109. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  110. //printf("USBPHY1_TX=%08lX\n", USBPHY1_TX);
  111. //printf("USBPHY1_RX=%08lX\n", USBPHY1_RX);
  112. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  113. //printf("USB1_USBMODE=%08lX\n", USB1_USBMODE);
  114. delay(25);
  115. }
  116. #endif
  117. // Device Controller Initialization, page 3161
  118. // USBCMD pg 3216
  119. // USBSTS pg 3220
  120. // USBINTR pg 3224
  121. // DEVICEADDR pg 3227
  122. // ENDPTLISTADDR 3229
  123. // USBMODE pg 3244
  124. // ENDPTSETUPSTAT 3245
  125. // ENDPTPRIME pg 3246
  126. // ENDPTFLUSH pg 3247
  127. // ENDPTSTAT pg 3247
  128. // ENDPTCOMPLETE 3248
  129. // ENDPTCTRL0 pg 3249
  130. USBPHY1_CTRL_CLR = USBPHY_CTRL_CLKGATE;
  131. USBPHY1_PWD = 0;
  132. //printf("USBPHY1_PWD=%08lX\n", USBPHY1_PWD);
  133. //printf("USBPHY1_CTRL=%08lX\n", USBPHY1_CTRL);
  134. USB1_USBMODE = USB_USBMODE_CM(2) | USB_USBMODE_SLOM;
  135. memset(endpoint_queue_head, 0, sizeof(endpoint_queue_head));
  136. endpoint_queue_head[0].config = (64 << 16) | (1 << 15);
  137. endpoint_queue_head[1].config = (64 << 16);
  138. USB1_ENDPOINTLISTADDR = (uint32_t)&endpoint_queue_head;
  139. // Recommended: enable all device interrupts including: USBINT, USBERRINT,
  140. // Port Change Detect, USB Reset Received, DCSuspend.
  141. USB1_USBINTR = USB_USBINTR_UE | USB_USBINTR_UEE | /* USB_USBINTR_PCE | */
  142. USB_USBINTR_URE | USB_USBINTR_SLE;
  143. //_VectorsRam[IRQ_USB1+16] = &isr;
  144. attachInterruptVector(IRQ_USB1, &isr);
  145. NVIC_ENABLE_IRQ(IRQ_USB1);
  146. //printf("USB1_ENDPTCTRL0=%08lX\n", USB1_ENDPTCTRL0);
  147. //printf("USB1_ENDPTCTRL1=%08lX\n", USB1_ENDPTCTRL1);
  148. //printf("USB1_ENDPTCTRL2=%08lX\n", USB1_ENDPTCTRL2);
  149. //printf("USB1_ENDPTCTRL3=%08lX\n", USB1_ENDPTCTRL3);
  150. USB1_USBCMD |= USB_USBCMD_RS;
  151. }
  152. static void isr(void)
  153. {
  154. //printf("*");
  155. // Port control in device mode is only used for
  156. // status port reset, suspend, and current connect status.
  157. uint32_t status = USB1_USBSTS;
  158. USB1_USBSTS = status;
  159. // USB_USBSTS_SLI - set to 1 when enters a suspend state from an active state
  160. // USB_USBSTS_SRI - set at start of frame
  161. // USB_USBSTS_SRI - set when USB reset detected
  162. if (status & USB_USBSTS_UI) {
  163. //printf("data\n");
  164. uint32_t setupstatus = USB1_ENDPTSETUPSTAT;
  165. //printf("USB1_ENDPTSETUPSTAT=%X\n", setupstatus);
  166. while (setupstatus) {
  167. USB1_ENDPTSETUPSTAT = setupstatus;
  168. setup_t s;
  169. do {
  170. USB1_USBCMD |= USB_USBCMD_SUTW;
  171. s.word1 = endpoint_queue_head[0].setup0;
  172. s.word2 = endpoint_queue_head[0].setup1;
  173. } while (!(USB1_USBCMD & USB_USBCMD_SUTW));
  174. USB1_USBCMD &= ~USB_USBCMD_SUTW;
  175. //printf("setup %08lX %08lX\n", s.word1, s.word2);
  176. USB1_ENDPTFLUSH = (1<<16) | (1<<0); // page 3174
  177. while (USB1_ENDPTFLUSH & ((1<<16) | (1<<0))) ;
  178. endpoint0_notify_mask = 0;
  179. endpoint0_setup(s.bothwords);
  180. setupstatus = USB1_ENDPTSETUPSTAT; // page 3175
  181. }
  182. uint32_t completestatus = USB1_ENDPTCOMPLETE;
  183. if (completestatus) {
  184. USB1_ENDPTCOMPLETE = completestatus;
  185. //printf("USB1_ENDPTCOMPLETE=%lX\n", completestatus);
  186. if (completestatus & endpoint0_notify_mask) {
  187. endpoint0_notify_mask = 0;
  188. endpoint0_complete();
  189. }
  190. completestatus &= endpointN_notify_mask;
  191. if (completestatus) {
  192. int i; // TODO: optimize with __builtin_ctz()
  193. for (i=2; i < NUM_ENDPOINTS; i++) {
  194. if (completestatus & (1 << i)) { // receive
  195. run_callbacks(endpoint_queue_head + i * 2);
  196. }
  197. if (completestatus & (1 << (i + 16))) { // transmit
  198. run_callbacks(endpoint_queue_head + i * 2 + 1);
  199. }
  200. }
  201. }
  202. }
  203. }
  204. if (status & USB_USBSTS_URI) { // page 3164
  205. USB1_ENDPTSETUPSTAT = USB1_ENDPTSETUPSTAT; // Clear all setup token semaphores
  206. USB1_ENDPTCOMPLETE = USB1_ENDPTCOMPLETE; // Clear all the endpoint complete status
  207. while (USB1_ENDPTPRIME != 0) ; // Wait for any endpoint priming
  208. USB1_ENDPTFLUSH = 0xFFFFFFFF; // Cancel all endpoint primed status
  209. if ((USB1_PORTSC1 & USB_PORTSC1_PR)) {
  210. //printf("reset\n");
  211. } else {
  212. // we took too long to respond :(
  213. // TODO; is this ever really a problem?
  214. //printf("reset too slow\n");
  215. }
  216. #if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE)
  217. usb_serial_reset();
  218. #endif
  219. endpointN_notify_mask = 0;
  220. // TODO: Free all allocated dTDs
  221. //if (++reset_count >= 3) {
  222. // shut off USB - easier to see results in protocol analyzer
  223. //USB1_USBCMD &= ~USB_USBCMD_RS;
  224. //printf("shut off USB\n");
  225. //}
  226. }
  227. if (status & USB_USBSTS_PCI) {
  228. if (USB1_PORTSC1 & USB_PORTSC1_HSP) {
  229. //printf("port at 480 Mbit\n");
  230. } else {
  231. //printf("port at 12 Mbit\n");
  232. }
  233. }
  234. if (status & USB_USBSTS_SLI) { // page 3165
  235. //printf("suspend\n");
  236. }
  237. if (status & USB_USBSTS_UEI) {
  238. //printf("error\n");
  239. }
  240. if ((USB1_USBINTR & USB_USBINTR_SRE) && (status & USB_USBSTS_SRI)) {
  241. printf("sof %d\n", usb_reboot_timer);
  242. if (usb_reboot_timer) {
  243. if (--usb_reboot_timer == 0) {
  244. asm("bkpt #251"); // run bootloader
  245. }
  246. } else {
  247. // turn off the SOF interrupt if nothing using it
  248. USB1_USBINTR &= ~USB_USBINTR_SRE;
  249. }
  250. }
  251. }
  252. /*
  253. struct transfer_struct { // table 55-60, pg 3159
  254. uint32_t next;
  255. uint32_t status;
  256. uint32_t pointer0;
  257. uint32_t pointer1;
  258. uint32_t pointer2;
  259. uint32_t pointer3;
  260. uint32_t pointer4;
  261. uint32_t unused1;
  262. };
  263. transfer_t endpoint0_transfer_data __attribute__ ((aligned(32)));;
  264. transfer_t endpoint0_transfer_ack __attribute__ ((aligned(32)));;
  265. */
  266. static void endpoint0_setup(uint64_t setupdata)
  267. {
  268. setup_t setup;
  269. uint32_t datalen = 0;
  270. const usb_descriptor_list_t *list;
  271. setup.bothwords = setupdata;
  272. switch (setup.wRequestAndType) {
  273. case 0x0500: // SET_ADDRESS
  274. endpoint0_receive(NULL, 0, 0);
  275. USB1_DEVICEADDR = USB_DEVICEADDR_USBADR(setup.wValue) | USB_DEVICEADDR_USBADRA;
  276. return;
  277. case 0x0900: // SET_CONFIGURATION
  278. usb_configuration = setup.wValue;
  279. // configure all other endpoints
  280. #if 0
  281. volatile uint32_t *reg = &USB1_ENDPTCTRL1;
  282. const uint32_t *cfg = usb_endpoint_config_table;
  283. int i;
  284. for (i=0; i < NUM_ENDPOINTS; i++) {
  285. uint32_t n = *cfg++;
  286. *reg = n;
  287. // TODO: do the TRX & RXR bits self clear??
  288. uint32_t m = n & ~(USB_ENDPTCTRL_TXR | USB_ENDPTCTRL_RXR);
  289. *reg = m;
  290. //uint32_t p = *reg;
  291. //printf(" ep=%d: cfg=%08lX - %08lX - %08lX\n", i + 1, n, m, p);
  292. reg++;
  293. }
  294. #else
  295. #if defined(ENDPOINT2_CONFIG)
  296. USB1_ENDPTCTRL2 = ENDPOINT2_CONFIG;
  297. #endif
  298. #if defined(ENDPOINT3_CONFIG)
  299. USB1_ENDPTCTRL3 = ENDPOINT3_CONFIG;
  300. #endif
  301. #if defined(ENDPOINT4_CONFIG)
  302. USB1_ENDPTCTRL4 = ENDPOINT4_CONFIG;
  303. #endif
  304. #if defined(ENDPOINT5_CONFIG)
  305. USB1_ENDPTCTRL5 = ENDPOINT5_CONFIG;
  306. #endif
  307. #if defined(ENDPOINT6_CONFIG)
  308. USB1_ENDPTCTRL6 = ENDPOINT6_CONFIG;
  309. #endif
  310. #if defined(ENDPOINT7_CONFIG)
  311. USB1_ENDPTCTRL7 = ENDPOINT7_CONFIG;
  312. #endif
  313. #endif
  314. #if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE)
  315. usb_serial_configure();
  316. #endif
  317. endpoint0_receive(NULL, 0, 0);
  318. return;
  319. case 0x0680: // GET_DESCRIPTOR
  320. case 0x0681:
  321. //printf("desc:\n"); // yay - sending device descriptor now works!!!!
  322. for (list = usb_descriptor_list; list->addr != NULL; list++) {
  323. if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
  324. if ((setup.wValue >> 8) == 3) {
  325. // for string descriptors, use the descriptor's
  326. // length field, allowing runtime configured length.
  327. datalen = *(list->addr);
  328. } else {
  329. datalen = list->length;
  330. }
  331. if (datalen > setup.wLength) datalen = setup.wLength;
  332. endpoint0_transmit(list->addr, datalen, 0);
  333. return;
  334. }
  335. }
  336. break;
  337. case 0x2221: // CDC_SET_CONTROL_LINE_STATE
  338. usb_cdc_line_rtsdtr_millis = systick_millis_count;
  339. usb_cdc_line_rtsdtr = setup.wValue;
  340. case 0x2321: // CDC_SEND_BREAK
  341. endpoint0_receive(NULL, 0, 0);
  342. return;
  343. case 0x2021: // CDC_SET_LINE_CODING
  344. if (setup.wLength != 7) break;
  345. endpoint0_setupdata.bothwords = setupdata;
  346. endpoint0_receive(endpoint0_buffer, 7, 1);
  347. return;
  348. }
  349. USB1_ENDPTCTRL0 = 0x000010001; // stall
  350. }
  351. static void endpoint0_transmit(const void *data, uint32_t len, int notify)
  352. {
  353. //printf("tx %lu\n", len);
  354. if (len > 0) {
  355. // Executing A Transfer Descriptor, page 3182
  356. endpoint0_transfer_data.next = 1;
  357. endpoint0_transfer_data.status = (len << 16) | (1<<7);
  358. uint32_t addr = (uint32_t)data;
  359. endpoint0_transfer_data.pointer0 = addr; // format: table 55-60, pg 3159
  360. endpoint0_transfer_data.pointer1 = addr + 4096;
  361. endpoint0_transfer_data.pointer2 = addr + 8192;
  362. endpoint0_transfer_data.pointer3 = addr + 12288;
  363. endpoint0_transfer_data.pointer4 = addr + 16384;
  364. // Case 1: Link list is empty, page 3182
  365. endpoint_queue_head[1].next = (uint32_t)&endpoint0_transfer_data;
  366. endpoint_queue_head[1].status = 0;
  367. USB1_ENDPTPRIME |= (1<<16);
  368. while (USB1_ENDPTPRIME) ;
  369. }
  370. endpoint0_transfer_ack.next = 1;
  371. endpoint0_transfer_ack.status = (1<<7) | (notify ? (1 << 15) : 0);
  372. endpoint0_transfer_ack.pointer0 = 0;
  373. endpoint_queue_head[0].next = (uint32_t)&endpoint0_transfer_ack;
  374. endpoint_queue_head[0].status = 0;
  375. USB1_ENDPTPRIME |= (1<<0);
  376. endpoint0_notify_mask = (notify ? (1 << 0) : 0);
  377. while (USB1_ENDPTPRIME) ;
  378. }
  379. static void endpoint0_receive(void *data, uint32_t len, int notify)
  380. {
  381. //printf("rx %lu\n", len);
  382. if (len > 0) {
  383. // Executing A Transfer Descriptor, page 3182
  384. endpoint0_transfer_data.next = 1;
  385. endpoint0_transfer_data.status = (len << 16) | (1<<7);
  386. uint32_t addr = (uint32_t)data;
  387. endpoint0_transfer_data.pointer0 = addr; // format: table 55-60, pg 3159
  388. endpoint0_transfer_data.pointer1 = addr + 4096;
  389. endpoint0_transfer_data.pointer2 = addr + 8192;
  390. endpoint0_transfer_data.pointer3 = addr + 12288;
  391. endpoint0_transfer_data.pointer4 = addr + 16384;
  392. // Case 1: Link list is empty, page 3182
  393. endpoint_queue_head[0].next = (uint32_t)&endpoint0_transfer_data;
  394. endpoint_queue_head[0].status = 0;
  395. USB1_ENDPTPRIME |= (1<<0);
  396. while (USB1_ENDPTPRIME) ;
  397. }
  398. endpoint0_transfer_ack.next = 1;
  399. endpoint0_transfer_ack.status = (1<<7) | (notify ? (1 << 15) : 0);
  400. endpoint0_transfer_ack.pointer0 = 0;
  401. endpoint_queue_head[1].next = (uint32_t)&endpoint0_transfer_ack;
  402. endpoint_queue_head[1].status = 0;
  403. USB1_ENDPTPRIME |= (1<<16);
  404. endpoint0_notify_mask = (notify ? (1 << 16) : 0);
  405. while (USB1_ENDPTPRIME) ;
  406. }
  407. /*typedef union {
  408. struct {
  409. union {
  410. struct {
  411. uint8_t bmRequestType;
  412. uint8_t bRequest;
  413. };
  414. uint16_t wRequestAndType;
  415. };
  416. uint16_t wValue;
  417. uint16_t wIndex;
  418. uint16_t wLength;
  419. };
  420. struct {
  421. uint32_t word1;
  422. uint32_t word2;
  423. };
  424. uint64_t bothwords;
  425. } setup_t; */
  426. static void endpoint0_complete(void)
  427. {
  428. setup_t setup;
  429. setup.bothwords = endpoint0_setupdata.bothwords;
  430. //printf("complete\n");
  431. #ifdef CDC_STATUS_INTERFACE
  432. if (setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/) {
  433. memcpy(usb_cdc_line_coding, endpoint0_buffer, 7);
  434. printf("usb_cdc_line_coding, baud=%u\n", usb_cdc_line_coding[0]);
  435. if (usb_cdc_line_coding[0] == 134) {
  436. USB1_USBINTR |= USB_USBINTR_SRE;
  437. usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
  438. }
  439. }
  440. #endif
  441. }
  442. static void usb_endpoint_config(endpoint_t *qh, uint32_t config, void (*callback)(transfer_t *))
  443. {
  444. memset(qh, 0, sizeof(endpoint_t));
  445. qh->config = config;
  446. qh->next = 1; // Terminate bit = 1
  447. qh->callback_function = callback;
  448. }
  449. void usb_config_rx(uint32_t ep, uint32_t packet_size, int do_zlp, void (*cb)(transfer_t *))
  450. {
  451. uint32_t config = (packet_size << 16) | (do_zlp ? 0 : (1 << 29));
  452. if (ep < 2 || ep > NUM_ENDPOINTS) return;
  453. usb_endpoint_config(endpoint_queue_head + ep * 2, config, cb);
  454. if (cb) endpointN_notify_mask |= (1 << ep);
  455. }
  456. void usb_config_tx(uint32_t ep, uint32_t packet_size, int do_zlp, void (*cb)(transfer_t *))
  457. {
  458. uint32_t config = (packet_size << 16) | (do_zlp ? 0 : (1 << 29));
  459. if (ep < 2 || ep > NUM_ENDPOINTS) return;
  460. usb_endpoint_config(endpoint_queue_head + ep * 2 + 1, config, cb);
  461. if (cb) endpointN_notify_mask |= (1 << (ep + 16));
  462. }
  463. void usb_prepare_transfer(transfer_t *transfer, const void *data, uint32_t len, uint32_t param)
  464. {
  465. transfer->next = 1;
  466. transfer->status = (len << 16) | (1<<7);
  467. uint32_t addr = (uint32_t)data;
  468. transfer->pointer0 = addr;
  469. transfer->pointer1 = addr + 4096;
  470. transfer->pointer2 = addr + 8192;
  471. transfer->pointer3 = addr + 12288;
  472. transfer->pointer4 = addr + 16384;
  473. transfer->callback_param = param;
  474. }
  475. static uint32_t get_endptstatus(void)
  476. {
  477. uint32_t status, cmd;
  478. cmd = USB1_USBCMD;
  479. do {
  480. USB1_USBCMD = cmd | USB_USBCMD_ATDTW;
  481. status = USB1_ENDPTSTATUS;
  482. } while (!(USB1_USBCMD & USB_USBCMD_ATDTW));
  483. return status;
  484. }
  485. static void schedule_transfer(endpoint_t *endpoint, uint32_t epmask, transfer_t *transfer)
  486. {
  487. transfer_t *last, *next;
  488. // 41.5.6.6.3 Executing A Transfer Descriptor, page 2468 (RT1060 manual, Rev 1, 12/2018)
  489. if (endpoint->callback_function) {
  490. // endpoint uses interrupts and maintains linked list of all transfers
  491. transfer->status |= (1<<15);
  492. last = endpoint->last_transfer;
  493. } else {
  494. // endpoint has no callback, no list of transfers
  495. //if ((USB1_ENDPTPRIME & epmask) || (get_endptstatus() & epmask)) {
  496. last = (transfer_t *)(endpoint->next & ~0x1F);
  497. if (last) {
  498. while (1) {
  499. next = (transfer_t *)(last->next & ~0x1F);
  500. if (!next) break;
  501. last = next;
  502. }
  503. }
  504. //} else {
  505. //last = NULL;
  506. //}
  507. }
  508. if (last) {
  509. last->next = transfer;
  510. if ((USB1_ENDPTPRIME & epmask) || (get_endptstatus() & epmask)) {
  511. endpoint->last_transfer = transfer;
  512. __enable_irq();
  513. return;
  514. }
  515. }
  516. endpoint->next = (uint32_t)transfer;
  517. endpoint->status = 0;
  518. endpoint->first_transfer = transfer;
  519. endpoint->last_transfer = transfer;
  520. USB1_ENDPTPRIME |= epmask;
  521. __enable_irq();
  522. // ENDPTPRIME - Software should write a one to the corresponding bit when
  523. // posting a new transfer descriptor to an endpoint queue head.
  524. // Hardware automatically uses this bit to begin parsing for a
  525. // new transfer descriptor from the queue head and prepare a
  526. // transmit buffer. Hardware clears this bit when the associated
  527. // endpoint(s) is (are) successfully primed.
  528. // Momentarily set by hardware during hardware re-priming
  529. // operations when a dTD is retired, and the dQH is updated.
  530. // ENDPTSTATUS - Transmit Buffer Ready - set to one by the hardware as a
  531. // response to receiving a command from a corresponding bit
  532. // in the ENDPTPRIME register. . Buffer ready is cleared by
  533. // USB reset, by the USB DMA system, or through the ENDPTFLUSH
  534. // register. (so 0=buffer ready, 1=buffer primed for transmit)
  535. // USBCMD.ATDTW - This bit is used as a semaphore to ensure proper addition
  536. // of a new dTD to an active (primed) endpoint's linked list.
  537. // This bit is set and cleared by software.
  538. // This bit would also be cleared by hardware when state machine
  539. // is hazard region for which adding a dTD to a primed endpoint
  540. // may go unrecognized.
  541. }
  542. static void run_callbacks(endpoint_t *ep)
  543. {
  544. transfer_t *t, *next;
  545. printf("run_callbacks\n");
  546. t = ep->first_transfer;
  547. while (t && (uint32_t)t != 1) {
  548. if (!(t->status & (1<<7))) {
  549. // transfer not active anymore
  550. next = (transfer_t *)t->next;
  551. ep->callback_function(t);
  552. } else {
  553. // transfer still active
  554. ep->first_transfer = t;
  555. return;
  556. }
  557. t = next;
  558. }
  559. // all transfers completed
  560. ep->first_transfer = NULL;
  561. ep->last_transfer = NULL;
  562. }
  563. void usb_transmit(int endpoint_number, transfer_t *transfer)
  564. {
  565. if (endpoint_number < 2 || endpoint_number > NUM_ENDPOINTS) return;
  566. endpoint_t *endpoint = endpoint_queue_head + endpoint_number * 2 + 1;
  567. uint32_t mask = 1 << (endpoint_number + 16);
  568. schedule_transfer(endpoint, mask, transfer);
  569. }
  570. void usb_receive(int endpoint_number, transfer_t *transfer)
  571. {
  572. if (endpoint_number < 2 || endpoint_number > NUM_ENDPOINTS) return;
  573. endpoint_t *endpoint = endpoint_queue_head + endpoint_number * 2;
  574. uint32_t mask = 1 << endpoint_number;
  575. schedule_transfer(endpoint, mask, transfer);
  576. }
  577. uint32_t usb_transfer_status(const transfer_t *transfer)
  578. {
  579. uint32_t status, cmd;
  580. //uint32_t count=0;
  581. cmd = USB1_USBCMD;
  582. do {
  583. //count++;
  584. USB1_USBCMD = cmd | USB_USBCMD_ATDTW;
  585. status = transfer->status;
  586. cmd = USB1_USBCMD;
  587. } while (!(cmd & USB_USBCMD_ATDTW));
  588. //if (count > 1) printf("s=%08X, count=%d\n", status, count);
  589. //printf("s=%08X, count=%d\n", status, count);
  590. return status;
  591. }
  592. #if 0
  593. void usb_transmit(int endpoint_number, transfer_t *transfer)
  594. {
  595. // endpoint 0 reserved for control
  596. // endpoint 1 reserved for debug
  597. //printf("usb_transmit %d\n", endpoint_number);
  598. if (endpoint_number < 2 || endpoint_number > NUM_ENDPOINTS) return;
  599. endpoint_t *endpoint = &endpoint_queue_head[endpoint_number * 2 + 1];
  600. if (endpoint->callback_function) {
  601. transfer->status |= (1<<15);
  602. } else {
  603. //transfer->status |= (1<<15);
  604. // remove all inactive transfers
  605. }
  606. uint32_t mask = 1 << (endpoint_number + 16);
  607. __disable_irq();
  608. #if 0
  609. if (endpoint->last_transfer) {
  610. if (!(endpoint->last_transfer->status & (1<<7))) {
  611. endpoint->last_transfer->next = (uint32_t)transfer;
  612. } else {
  613. // Case 2: Link list is not empty, page 3182
  614. endpoint->last_transfer->next = (uint32_t)transfer;
  615. if (USB1_ENDPTPRIME & mask) {
  616. endpoint->last_transfer = transfer;
  617. __enable_irq();
  618. printf(" case 2a\n");
  619. return;
  620. }
  621. uint32_t stat;
  622. uint32_t cmd = USB1_USBCMD;
  623. do {
  624. USB1_USBCMD = cmd | USB_USBCMD_ATDTW;
  625. stat = USB1_ENDPTSTATUS;
  626. } while (!(USB1_USBCMD & USB_USBCMD_ATDTW));
  627. USB1_USBCMD = cmd & ~USB_USBCMD_ATDTW;
  628. if (stat & mask) {
  629. endpoint->last_transfer = transfer;
  630. __enable_irq();
  631. printf(" case 2b\n");
  632. return;
  633. }
  634. }
  635. } else {
  636. endpoint->first_transfer = transfer;
  637. }
  638. endpoint->last_transfer = transfer;
  639. #endif
  640. // Case 1: Link list is empty, page 3182
  641. endpoint->next = (uint32_t)transfer;
  642. endpoint->status = 0;
  643. USB1_ENDPTPRIME |= mask;
  644. while (USB1_ENDPTPRIME & mask) ;
  645. __enable_irq();
  646. //printf(" case 1\n");
  647. // ENDPTPRIME - momentarily set by hardware during hardware re-priming
  648. // operations when a dTD is retired, and the dQH is updated.
  649. // ENDPTSTAT - Transmit Buffer Ready - set to one by the hardware as a
  650. // response to receiving a command from a corresponding bit
  651. // in the ENDPTPRIME register. . Buffer ready is cleared by
  652. // USB reset, by the USB DMA system, or through the ENDPTFLUSH
  653. // register. (so 0=buffer ready, 1=buffer primed for transmit)
  654. }
  655. #endif
  656. /*struct endpoint_struct {
  657. uint32_t config;
  658. uint32_t current;
  659. uint32_t next;
  660. uint32_t status;
  661. uint32_t pointer0;
  662. uint32_t pointer1;
  663. uint32_t pointer2;
  664. uint32_t pointer3;
  665. uint32_t pointer4;
  666. uint32_t reserved;
  667. uint32_t setup0;
  668. uint32_t setup1;
  669. transfer_t *first_transfer;
  670. transfer_t *last_transfer;
  671. void (*callback_function)(transfer_t *completed_transfer);
  672. uint32_t unused1;
  673. };*/