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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

board_qc.ino 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /* USB Host Shield 2.0 board quality control routine */
  2. /* To see the output set your terminal speed to 115200 */
  3. /* for GPIO test to pass you need to connect GPIN0 to GPOUT7, GPIN1 to GPOUT6, etc. */
  4. /* otherwise press any key after getting GPIO error to complete the test */
  5. /**/
  6. #include <usbhub.h>
  7. // Satisfy the IDE, which needs to see the include statment in the ino too.
  8. #ifdef dobogusinclude
  9. #include <spi4teensy3.h>
  10. #include <../../../../hardware/pic32/libraries/SPI/SPI.h> // Hack to use the SPI library
  11. #include <SPI.h> // Hack to use the SPI library
  12. #endif
  13. /* variables */
  14. uint8_t rcode;
  15. uint8_t usbstate;
  16. uint8_t laststate;
  17. //uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
  18. USB_DEVICE_DESCRIPTOR buf;
  19. /* objects */
  20. USB Usb;
  21. //USBHub hub(&Usb);
  22. void setup() {
  23. laststate = 0;
  24. Serial.begin(115200);
  25. #if !defined(__MIPSEL__)
  26. while(!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  27. #endif
  28. E_Notify(PSTR("\r\nCircuits At Home 2011"), 0x80);
  29. E_Notify(PSTR("\r\nUSB Host Shield Quality Control Routine"), 0x80);
  30. /* SPI quick test - check revision register */
  31. E_Notify(PSTR("\r\nReading REVISION register... Die revision "), 0x80);
  32. Usb.Init(); // Initializes SPI, we don't care about the return value here
  33. {
  34. uint8_t tmpbyte = Usb.regRd(rREVISION);
  35. switch(tmpbyte) {
  36. case( 0x01): //rev.01
  37. E_Notify(PSTR("01"), 0x80);
  38. break;
  39. case( 0x12): //rev.02
  40. E_Notify(PSTR("02"), 0x80);
  41. break;
  42. case( 0x13): //rev.03
  43. E_Notify(PSTR("03"), 0x80);
  44. break;
  45. default:
  46. E_Notify(PSTR("invalid. Value returned: "), 0x80);
  47. print_hex(tmpbyte, 8);
  48. halt55();
  49. break;
  50. }//switch( tmpbyte...
  51. }//check revision register
  52. /* SPI long test */
  53. {
  54. E_Notify(PSTR("\r\nSPI long test. Transfers 1MB of data. Each dot is 64K"), 0x80);
  55. uint8_t sample_wr = 0;
  56. uint8_t sample_rd = 0;
  57. uint8_t gpinpol_copy = Usb.regRd(rGPINPOL);
  58. for(uint8_t i = 0; i < 16; i++) {
  59. for(uint16_t j = 0; j < 65535; j++) {
  60. Usb.regWr(rGPINPOL, sample_wr);
  61. sample_rd = Usb.regRd(rGPINPOL);
  62. if(sample_rd != sample_wr) {
  63. E_Notify(PSTR("\r\nTest failed. "), 0x80);
  64. E_Notify(PSTR("Value written: "), 0x80);
  65. print_hex(sample_wr, 8);
  66. E_Notify(PSTR(" read: "), 0x80);
  67. print_hex(sample_rd, 8);
  68. halt55();
  69. }//if( sample_rd != sample_wr..
  70. sample_wr++;
  71. }//for( uint16_t j...
  72. E_Notify(PSTR("."), 0x80);
  73. }//for( uint8_t i...
  74. Usb.regWr(rGPINPOL, gpinpol_copy);
  75. E_Notify(PSTR(" SPI long test passed"), 0x80);
  76. }//SPI long test
  77. /* GPIO test */
  78. /* in order to simplify board layout, GPIN pins on text fixture are connected to GPOUT */
  79. /* in reverse order, i.e, GPIN0 is connected to GPOUT7, GPIN1 to GPOUT6, etc. */
  80. {
  81. uint8_t tmpbyte;
  82. E_Notify(PSTR("\r\nGPIO test. Connect GPIN0 to GPOUT7, GPIN1 to GPOUT6, and so on"), 0x80);
  83. for(uint8_t sample_gpio = 0; sample_gpio < 255; sample_gpio++) {
  84. Usb.gpioWr(sample_gpio);
  85. tmpbyte = Usb.gpioRd();
  86. /* bit reversing code copied vetbatim from http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious */
  87. tmpbyte = ((tmpbyte * 0x0802LU & 0x22110LU) | (tmpbyte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
  88. if(sample_gpio != tmpbyte) {
  89. E_Notify(PSTR("\r\nTest failed. Value written: "), 0x80);
  90. print_hex(sample_gpio, 8);
  91. E_Notify(PSTR(" Value read: "), 0x80);
  92. print_hex(tmpbyte, 8);
  93. E_Notify(PSTR(" "), 0x80);
  94. press_any_key();
  95. break;
  96. }//if( sample_gpio != tmpbyte...
  97. }//for( uint8_t sample_gpio...
  98. E_Notify(PSTR("\r\nGPIO test passed."), 0x80);
  99. }//GPIO test
  100. /* PLL test. Stops/starts MAX3421E oscillator several times */
  101. {
  102. E_Notify(PSTR("\r\nPLL test. 100 chip resets will be performed"), 0x80);
  103. /* check current state of the oscillator */
  104. if(!(Usb.regRd(rUSBIRQ) & bmOSCOKIRQ)) { //wrong state - should be on
  105. E_Notify(PSTR("\r\nCurrent oscillator state unexpected."), 0x80);
  106. press_any_key();
  107. }
  108. /* Restart oscillator */
  109. E_Notify(PSTR("\r\nResetting oscillator\r\n"), 0x80);
  110. for(uint16_t i = 0; i < 100; i++) {
  111. E_Notify(PSTR("\rReset number "), 0x80);
  112. Serial.print(i, DEC);
  113. Usb.regWr(rUSBCTL, bmCHIPRES); //reset
  114. if(Usb.regRd(rUSBIRQ) & bmOSCOKIRQ) { //wrong state - should be off
  115. E_Notify(PSTR("\r\nCurrent oscillator state unexpected."), 0x80);
  116. halt55();
  117. }
  118. Usb.regWr(rUSBCTL, 0x00); //release from reset
  119. uint16_t j = 0;
  120. for(j = 1; j < 65535; j++) { //tracking off to on time
  121. if(Usb.regRd(rUSBIRQ) & bmOSCOKIRQ) {
  122. E_Notify(PSTR(" Time to stabilize - "), 0x80);
  123. Serial.print(j, DEC);
  124. E_Notify(PSTR(" cycles\r\n"), 0x80);
  125. break;
  126. }
  127. }//for( uint16_t j = 0; j < 65535; j++
  128. if(j == 0) {
  129. E_Notify(PSTR("PLL failed to stabilize"), 0x80);
  130. press_any_key();
  131. }
  132. }//for( uint8_t i = 0; i < 255; i++
  133. }//PLL test
  134. /* initializing USB stack */
  135. if(Usb.Init() == -1) {
  136. E_Notify(PSTR("\r\nOSCOKIRQ failed to assert"), 0x80);
  137. halt55();
  138. }
  139. E_Notify(PSTR("\r\nChecking USB device communication.\r\n"), 0x80);
  140. }
  141. void loop() {
  142. delay(200);
  143. Usb.Task();
  144. usbstate = Usb.getUsbTaskState();
  145. if(usbstate != laststate) {
  146. laststate = usbstate;
  147. /**/
  148. switch(usbstate) {
  149. case( USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE):
  150. E_Notify(PSTR("\r\nWaiting for device..."), 0x80);
  151. break;
  152. case( USB_ATTACHED_SUBSTATE_RESET_DEVICE):
  153. E_Notify(PSTR("\r\nDevice connected. Resetting..."), 0x80);
  154. break;
  155. case( USB_ATTACHED_SUBSTATE_WAIT_SOF):
  156. E_Notify(PSTR("\r\nReset complete. Waiting for the first SOF..."), 0x80);
  157. break;
  158. case( USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE):
  159. E_Notify(PSTR("\r\nSOF generation started. Enumerating device..."), 0x80);
  160. break;
  161. case( USB_STATE_ADDRESSING):
  162. E_Notify(PSTR("\r\nSetting device address..."), 0x80);
  163. break;
  164. case( USB_STATE_RUNNING):
  165. E_Notify(PSTR("\r\nGetting device descriptor"), 0x80);
  166. rcode = Usb.getDevDescr(1, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) & buf);
  167. if(rcode) {
  168. E_Notify(PSTR("\r\nError reading device descriptor. Error code "), 0x80);
  169. print_hex(rcode, 8);
  170. } else {
  171. /**/
  172. E_Notify(PSTR("\r\nDescriptor Length:\t"), 0x80);
  173. print_hex(buf.bLength, 8);
  174. E_Notify(PSTR("\r\nDescriptor type:\t"), 0x80);
  175. print_hex(buf.bDescriptorType, 8);
  176. E_Notify(PSTR("\r\nUSB version:\t\t"), 0x80);
  177. print_hex(buf.bcdUSB, 16);
  178. E_Notify(PSTR("\r\nDevice class:\t\t"), 0x80);
  179. print_hex(buf.bDeviceClass, 8);
  180. E_Notify(PSTR("\r\nDevice Subclass:\t"), 0x80);
  181. print_hex(buf.bDeviceSubClass, 8);
  182. E_Notify(PSTR("\r\nDevice Protocol:\t"), 0x80);
  183. print_hex(buf.bDeviceProtocol, 8);
  184. E_Notify(PSTR("\r\nMax.packet size:\t"), 0x80);
  185. print_hex(buf.bMaxPacketSize0, 8);
  186. E_Notify(PSTR("\r\nVendor ID:\t\t"), 0x80);
  187. print_hex(buf.idVendor, 16);
  188. E_Notify(PSTR("\r\nProduct ID:\t\t"), 0x80);
  189. print_hex(buf.idProduct, 16);
  190. E_Notify(PSTR("\r\nRevision ID:\t\t"), 0x80);
  191. print_hex(buf.bcdDevice, 16);
  192. E_Notify(PSTR("\r\nMfg.string index:\t"), 0x80);
  193. print_hex(buf.iManufacturer, 8);
  194. E_Notify(PSTR("\r\nProd.string index:\t"), 0x80);
  195. print_hex(buf.iProduct, 8);
  196. E_Notify(PSTR("\r\nSerial number index:\t"), 0x80);
  197. print_hex(buf.iSerialNumber, 8);
  198. E_Notify(PSTR("\r\nNumber of conf.:\t"), 0x80);
  199. print_hex(buf.bNumConfigurations, 8);
  200. /**/
  201. E_Notify(PSTR("\r\n\nAll tests passed. Press RESET to restart test"), 0x80);
  202. while(1);
  203. }
  204. break;
  205. case( USB_STATE_ERROR):
  206. E_Notify(PSTR("\r\nUSB state machine reached error state"), 0x80);
  207. break;
  208. default:
  209. break;
  210. }//switch( usbstate...
  211. }
  212. }//loop()...
  213. /* constantly transmits 0x55 via SPI to aid probing */
  214. void halt55() {
  215. E_Notify(PSTR("\r\nUnrecoverable error - test halted!!"), 0x80);
  216. E_Notify(PSTR("\r\n0x55 pattern is transmitted via SPI"), 0x80);
  217. E_Notify(PSTR("\r\nPress RESET to restart test"), 0x80);
  218. while(1) {
  219. Usb.regWr(0x55, 0x55);
  220. }
  221. }
  222. /* prints hex numbers with leading zeroes */
  223. void print_hex(int v, int num_places) {
  224. int mask = 0, n, num_nibbles, digit;
  225. for(n = 1; n <= num_places; n++) {
  226. mask = (mask << 1) | 0x0001;
  227. }
  228. v = v & mask; // truncate v to specified number of places
  229. num_nibbles = num_places / 4;
  230. if((num_places % 4) != 0) {
  231. ++num_nibbles;
  232. }
  233. do {
  234. digit = ((v >> (num_nibbles - 1) * 4)) & 0x0f;
  235. Serial.print(digit, HEX);
  236. } while(--num_nibbles);
  237. }
  238. /* prints "Press any key" and returns when key is pressed */
  239. void press_any_key() {
  240. E_Notify(PSTR("\r\nPress any key to continue..."), 0x80);
  241. while(Serial.available() <= 0); //wait for input
  242. Serial.read(); //empty input buffer
  243. return;
  244. }