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 */
8 // Satisfy the IDE, which needs to see the include statment in the ino too.
10 #include <spi4teensy3.h>
11 #include <../../../../hardware/pic32/libraries/SPI/SPI.h> // Hack to use the SPI library
12 #include <SPI.h> // Hack to use the SPI library
19 //uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
20 USB_DEVICE_DESCRIPTOR buf;
29 #if !defined(__MIPSEL__)
30 while(!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
32 E_Notify(PSTR("\r\nCircuits At Home 2011"), 0x80);
33 E_Notify(PSTR("\r\nUSB Host Shield Quality Control Routine"), 0x80);
34 /* SPI quick test - check revision register */
35 E_Notify(PSTR("\r\nReading REVISION register... Die revision "), 0x80);
36 Usb.Init(); // Initializes SPI, we don't care about the return value here
38 uint8_t tmpbyte = Usb.regRd(rREVISION);
41 E_Notify(PSTR("01"), 0x80);
44 E_Notify(PSTR("02"), 0x80);
47 E_Notify(PSTR("03"), 0x80);
50 E_Notify(PSTR("invalid. Value returned: "), 0x80);
51 print_hex(tmpbyte, 8);
55 }//check revision register
58 E_Notify(PSTR("\r\nSPI long test. Transfers 1MB of data. Each dot is 64K"), 0x80);
59 uint8_t sample_wr = 0;
60 uint8_t sample_rd = 0;
61 uint8_t gpinpol_copy = Usb.regRd(rGPINPOL);
62 for(uint8_t i = 0; i < 16; i++) {
63 for(uint16_t j = 0; j < 65535; j++) {
64 Usb.regWr(rGPINPOL, sample_wr);
65 sample_rd = Usb.regRd(rGPINPOL);
66 if(sample_rd != sample_wr) {
67 E_Notify(PSTR("\r\nTest failed. "), 0x80);
68 E_Notify(PSTR("Value written: "), 0x80);
69 print_hex(sample_wr, 8);
70 E_Notify(PSTR(" read: "), 0x80);
71 print_hex(sample_rd, 8);
73 }//if( sample_rd != sample_wr..
76 E_Notify(PSTR("."), 0x80);
78 Usb.regWr(rGPINPOL, gpinpol_copy);
79 E_Notify(PSTR(" SPI long test passed"), 0x80);
82 /* in order to simplify board layout, GPIN pins on text fixture are connected to GPOUT */
83 /* in reverse order, i.e, GPIN0 is connected to GPOUT7, GPIN1 to GPOUT6, etc. */
86 E_Notify(PSTR("\r\nGPIO test. Connect GPIN0 to GPOUT7, GPIN1 to GPOUT6, and so on"), 0x80);
87 for(uint8_t sample_gpio = 0; sample_gpio < 255; sample_gpio++) {
88 Usb.gpioWr(sample_gpio);
89 tmpbyte = Usb.gpioRd();
90 /* bit reversing code copied vetbatim from http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious */
91 tmpbyte = ((tmpbyte * 0x0802LU & 0x22110LU) | (tmpbyte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
92 if(sample_gpio != tmpbyte) {
93 E_Notify(PSTR("\r\nTest failed. Value written: "), 0x80);
94 print_hex(sample_gpio, 8);
95 E_Notify(PSTR(" Value read: "), 0x80);
96 print_hex(tmpbyte, 8);
97 E_Notify(PSTR(" "), 0x80);
100 }//if( sample_gpio != tmpbyte...
101 }//for( uint8_t sample_gpio...
102 E_Notify(PSTR("\r\nGPIO test passed."), 0x80);
104 /* PLL test. Stops/starts MAX3421E oscillator several times */
106 E_Notify(PSTR("\r\nPLL test. 100 chip resets will be performed"), 0x80);
107 /* check current state of the oscillator */
108 if(!(Usb.regRd(rUSBIRQ) & bmOSCOKIRQ)) { //wrong state - should be on
109 E_Notify(PSTR("\r\nCurrent oscillator state unexpected."), 0x80);
112 /* Restart oscillator */
113 E_Notify(PSTR("\r\nResetting oscillator\r\n"), 0x80);
114 for(uint16_t i = 0; i < 100; i++) {
115 E_Notify(PSTR("\rReset number "), 0x80);
116 Serial.print(i, DEC);
117 Usb.regWr(rUSBCTL, bmCHIPRES); //reset
118 if(Usb.regRd(rUSBIRQ) & bmOSCOKIRQ) { //wrong state - should be off
119 E_Notify(PSTR("\r\nCurrent oscillator state unexpected."), 0x80);
122 Usb.regWr(rUSBCTL, 0x00); //release from reset
124 for(j = 1; j < 65535; j++) { //tracking off to on time
125 if(Usb.regRd(rUSBIRQ) & bmOSCOKIRQ) {
126 E_Notify(PSTR(" Time to stabilize - "), 0x80);
127 Serial.print(j, DEC);
128 E_Notify(PSTR(" cycles\r\n"), 0x80);
131 }//for( uint16_t j = 0; j < 65535; j++
133 E_Notify(PSTR("PLL failed to stabilize"), 0x80);
136 }//for( uint8_t i = 0; i < 255; i++
139 /* initializing USB stack */
140 if(Usb.Init() == -1) {
141 E_Notify(PSTR("\r\nOSCOKIRQ failed to assert"), 0x80);
144 E_Notify(PSTR("\r\nChecking USB device communication.\r\n"), 0x80);
150 usbstate = Usb.getUsbTaskState();
151 if(usbstate != laststate) {
152 laststate = usbstate;
155 case( USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE):
156 E_Notify(PSTR("\r\nWaiting for device..."), 0x80);
158 case( USB_ATTACHED_SUBSTATE_RESET_DEVICE):
159 E_Notify(PSTR("\r\nDevice connected. Resetting..."), 0x80);
161 case( USB_ATTACHED_SUBSTATE_WAIT_SOF):
162 E_Notify(PSTR("\r\nReset complete. Waiting for the first SOF..."), 0x80);
164 case( USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE):
165 E_Notify(PSTR("\r\nSOF generation started. Enumerating device..."), 0x80);
167 case( USB_STATE_ADDRESSING):
168 E_Notify(PSTR("\r\nSetting device address..."), 0x80);
170 case( USB_STATE_RUNNING):
171 E_Notify(PSTR("\r\nGetting device descriptor"), 0x80);
172 rcode = Usb.getDevDescr(1, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) & buf);
175 E_Notify(PSTR("\r\nError reading device descriptor. Error code "), 0x80);
179 E_Notify(PSTR("\r\nDescriptor Length:\t"), 0x80);
180 print_hex(buf.bLength, 8);
181 E_Notify(PSTR("\r\nDescriptor type:\t"), 0x80);
182 print_hex(buf.bDescriptorType, 8);
183 E_Notify(PSTR("\r\nUSB version:\t\t"), 0x80);
184 print_hex(buf.bcdUSB, 16);
185 E_Notify(PSTR("\r\nDevice class:\t\t"), 0x80);
186 print_hex(buf.bDeviceClass, 8);
187 E_Notify(PSTR("\r\nDevice Subclass:\t"), 0x80);
188 print_hex(buf.bDeviceSubClass, 8);
189 E_Notify(PSTR("\r\nDevice Protocol:\t"), 0x80);
190 print_hex(buf.bDeviceProtocol, 8);
191 E_Notify(PSTR("\r\nMax.packet size:\t"), 0x80);
192 print_hex(buf.bMaxPacketSize0, 8);
193 E_Notify(PSTR("\r\nVendor ID:\t\t"), 0x80);
194 print_hex(buf.idVendor, 16);
195 E_Notify(PSTR("\r\nProduct ID:\t\t"), 0x80);
196 print_hex(buf.idProduct, 16);
197 E_Notify(PSTR("\r\nRevision ID:\t\t"), 0x80);
198 print_hex(buf.bcdDevice, 16);
199 E_Notify(PSTR("\r\nMfg.string index:\t"), 0x80);
200 print_hex(buf.iManufacturer, 8);
201 E_Notify(PSTR("\r\nProd.string index:\t"), 0x80);
202 print_hex(buf.iProduct, 8);
203 E_Notify(PSTR("\r\nSerial number index:\t"), 0x80);
204 print_hex(buf.iSerialNumber, 8);
205 E_Notify(PSTR("\r\nNumber of conf.:\t"), 0x80);
206 print_hex(buf.bNumConfigurations, 8);
208 E_Notify(PSTR("\r\n\nAll tests passed. Press RESET to restart test"), 0x80);
212 case( USB_STATE_ERROR):
213 E_Notify(PSTR("\r\nUSB state machine reached error state"), 0x80);
218 }//switch( usbstate...
222 /* constantly transmits 0x55 via SPI to aid probing */
225 E_Notify(PSTR("\r\nUnrecoverable error - test halted!!"), 0x80);
226 E_Notify(PSTR("\r\n0x55 pattern is transmitted via SPI"), 0x80);
227 E_Notify(PSTR("\r\nPress RESET to restart test"), 0x80);
230 Usb.regWr(0x55, 0x55);
234 /* prints hex numbers with leading zeroes */
235 void print_hex(int v, int num_places) {
236 int mask = 0, n, num_nibbles, digit;
238 for(n = 1; n <= num_places; n++) {
239 mask = (mask << 1) | 0x0001;
241 v = v & mask; // truncate v to specified number of places
243 num_nibbles = num_places / 4;
244 if((num_places % 4) != 0) {
248 digit = ((v >> (num_nibbles - 1) * 4)) & 0x0f;
249 Serial.print(digit, HEX);
250 } while(--num_nibbles);
253 /* prints "Press any key" and returns when key is pressed */
254 void press_any_key() {
255 E_Notify(PSTR("\r\nPress any key to continue..."), 0x80);
256 while(Serial.available() <= 0); //wait for input
257 Serial.read(); //empty input buffer