You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 line
5.8KB

  1. // usb host experiments....
  2. uint32_t periodictable[64] __attribute__ ((aligned(4096)));
  3. uint32_t qh[12] __attribute__ ((aligned(64)));
  4. uint32_t qtd_setup[8] __attribute__ ((aligned(32)));
  5. uint32_t qtd_in[8] __attribute__ ((aligned(32)));
  6. uint32_t qtd_outack[8] __attribute__ ((aligned(32)));
  7. void setup()
  8. {
  9. pinMode(32, OUTPUT); // pin 32 = USB switch, high=connect device
  10. digitalWrite(32, LOW);
  11. while (!Serial) ; // wait
  12. print("USB Host Testing");
  13. //MPU_RGDAAC0 |= 0x30000000;
  14. MPU_RGDAAC0 |= 0xF0000000;
  15. MCG_C1 |= MCG_C1_IRCLKEN; // enable MCGIRCLK 32kHz
  16. OSC0_CR |= OSC_ERCLKEN;
  17. SIM_SOPT2 |= SIM_SOPT2_USBREGEN; // turn on USB regulator
  18. SIM_SOPT2 &= ~SIM_SOPT2_USBSLSRC; // use IRC for slow clock
  19. print("power up USBHS PHY");
  20. SIM_USBPHYCTL |= SIM_USBPHYCTL_USBDISILIM; // disable USB current limit
  21. //SIM_USBPHYCTL = SIM_USBPHYCTL_USBDISILIM | SIM_USBPHYCTL_USB3VOUTTRG(6); // pg 237
  22. SIM_SCGC3 |= SIM_SCGC3_USBHSDCD | SIM_SCGC3_USBHSPHY | SIM_SCGC3_USBHS;
  23. USBHSDCD_CLOCK = 33 << 2;
  24. print("init USBHS PHY & PLL");
  25. // init process: page 1681-1682
  26. USBPHY_CTRL_CLR = (USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE); // // CTRL pg 1698
  27. USBPHY_TRIM_OVERRIDE_EN_SET = 1;
  28. USBPHY_PLL_SIC = USBPHY_PLL_SIC_PLL_POWER | USBPHY_PLL_SIC_PLL_ENABLE |
  29. USBPHY_PLL_SIC_PLL_DIV_SEL(1) | USBPHY_PLL_SIC_PLL_EN_USB_CLKS;
  30. // wait for the PLL to lock
  31. int count=0;
  32. while ((USBPHY_PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK) == 0) {
  33. count++;
  34. }
  35. print("PLL locked, waited ", count);
  36. // turn on power to PHY
  37. USBPHY_PWD = 0;
  38. delay(10);
  39. // sanity check, connect 470K pullup & 100K pulldown and watch D+ voltage change
  40. //USBPHY_ANACTRL_CLR = (1<<10); // turn off both 15K pulldowns... works! :)
  41. // sanity check, output clocks on pin 9 for testing
  42. //SIM_SOPT2 = SIM_SOPT2 & (~SIM_SOPT2_CLKOUTSEL(7)) | SIM_SOPT2_CLKOUTSEL(3); // LPO 1kHz
  43. //SIM_SOPT2 = SIM_SOPT2 & (~SIM_SOPT2_CLKOUTSEL(7)) | SIM_SOPT2_CLKOUTSEL(2); // Flash
  44. //SIM_SOPT2 = SIM_SOPT2 & (~SIM_SOPT2_CLKOUTSEL(7)) | SIM_SOPT2_CLKOUTSEL(6); // XTAL
  45. //SIM_SOPT2 = SIM_SOPT2 & (~SIM_SOPT2_CLKOUTSEL(7)) | SIM_SOPT2_CLKOUTSEL(7); // IRC 48MHz
  46. //SIM_SOPT2 = SIM_SOPT2 & (~SIM_SOPT2_CLKOUTSEL(7)) | SIM_SOPT2_CLKOUTSEL(4); // MCGIRCLK
  47. //CORE_PIN9_CONFIG = PORT_PCR_MUX(5); // CLKOUT on PTC3 Alt5 (Arduino pin 9)
  48. // EHCI registers page default
  49. // -------------- ---- -------
  50. // USBHS_USBCMD 1599 00080000
  51. // USBHS_USBSTS 1602 00000000
  52. // USBHS_USBINTR 1606 00000000
  53. // USBHS_FRINDEX 1609 00000000
  54. // USBHS_PERIODICLISTBASE 1610 undefine
  55. // USBHS_ASYNCLISTADDR 1612 undefine
  56. // USBHS_PORTSC 1619 00002000
  57. // USBHS_USBMODE 1629 00005000
  58. print("begin ehci reset");
  59. USBHS_USBCMD |= USBHS_USBCMD_RST;
  60. count = 0;
  61. while (USBHS_USBCMD & USBHS_USBCMD_RST) {
  62. count;
  63. }
  64. print(" reset waited ", count);
  65. for (int i=0; i < 64; i++) {
  66. //periodictable[i] = (void *)1;
  67. periodictable[i] = 1;
  68. }
  69. qh[0] = ((uint32_t)qh) | 2;
  70. qh[1] = 0x0040E000; // addr=0, ep=0
  71. qh[2] = 0x40000000;
  72. qh[3] = 0;
  73. qh[4] = 1;
  74. qh[5] = 0;
  75. qh[6] = 0;
  76. qh[7] = 0;
  77. qh[8] = 0;
  78. qh[9] = 0;
  79. qh[10] = 0;
  80. qh[11] = 0;
  81. USBHS_USBINTR = 0;
  82. USBHS_PERIODICLISTBASE = (uint32_t)periodictable;
  83. USBHS_FRINDEX = 0;
  84. USBHS_ASYNCLISTADDR = (uint32_t)qh;
  85. // turn on the USBHS controller
  86. USBHS_USBMODE = USBHS_USBMODE_TXHSD(5) | USBHS_USBMODE_CM(3); // host mode
  87. USBHS_USBCMD = USBHS_USBCMD_ITC(0) | USBHS_USBCMD_RS | USBHS_USBCMD_ASP(3) |
  88. USBHS_USBCMD_FS2 | USBHS_USBCMD_FS(0) | // periodic table is 64 pointers
  89. 0;
  90. //USBHS_USBCMD_ASE; // TODO: halts with error, but why?
  91. //USBHS_USBCMD_PSE | USBHS_USBCMD_ASE; // TODO: halts with error, but why?
  92. USBHS_PORTSC1 |= USBHS_PORTSC_PP;
  93. //USBHS_PORTSC1 |= USBHS_PORTSC_PFSC; // force 12 Mbit/sec
  94. //USBHS_PORTSC1 |= USBHS_PORTSC_PHCD; // phy off
  95. }
  96. void port_status()
  97. {
  98. uint32_t n;
  99. Serial.print("Port: ");
  100. n = USBHS_PORTSC1;
  101. if (n & USBHS_PORTSC_PR) {
  102. Serial.print("reset ");
  103. }
  104. if (n & USBHS_PORTSC_PP) {
  105. Serial.print("on ");
  106. } else {
  107. Serial.print("off ");
  108. }
  109. if (n & USBHS_PORTSC_PHCD) {
  110. Serial.print("phyoff ");
  111. }
  112. if (n & USBHS_PORTSC_PE) {
  113. if (n & USBHS_PORTSC_SUSP) {
  114. Serial.print("suspend ");
  115. } else {
  116. Serial.print("enable ");
  117. }
  118. } else {
  119. Serial.print("disable ");
  120. }
  121. Serial.print("speed=");
  122. switch ((n >> 26) & 3) {
  123. case 0: Serial.print("12 Mbps "); break;
  124. case 1: Serial.print("1.5 Mbps "); break;
  125. case 2: Serial.print("480 Mbps "); break;
  126. default: Serial.print("(undef) ");
  127. }
  128. if (n & USBHS_PORTSC_HSP) {
  129. Serial.print("highspeed ");
  130. }
  131. if (n & USBHS_PORTSC_OCA) {
  132. Serial.print("overcurrent ");
  133. }
  134. if (n & USBHS_PORTSC_CCS) {
  135. Serial.print("connected ");
  136. } else {
  137. Serial.print("not-connected ");
  138. }
  139. // print info about the EHCI status
  140. Serial.print(" run=");
  141. Serial.print(USBHS_USBCMD & 1); // running mode
  142. Serial.print(",halt=");
  143. Serial.print((USBHS_USBSTS >> 12) & 1); // halted mode
  144. Serial.print(",err=");
  145. Serial.print((USBHS_USBSTS >> 4) & 1); // error encountered!
  146. Serial.print(",asyn=");
  147. Serial.print((USBHS_USBSTS >> 15) & 1); // running the async schedule
  148. Serial.print(",per=");
  149. Serial.print((USBHS_USBSTS >> 14) & 1); // running the periodic schedule
  150. Serial.print(",index=");
  151. Serial.print(USBHS_FRINDEX); // periodic index
  152. Serial.println();
  153. }
  154. void loop()
  155. {
  156. static unsigned int count=0;
  157. port_status();
  158. delay(1);
  159. count++;
  160. if (count == 2) {
  161. Serial.println("Plug in device...");
  162. digitalWrite(32, HIGH); // connect device
  163. }
  164. if (count == 5) {
  165. Serial.println("Initiate Reset Sequence...");
  166. USBHS_PORTSC1 |= USBHS_PORTSC_PR;
  167. }
  168. if (count == 15) {
  169. Serial.println("End Reset Sequence...");
  170. USBHS_PORTSC1 &= ~USBHS_PORTSC_PR;
  171. }
  172. if (count > 5000) {
  173. while (1) ; // stop here
  174. }
  175. }
  176. void print(const char *s)
  177. {
  178. Serial.println(s);
  179. delay(10);
  180. }
  181. void print(const char *s, int num)
  182. {
  183. Serial.print(s);
  184. Serial.println(num);
  185. delay(10);
  186. }