Teensy 4.1 core updated for C++20
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

772 lines
23KB

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