Teensy 4.1 core updated for C++20
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

usb.c 26KB

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