Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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