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.

797 lines
24KB

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