]> git.gir.st - tmk_keyboard.git/blob - protocol/usb_hid/USB_Host_Shield_2.0/examples/board_qc/board_qc.ino
Squashed 'tmk_core/' changes from caca2c0..dc0e46e
[tmk_keyboard.git] / 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 }
Imprint / Impressum