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.

227 satır
6.2KB

  1. // usb host experiments....
  2. uint32_t periodictable[64] __attribute__ ((aligned(4096), used));
  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. print_mpu();
  14. MPU_RGDAAC0 |= 0x30000000;
  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] = 1;
  67. }
  68. qh[0] = ((uint32_t)qh) | 2;
  69. qh[1] = 0x0040E000; // addr=0, ep=0
  70. qh[2] = 0x40000000;
  71. qh[3] = (uint32_t)qtd_setup;
  72. qh[4] = 1;
  73. qh[5] = 0;
  74. qh[6] = 0;
  75. qh[7] = 0;
  76. qh[8] = 0;
  77. qh[9] = 0;
  78. qh[10] = 0;
  79. qh[11] = 0;
  80. qtd_setup[0] = 1;
  81. qtd_setup[1] = 1;
  82. qtd_setup[2] = 0; // 0 = not active
  83. qtd_setup[3] = 0;
  84. qtd_setup[4] = 0;
  85. qtd_setup[5] = 0;
  86. qtd_setup[6] = 0;
  87. qtd_setup[7] = 0;
  88. // turn on the USBHS controller
  89. USBHS_USBMODE = USBHS_USBMODE_TXHSD(5) | USBHS_USBMODE_CM(3); // host mode
  90. USBHS_USBINTR = 0;
  91. USBHS_PERIODICLISTBASE = (uint32_t)periodictable;
  92. USBHS_FRINDEX = 0;
  93. USBHS_ASYNCLISTADDR = (uint32_t)qh;
  94. USBHS_USBCMD = USBHS_USBCMD_ITC(0) | USBHS_USBCMD_RS | USBHS_USBCMD_ASP(3) |
  95. USBHS_USBCMD_FS2 | USBHS_USBCMD_FS(0) | // periodic table is 64 pointers
  96. USBHS_USBCMD_PSE | USBHS_USBCMD_ASE;
  97. USBHS_PORTSC1 |= USBHS_PORTSC_PP;
  98. //USBHS_PORTSC1 |= USBHS_PORTSC_PFSC; // force 12 Mbit/sec
  99. //USBHS_PORTSC1 |= USBHS_PORTSC_PHCD; // phy off
  100. Serial.print("USBHS_ASYNCLISTADDR = ");
  101. Serial.println(USBHS_ASYNCLISTADDR, HEX);
  102. Serial.print("USBHS_PERIODICLISTBASE = ");
  103. Serial.println(USBHS_PERIODICLISTBASE, HEX);
  104. Serial.print("periodictable = ");
  105. Serial.println((uint32_t)periodictable, HEX);
  106. }
  107. void port_status()
  108. {
  109. uint32_t n;
  110. Serial.print("Port: ");
  111. n = USBHS_PORTSC1;
  112. if (n & USBHS_PORTSC_PR) {
  113. Serial.print("reset ");
  114. }
  115. if (n & USBHS_PORTSC_PP) {
  116. Serial.print("on ");
  117. } else {
  118. Serial.print("off ");
  119. }
  120. if (n & USBHS_PORTSC_PHCD) {
  121. Serial.print("phyoff ");
  122. }
  123. if (n & USBHS_PORTSC_PE) {
  124. if (n & USBHS_PORTSC_SUSP) {
  125. Serial.print("suspend ");
  126. } else {
  127. Serial.print("enable ");
  128. }
  129. } else {
  130. Serial.print("disable ");
  131. }
  132. Serial.print("speed=");
  133. switch ((n >> 26) & 3) {
  134. case 0: Serial.print("12 Mbps "); break;
  135. case 1: Serial.print("1.5 Mbps "); break;
  136. case 2: Serial.print("480 Mbps "); break;
  137. default: Serial.print("(undef) ");
  138. }
  139. if (n & USBHS_PORTSC_HSP) {
  140. Serial.print("highspeed ");
  141. }
  142. if (n & USBHS_PORTSC_OCA) {
  143. Serial.print("overcurrent ");
  144. }
  145. if (n & USBHS_PORTSC_CCS) {
  146. Serial.print("connected ");
  147. } else {
  148. Serial.print("not-connected ");
  149. }
  150. // print info about the EHCI status
  151. Serial.print(" run=");
  152. Serial.print(USBHS_USBCMD & 1); // running mode
  153. Serial.print(",halt=");
  154. Serial.print((USBHS_USBSTS >> 12) & 1); // halted mode
  155. Serial.print(",err=");
  156. Serial.print((USBHS_USBSTS >> 4) & 1); // error encountered!
  157. Serial.print(",asyn=");
  158. Serial.print((USBHS_USBSTS >> 15) & 1); // running the async schedule
  159. Serial.print(",per=");
  160. Serial.print((USBHS_USBSTS >> 14) & 1); // running the periodic schedule
  161. Serial.print(",index=");
  162. Serial.print(USBHS_FRINDEX); // periodic index
  163. Serial.println();
  164. if (USBHS_USBSTS & 16) {
  165. print_mpu();
  166. USBHS_USBSTS = 16; // clear error
  167. }
  168. }
  169. void loop()
  170. {
  171. static unsigned int count=0;
  172. port_status();
  173. delay(1);
  174. count++;
  175. if (count == 2) {
  176. Serial.println("Plug in device...");
  177. digitalWrite(32, HIGH); // connect device
  178. }
  179. if (count == 5) {
  180. Serial.println("Initiate Reset Sequence...");
  181. USBHS_PORTSC1 |= USBHS_PORTSC_PR;
  182. }
  183. if (count == 15) {
  184. Serial.println("End Reset Sequence...");
  185. USBHS_PORTSC1 &= ~USBHS_PORTSC_PR;
  186. }
  187. if (count > 5000) {
  188. while (1) ; // stop here
  189. }
  190. }
  191. void print(const char *s)
  192. {
  193. Serial.println(s);
  194. delay(10);
  195. }
  196. void print(const char *s, int num)
  197. {
  198. Serial.print(s);
  199. Serial.println(num);
  200. delay(10);
  201. }
  202. void print_mpu()
  203. {
  204. Serial.print("MPU: CESR=");
  205. Serial.println(MPU_CESR, HEX);
  206. }