]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/protocol/usb_hid/USB_Host_Shield_2.0/examples/board_qc/board_qc.ino
lufa: usb-usb: Use LUFA startup instead of cusotom
[max/tmk_keyboard.git] / tmk_core / protocol / usb_hid / USB_Host_Shield_2.0 / examples / board_qc / board_qc.ino
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
8 // Satisfy the IDE, which needs to see the include statment in the ino too.
9 #ifdef dobogusinclude
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
13 #endif
14
15 /* variables */
16 uint8_t rcode;
17 uint8_t usbstate;
18 uint8_t laststate;
19 //uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
20 USB_DEVICE_DESCRIPTOR buf;
21
22 /* objects */
23 USB Usb;
24 //USBHub hub(&Usb);
25
26 void setup() {
27         laststate = 0;
28         Serial.begin(115200);
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
31 #endif
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
37         {
38                 uint8_t tmpbyte = Usb.regRd(rREVISION);
39                 switch(tmpbyte) {
40                         case( 0x01): //rev.01
41                                 E_Notify(PSTR("01"), 0x80);
42                                 break;
43                         case( 0x12): //rev.02
44                                 E_Notify(PSTR("02"), 0x80);
45                                 break;
46                         case( 0x13): //rev.03
47                                 E_Notify(PSTR("03"), 0x80);
48                                 break;
49                         default:
50                                 E_Notify(PSTR("invalid. Value returned: "), 0x80);
51                                 print_hex(tmpbyte, 8);
52                                 halt55();
53                                 break;
54                 }//switch( tmpbyte...
55         }//check revision register
56         /* SPI long test */
57         {
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);
72                                         halt55();
73                                 }//if( sample_rd != sample_wr..
74                                 sample_wr++;
75                         }//for( uint16_t j...
76                         E_Notify(PSTR("."), 0x80);
77                 }//for( uint8_t i...
78                 Usb.regWr(rGPINPOL, gpinpol_copy);
79                 E_Notify(PSTR(" SPI long test passed"), 0x80);
80         }//SPI long test
81         /* GPIO test */
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. */
84         {
85                 uint8_t tmpbyte;
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);
98                                 press_any_key();
99                                 break;
100                         }//if( sample_gpio != tmpbyte...
101                 }//for( uint8_t sample_gpio...
102                 E_Notify(PSTR("\r\nGPIO test passed."), 0x80);
103         }//GPIO test
104         /* PLL test. Stops/starts MAX3421E oscillator several times */
105         {
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);
110                         press_any_key();
111                 }
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);
120                                 halt55();
121                         }
122                         Usb.regWr(rUSBCTL, 0x00); //release from reset
123                         uint16_t j = 0;
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);
129                                         break;
130                                 }
131                         }//for( uint16_t j = 0; j < 65535; j++
132                         if(j == 0) {
133                                 E_Notify(PSTR("PLL failed to stabilize"), 0x80);
134                                 press_any_key();
135                         }
136                 }//for( uint8_t i = 0; i < 255; i++
137
138         }//PLL test
139         /* initializing USB stack */
140         if(Usb.Init() == -1) {
141                 E_Notify(PSTR("\r\nOSCOKIRQ failed to assert"), 0x80);
142                 halt55();
143         }
144         E_Notify(PSTR("\r\nChecking USB device communication.\r\n"), 0x80);
145 }
146
147 void loop() {
148         delay(200);
149         Usb.Task();
150         usbstate = Usb.getUsbTaskState();
151         if(usbstate != laststate) {
152                 laststate = usbstate;
153                 /**/
154                 switch(usbstate) {
155                         case( USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE):
156                                 E_Notify(PSTR("\r\nWaiting for device..."), 0x80);
157                                 break;
158                         case( USB_ATTACHED_SUBSTATE_RESET_DEVICE):
159                                 E_Notify(PSTR("\r\nDevice connected. Resetting..."), 0x80);
160                                 break;
161                         case( USB_ATTACHED_SUBSTATE_WAIT_SOF):
162                                 E_Notify(PSTR("\r\nReset complete. Waiting for the first SOF..."), 0x80);
163                                 break;
164                         case( USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE):
165                                 E_Notify(PSTR("\r\nSOF generation started. Enumerating device..."), 0x80);
166                                 break;
167                         case( USB_STATE_ADDRESSING):
168                                 E_Notify(PSTR("\r\nSetting device address..."), 0x80);
169                                 break;
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);
173
174                                 if(rcode) {
175                                         E_Notify(PSTR("\r\nError reading device descriptor. Error code "), 0x80);
176                                         print_hex(rcode, 8);
177                                 } else {
178                                         /**/
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);
207                                         /**/
208                                         E_Notify(PSTR("\r\n\nAll tests passed. Press RESET to restart test"), 0x80);
209                                         while(1);
210                                 }
211                                 break;
212                         case( USB_STATE_ERROR):
213                                 E_Notify(PSTR("\r\nUSB state machine reached error state"), 0x80);
214                                 break;
215
216                         default:
217                                 break;
218                 }//switch( usbstate...
219         }
220 }//loop()...
221
222 /* constantly transmits 0x55 via SPI to aid probing */
223 void halt55() {
224
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);
228
229         while(1) {
230                 Usb.regWr(0x55, 0x55);
231         }
232 }
233
234 /* prints hex numbers with leading zeroes */
235 void print_hex(int v, int num_places) {
236         int mask = 0, n, num_nibbles, digit;
237
238         for(n = 1; n <= num_places; n++) {
239                 mask = (mask << 1) | 0x0001;
240         }
241         v = v & mask; // truncate v to specified number of places
242
243         num_nibbles = num_places / 4;
244         if((num_places % 4) != 0) {
245                 ++num_nibbles;
246         }
247         do {
248                 digit = ((v >> (num_nibbles - 1) * 4)) & 0x0f;
249                 Serial.print(digit, HEX);
250         } while(--num_nibbles);
251 }
252
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
258         return;
259 }