23
|
1 #include <stdlib.h>
|
|
2 #include <avr/io.h>
|
|
3 #include <avr/pgmspace.h>
|
|
4 #include <avr/interrupt.h>
|
|
5 #include <avr/eeprom.h>
|
|
6 #include <util/delay.h>
|
|
7
|
|
8 #include "usb.h"
|
|
9
|
|
10 #define EP0_SIZE 16
|
|
11
|
|
12 #define D12_MODE_0 0x14 /* Endpoint config = 0, SoftConnect = 1, IRQ Mode = 1,
|
|
13 * Clock running = 0, No Lazy Clock = 0
|
|
14 */
|
|
15 #define D12_MODE_1 0x02 /* SOF mode = 0, Set-to-one = 0, Clock div = 2 (16Mhz) */
|
|
16 /* Debugging stuff */
|
|
17 void uart_putsP(const char *addr);
|
|
18 void uart_puts(const char *addr);
|
|
19 int uart_putc(char c);
|
|
20 void uart_puts_dec(uint8_t a, uint8_t l);
|
|
21 void uart_puts_hex(uint8_t a);
|
|
22
|
|
23 /* USB administrivia */
|
|
24 uint8_t deviceaddress;
|
|
25 uint8_t deviceconfigured;
|
|
26
|
|
27 /* End point buffer points and such */
|
|
28 const uint8_t *pSendBuffer;
|
|
29 uint8_t BytesToSend;
|
|
30 static uint8_t send_Bytes;
|
|
31 static uint8_t exact_Bytes;
|
|
32
|
|
33 static const uint8_t *pSendBuffer2;
|
|
34 static uint8_t BytesToSend2;
|
|
35
|
|
36 /* Data packet buffer */
|
|
37 static uint8_t send_packet2;
|
|
38 static uint8_t packet2[270];
|
|
39 static uint16_t packetlen2;
|
|
40
|
|
41 /* XXX: Not actually used */
|
|
42 void (*bootloader)(void) = (void*)0xe000;
|
|
43
|
|
44 /* Device/endpoint/etc descriptions */
|
|
45 const USB_DEVICE_DESCRIPTOR DeviceDescriptor = {
|
|
46 sizeof(USB_DEVICE_DESCRIPTOR), /* bLength */
|
|
47 TYPE_DEVICE_DESCRIPTOR, /* bDescriptorType */
|
|
48 0x0110, /* bcdUSB USB Version 1.1 */
|
|
49 0, /* bDeviceClass */
|
|
50 0, /* bDeviceSubclass */
|
|
51 0, /* bDeviceProtocol */
|
|
52 EP0_SIZE, /* bMaxPacketSize in Bytes */
|
|
53 0x4753, /* idVendor (inofficial GS) */
|
|
54 0x0001, /* idProduct */
|
|
55 0x0100, /* bcdDevice */
|
|
56 1, /* iManufacturer String Index */
|
|
57 2, /* iProduct String Index */
|
|
58 3, /* iSerialNumber String Index */
|
|
59 1 /* bNumberConfigurations */
|
|
60 };
|
|
61
|
|
62 const USB_CONFIG_DATA ConfigurationDescriptor = {
|
|
63 { /* configuration descriptor */
|
|
64 sizeof(USB_CONFIGURATION_DESCRIPTOR), /* bLength */
|
|
65 TYPE_CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
|
|
66 sizeof(USB_CONFIG_DATA), /* wTotalLength */
|
|
67 2, /* bNumInterfaces */
|
|
68 1, /* bConfigurationValue */
|
|
69 0, /* iConfiguration String Index */
|
|
70 0x80, /* bmAttributes Bus Powered, No Remote Wakeup */
|
|
71 100/2 /* bMaxPower in mA */
|
|
72 },
|
|
73 { /* interface descriptor */
|
|
74 sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */
|
|
75 TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */
|
|
76 0, /* bInterface Number */
|
|
77 0, /* bAlternateSetting */
|
|
78 2, /* bNumEndpoints */
|
|
79 0xFF, /* bInterfaceClass (Vendor specific) */
|
|
80 0x02, /* bInterfaceSubClass */
|
|
81 0x00, /* bInterfaceProtocol */
|
|
82 0 /* iInterface String Index */
|
|
83 },
|
|
84 { /* endpoint descriptor */
|
|
85 sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
|
|
86 TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */
|
|
87 0x02, /* bEndpoint Address EP2 OUT */
|
|
88 0x02, /* bmAttributes - Bulk */
|
|
89 0x0040, /* wMaxPacketSize */
|
|
90 0x00 /* bInterval */
|
|
91 },
|
|
92 { /* endpoint descriptor */
|
|
93 sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
|
|
94 TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */
|
|
95 0x82, /* bEndpoint Address EP2 IN */
|
|
96 0x02, /* bmAttributes - Bulk */
|
|
97 0x0040, /* wMaxPacketSize */
|
|
98 0x00 /* bInterval */
|
|
99 },
|
|
100 { /* interface descriptor */
|
|
101 sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */
|
|
102 TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */
|
|
103 1, /* bInterface Number */
|
|
104 0, /* bAlternateSetting */
|
|
105 2, /* bNumEndpoints */
|
|
106 0xFF, /* bInterfaceClass (Vendor specific) */
|
|
107 0x02, /* bInterfaceSubClass */
|
|
108 0x00, /* bInterfaceProtocol */
|
|
109 0 /* iInterface String Index */
|
|
110 },
|
|
111 { /* endpoint descriptor */
|
|
112 sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
|
|
113 TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */
|
|
114 0x01, /* bEndpoint Address EP1 OUT */
|
|
115 0x02, /* bmAttributes - Bulk */
|
|
116 0x0010, /* wMaxPacketSize */
|
|
117 0x00 /* bInterval */
|
|
118 },
|
|
119 { /* endpoint descriptor */
|
|
120 sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
|
|
121 TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */
|
|
122 0x81, /* bEndpoint Address EP1 IN */
|
|
123 0x02, /* bmAttributes - Bulk */
|
|
124 0x0010, /* wMaxPacketSize */
|
|
125 0x00 /* bInterval */
|
|
126 }
|
|
127 };
|
|
128 const LANGID_DESCRIPTOR LANGID_Descriptor = { /* LANGID String Descriptor
|
|
129 * Zero */
|
|
130 sizeof(LANGID_DESCRIPTOR), /* bLength - must match string below */
|
|
131 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
|
|
132 0x0409 /* LANGID US English */
|
|
133 };
|
|
134
|
26
|
135 STRING_DESCRIPTOR Manufacturer_Descriptor = {
|
|
136 sizeof(STRING_DESCRIPTOR) + 32, /* bLength */
|
|
137 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
|
|
138 "G\0e\0n\0e\0s\0i\0s\0 \0S\0o\0f\0t\0w\0a\0r\0e\0" /* ManufacturerString in
|
|
139 * UNICODE */
|
23
|
140 };
|
|
141
|
26
|
142 STRING_DESCRIPTOR Product_Descriptor = {
|
|
143 sizeof(STRING_DESCRIPTOR) + 48, /* bLength */
|
23
|
144 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
|
|
145 /* ProductString in
|
|
146 * UNICODE */
|
|
147 "R\0S\0""-\0""4\0""8\0""5\0"" \0M\0u\0l\0t\0i\0d\0r\0o\0p\0 \0A\0d\0a\0p\0t\0e\0r\0"
|
|
148 /* XXX: dunno why I need the double quote magic above.. */
|
26
|
149 };
|
23
|
150
|
26
|
151 STRING_DESCRIPTOR Serial_Descriptor;
|
|
152 STRING_DESCRIPTOR EE_Serial_Descriptor __attribute__ ((section (".eeprom"))) = { /* SerialString 3 */
|
|
153 sizeof(STRING_DESCRIPTOR) + 20, /* bLength - must match string below */
|
23
|
154 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
|
|
155 "1\02\03\0"
|
|
156 };
|
|
157
|
|
158 /*
|
|
159 * The PDIUSBD12 is wired up like so
|
|
160 *
|
|
161 * PDI AVR
|
|
162 * ======================
|
|
163 * D7:0 <=> PA7:0
|
|
164 * INT_N => PB0
|
|
165 * RD_N <= PB1
|
|
166 * WR_N <= PB2
|
|
167 * A0 <= PB3 (0 = data, 1 = cmd)
|
|
168 * SUSPEND <=> PB4
|
|
169 */
|
|
170 uint8_t
|
|
171 d12_get_data(void) {
|
|
172 uint8_t data;
|
26
|
173
|
23
|
174 PORTB &= ~_BV(PB3); /* Data phase */
|
|
175 DDRA = 0x00; /* Set to input */
|
|
176 PORTB &= ~_BV(PB1); /* Pull RD_N low */
|
|
177 PORTB &= ~_BV(PB1); /* Delay 40ns */
|
|
178 PORTB &= ~_BV(PB1);
|
|
179 PORTB &= ~_BV(PB1);
|
|
180 data = PINA; /* Read the data */
|
|
181 PORTB |= _BV(PB1); /* Pull RD_N high */
|
|
182 return(data);
|
|
183 }
|
|
184
|
|
185 void
|
|
186 set_d12_data(uint8_t data) {
|
|
187 PORTB &= ~_BV(PB3); /* Data phase */
|
|
188 DDRA = 0xff; /* Set to output */
|
|
189 PORTA = data; /* Put the data on the bus */
|
|
190 PORTB &= ~_BV(PB2); /* Pull WR_N low */
|
|
191 PORTB &= ~_BV(PB2); /* Delay 40ns */
|
|
192 PORTB &= ~_BV(PB2);
|
|
193 PORTB &= ~_BV(PB2);
|
|
194 PORTB |= _BV(PB2); /* Pull WR_N high */
|
|
195 PORTB |= _BV(PB2); /* Delay 40 ns */
|
|
196 PORTB |= _BV(PB2);
|
|
197 PORTB |= _BV(PB2);
|
|
198 DDRA = 0x00; /* Back to input */
|
|
199 }
|
|
200
|
|
201 void
|
|
202 set_d12_cmd(uint8_t cmd) {
|
|
203 PORTB |= _BV(PB3); /* Command phase */
|
|
204 DDRA = 0xff; /* Set to output */
|
|
205 PORTA = cmd; /* Put the data on the bus */
|
|
206 PORTB &= ~_BV(PB2); /* Pull WR_N low */
|
|
207 PORTB &= ~_BV(PB2); /* Delay 40ns */
|
|
208 PORTB &= ~_BV(PB2);
|
|
209 PORTB &= ~_BV(PB2);
|
|
210 PORTB |= _BV(PB2); /* Pull WR_N high */
|
|
211 PORTB |= _BV(PB2); /* Delay 40ns */
|
|
212 PORTB |= _BV(PB2);
|
|
213 PORTB |= _BV(PB2);
|
|
214 DDRA = 0x00; /* Back to input */
|
|
215 }
|
|
216
|
|
217 void
|
|
218 d12_write_cmd(uint8_t command, const uint8_t *buffer, uint8_t count) {
|
|
219 uint8_t i;
|
|
220
|
|
221 set_d12_cmd(command);
|
|
222 if (count) {
|
|
223 for (i = 0; i < count; i++) {
|
|
224 set_d12_data(buffer[i]);
|
|
225 }
|
|
226 }
|
|
227 }
|
|
228
|
|
229 void
|
|
230 d12_read_cmd(uint8_t command, uint8_t *buffer, uint8_t count) {
|
|
231 uint8_t i;
|
|
232
|
|
233 set_d12_cmd(command);
|
|
234 if (count) {
|
|
235 for (i = 0; i < count; i++) {
|
|
236 buffer[i] = d12_get_data();
|
|
237 }
|
|
238 }
|
|
239 }
|
|
240
|
|
241 /* Set up the PDIUSBD12 */
|
|
242 void
|
|
243 usb_init(void) {
|
|
244 uint8_t buffer[2];
|
|
245
|
|
246 /* pull EE_Serial_Descriptor into RAM */
|
26
|
247 eeprom_read_block(&Serial_Descriptor, &EE_Serial_Descriptor, EE_Serial_Descriptor.bLength);
|
23
|
248
|
|
249 /* Set Address to zero (default) and enable function */
|
|
250 buffer[0] = 0x80;
|
|
251 d12_write_cmd(D12_SET_ADDRESS_ENABLE, buffer, 1);
|
|
252
|
|
253 /* Enable function generic endpoints */
|
|
254 buffer[0] = 0x01;
|
|
255 d12_write_cmd(D12_SET_ENDPOINT_ENABLE, buffer, 1);
|
|
256
|
|
257 /* Configure the device (soft connect off) */
|
|
258 buffer[0] = D12_MODE_0 & 0xef;
|
|
259 buffer[1] = D12_MODE_1;
|
|
260 d12_write_cmd(D12_SET_MODE, buffer, 2);
|
|
261
|
|
262 /* Delay long enough for the PC to notice the disconnect */
|
|
263 _delay_us(1000);
|
|
264
|
|
265 buffer[0] |= 0x10; /* Soft connect on */
|
|
266 d12_write_cmd(D12_SET_MODE, buffer, 2);
|
|
267
|
|
268 /* Endpoint 2 IN/OUT IRQ enable */
|
|
269 buffer[0] = 0xc0;
|
|
270 d12_write_cmd(D12_SET_DMA, buffer, 1);
|
|
271 }
|
|
272
|
|
273 /* Process an interrupt */
|
|
274 void
|
|
275 usb_intr(void) {
|
|
276 uint8_t irq[2];
|
|
277 uint8_t buffer[8];
|
|
278
|
|
279 d12_read_cmd(D12_READ_INTERRUPT_REGISTER, (uint8_t *)&irq, 2);
|
|
280
|
|
281 /* Why do we get interrupts when this is 0? */
|
|
282 if (irq[0] == 0)
|
|
283 return;
|
|
284
|
|
285 if (irq[0] & D12_INT_BUS_RESET) {
|
|
286 uart_putsP(PSTR("Bus reset\n\r"));
|
|
287 usb_init();
|
|
288 return;
|
|
289 }
|
|
290
|
|
291 if (irq[0] & D12_INT_SUSPEND) {
|
|
292 uart_putsP(PSTR("Suspend change\n\r"));
|
|
293 }
|
|
294
|
|
295 if (irq[0] & D12_INT_EP0_IN) {
|
|
296 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_IN, buffer, 1);
|
|
297
|
|
298 /* Handle any outgoing data for EP0 */
|
|
299 d12_write_buffer_ep0();
|
|
300 }
|
|
301
|
|
302 /* Handle configuration and misc stuff */
|
|
303 if (irq[0] & D12_INT_EP0_OUT) {
|
|
304 d12_ep0_irq();
|
|
305 }
|
|
306
|
|
307 /* EPx_IN is when the host has had a packet of data and is expecting more */
|
|
308 if (irq[0] & D12_INT_EP1_IN) {
|
|
309 /* XXX: Not yet implemented */
|
|
310 }
|
|
311
|
|
312 /* EPx_OUT is when we have gotten a packet from the host */
|
|
313 if (irq[0] & D12_INT_EP1_OUT) {
|
|
314 /* XXX: Not yet implemented */
|
|
315 }
|
|
316
|
|
317 if (irq[0] & D12_INT_EP2_IN) {
|
|
318 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_IN, buffer, 1);
|
|
319 d12_send_data_ep2();
|
|
320 }
|
|
321
|
|
322 if (irq[0] & D12_INT_EP2_OUT) {
|
|
323 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_OUT, buffer, 1);
|
|
324 d12_receive_data_ep2();
|
|
325 }
|
|
326 }
|
|
327
|
|
328 void
|
|
329 usb_gendata(void) {
|
|
330 packet2[0] = 'a';
|
|
331 packet2[1] = 'b';
|
|
332 packet2[2] = 'c';
|
|
333 packet2[3] = '\n';
|
|
334 packet2[4] = '\r';
|
|
335 BytesToSend2 = 5;
|
|
336 pSendBuffer2 = (uint8_t *)&packet2[0];
|
|
337 send_packet2 = 1;
|
|
338
|
|
339 /* Kick off the data transfer */
|
|
340 d12_send_data_ep2();
|
|
341 }
|
|
342
|
|
343 void
|
|
344 d12_ep0_irq(void) {
|
|
345 uint8_t buffer[2];
|
|
346 USB_SETUP_REQUEST setuppkt;
|
|
347
|
|
348 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_OUT, buffer, 1);
|
|
349
|
|
350 if (buffer[0] & D12_LAST_TRAN_SETUP) {
|
|
351 /* Read the setup packet */
|
|
352 d12_read_endpt(D12_ENDPOINT_EP0_OUT, (uint8_t *)&setuppkt);
|
|
353
|
|
354 /* Ack the packet to EP0_OUT */
|
|
355 d12_write_cmd(D12_ENDPOINT_EP0_OUT, NULL, 0);
|
|
356 d12_write_cmd(D12_ACK_SETUP, NULL, 0);
|
|
357 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0);
|
|
358
|
|
359 /* Ack the packet to EP0_IN */
|
|
360 d12_write_cmd(D12_ENDPOINT_EP0_IN, NULL, 0);
|
|
361 d12_write_cmd(D12_ACK_SETUP, NULL, 0);
|
|
362
|
|
363 /* It's a new xfer, so forget about any old one */
|
|
364 send_Bytes = 0;
|
|
365
|
|
366 /* Parse request type */
|
|
367 switch (setuppkt.bmRequestType & 0x7f) {
|
|
368 case STANDARD_DEVICE_REQUEST:
|
|
369 switch (setuppkt.bRequest) {
|
|
370 case GET_STATUS:
|
|
371 /* Get status request should return remote
|
|
372 * wakeup and self powered status
|
|
373 */
|
|
374 buffer[0] = 0x01;
|
|
375 buffer[1] = 0x00;
|
|
376 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2);
|
|
377 break;
|
|
378 case CLEAR_FEATURE:
|
|
379 case SET_FEATURE:
|
|
380 /* We don't support DEVICE_REMOTE_WAKEUP or
|
|
381 * TEST_MODE
|
|
382 */
|
|
383 d12_stallctrlendpt();
|
|
384 break;
|
|
385
|
|
386 case SET_ADDRESS:
|
|
387 deviceaddress = setuppkt.wValue | 0x80;
|
|
388 d12_write_cmd(D12_SET_ADDRESS_ENABLE, &deviceaddress, 1);
|
|
389 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
|
|
390 break;
|
|
391
|
|
392 case GET_DESCRIPTOR:
|
|
393 d12_getdescriptor(&setuppkt);
|
|
394 break;
|
|
395
|
|
396 case GET_CONFIGURATION:
|
|
397 d12_write_endpt(D12_ENDPOINT_EP0_IN, &deviceconfigured, 1);
|
|
398 break;
|
|
399
|
|
400 case SET_CONFIGURATION:
|
|
401 deviceconfigured = setuppkt.wValue & 0xff;
|
|
402 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
|
|
403 break;
|
|
404
|
|
405
|
|
406 case SET_DESCRIPTOR:
|
|
407 default:
|
|
408 /* Unsupported, stall */
|
|
409 d12_stallctrlendpt();
|
|
410 break;
|
|
411 }
|
|
412 break;
|
|
413
|
|
414 case STANDARD_INTERFACE_REQUEST:
|
|
415 switch (setuppkt.bRequest) {
|
|
416 case GET_STATUS:
|
|
417 /* Should return 0, 0 (reserved) */
|
|
418 buffer[0] = 0x00;
|
|
419 buffer[1] = 0x00;
|
|
420 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2);
|
|
421 break;
|
|
422
|
|
423 case SET_INTERFACE:
|
|
424 if (setuppkt.wIndex == 0 && setuppkt.wValue == 0)
|
|
425 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
|
|
426 else
|
|
427 d12_stallctrlendpt();
|
|
428 break;
|
|
429
|
|
430 case GET_INTERFACE:
|
|
431 /* Can only handle interface 0 ... */
|
|
432 if (setuppkt.wIndex == 0) {
|
|
433 buffer[0] = 0;
|
|
434 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 1);
|
|
435 break;
|
|
436 }
|
|
437 /* .. otherwise fall through to error */
|
|
438
|
|
439 case CLEAR_FEATURE:
|
|
440 case SET_FEATURE:
|
|
441 default:
|
|
442 d12_stallctrlendpt();
|
|
443 break;
|
|
444 }
|
|
445 break;
|
|
446
|
|
447 case STANDARD_ENDPOINT_REQUEST:
|
|
448 switch (setuppkt.bRequest) {
|
|
449 case CLEAR_FEATURE:
|
|
450 case SET_FEATURE:
|
|
451 /* Halt(stall) is required to be implemented on
|
|
452 * interrupt and bulk endpoints.
|
|
453 */
|
|
454 if (setuppkt.wValue == ENDPOINT_HALT) {
|
|
455 if (setuppkt.bRequest == CLEAR_FEATURE)
|
|
456 buffer[0] = 0x00;
|
|
457 else
|
|
458 buffer[0] = 0x01;
|
|
459 switch (setuppkt.wIndex & 0xFF) {
|
|
460 case 0x01:
|
|
461 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \
|
|
462 D12_ENDPOINT_EP1_OUT, buffer, 1);
|
|
463 break;
|
|
464 case 0x81:
|
|
465 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \
|
|
466 D12_ENDPOINT_EP1_IN, buffer, 1);
|
|
467 break;
|
|
468 case 0x02:
|
|
469 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \
|
|
470 D12_ENDPOINT_EP2_OUT, buffer, 1);
|
|
471 break;
|
|
472 case 0x82:
|
|
473 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \
|
|
474 D12_ENDPOINT_EP2_IN, buffer, 1);
|
|
475 break;
|
|
476 default: /* Invalid Endpoint -
|
|
477 * RequestError */
|
|
478 d12_stallctrlendpt();
|
|
479 break;
|
|
480 }
|
|
481 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
|
|
482 } else {
|
|
483 /*
|
|
484 * No other Features for Endpoint -
|
|
485 * Request Error
|
|
486 */
|
|
487 d12_stallctrlendpt();
|
|
488 }
|
|
489 break;
|
|
490
|
|
491 case GET_STATUS:
|
|
492 /*
|
|
493 * Get Status Request to Endpoint should
|
|
494 * return Halt Status in D0 for Interrupt and Bulk
|
|
495 */
|
|
496 switch (setuppkt.wIndex & 0xFF) {
|
|
497 case 0x01:
|
|
498 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \
|
|
499 D12_ENDPOINT_EP1_OUT, buffer, 1);
|
|
500 break;
|
|
501 case 0x81:
|
|
502 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \
|
|
503 D12_ENDPOINT_EP1_IN, buffer, 1);
|
|
504 break;
|
|
505 case 0x02:
|
|
506 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \
|
|
507 D12_ENDPOINT_EP2_OUT, buffer, 1);
|
|
508 break;
|
|
509 case 0x82:
|
|
510 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \
|
|
511 D12_ENDPOINT_EP2_IN, buffer, 1);
|
|
512 break;
|
|
513 default: /* Invalid Endpoint -
|
|
514 * RequestError */
|
|
515 d12_stallctrlendpt();
|
|
516 break;
|
|
517 }
|
|
518 if (buffer[0] & 0x08)
|
|
519 buffer[0] = 0x01;
|
|
520 else
|
|
521 buffer[0] = 0x00;
|
|
522 buffer[1] = 0x00;
|
|
523 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2);
|
|
524 break;
|
|
525
|
|
526 default:
|
|
527 /* Unsupported - Request Error - Stall */
|
|
528 d12_stallctrlendpt();
|
|
529 break;
|
|
530 }
|
|
531 break;
|
|
532 case VENDOR_DEVICE_REQUEST:
|
|
533 case VENDOR_ENDPOINT_REQUEST:
|
|
534 switch (setuppkt.bRequest) {
|
|
535 case VENDOR_RESET:
|
|
536 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
|
|
537 _delay_us(1000);
|
|
538 /* disconnect from USB */
|
|
539 buffer[0] = D12_MODE_0 & 0xef;
|
|
540 buffer[1] = D12_MODE_1;
|
|
541 d12_write_cmd(D12_SET_MODE, buffer, 2);
|
|
542 _delay_us(1000);
|
|
543 cli();
|
|
544 reset();
|
|
545 /* NOT REACHED */
|
|
546 break;
|
|
547 case VENDOR_UPDATE:
|
|
548 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
|
|
549 _delay_us(1000);
|
|
550 /* disconnect from USB */
|
|
551 buffer[0] = D12_MODE_0 & 0xef;
|
|
552 buffer[1] = D12_MODE_1;
|
|
553 d12_write_cmd(D12_SET_MODE, buffer, 2);
|
|
554 _delay_us(1000);
|
|
555 cli();
|
|
556 bootloader();
|
|
557 /* NOT REACHED */
|
|
558 break;
|
|
559 default:
|
|
560 d12_stallctrlendpt();
|
|
561 break;
|
|
562 }
|
|
563 break;
|
|
564 case VENDOR_INTERFACE_REQUEST:
|
|
565 switch (setuppkt.bRequest) {
|
|
566 default:
|
|
567 d12_stallctrlendpt();
|
|
568 break;
|
|
569 }
|
|
570 break;
|
|
571 default:
|
|
572 d12_stallctrlendpt();
|
|
573 break;
|
|
574 }
|
|
575 } else {
|
|
576 /* This is a Data Packet */
|
|
577 }
|
|
578
|
|
579 }
|
|
580
|
26
|
581 /* Reset the micro */
|
23
|
582 static void
|
|
583 reset(void) {
|
|
584 MCUCR = _BV(IVCE);
|
|
585 MCUCR = 0;
|
|
586 WDTCR = _BV(WDE);
|
|
587 for (;;)
|
|
588 ;
|
|
589 }
|
|
590
|
|
591 void
|
|
592 d12_getdescriptor(USB_SETUP_REQUEST *setuppkt) {
|
|
593 switch ((setuppkt->wValue & 0xff00) >> 8) {
|
|
594 case TYPE_DEVICE_DESCRIPTOR:
|
|
595 pSendBuffer = (const uint8_t *)&DeviceDescriptor;
|
|
596 BytesToSend = DeviceDescriptor.bLength;
|
|
597 send_Bytes = 1;
|
|
598 if (BytesToSend >= setuppkt->wLength) {
|
|
599 BytesToSend = setuppkt->wLength;
|
|
600 exact_Bytes = 1;
|
|
601 } else {
|
|
602 exact_Bytes = 0;
|
|
603 }
|
|
604 d12_write_buffer_ep0();
|
|
605 break;
|
|
606
|
|
607 case TYPE_CONFIGURATION_DESCRIPTOR:
|
|
608 pSendBuffer = (const uint8_t *)&ConfigurationDescriptor;
|
|
609 BytesToSend = sizeof(ConfigurationDescriptor);
|
|
610 send_Bytes = 1;
|
|
611 if (BytesToSend >= setuppkt->wLength) {
|
|
612 BytesToSend = setuppkt->wLength;
|
|
613 exact_Bytes = 1;
|
|
614 } else {
|
|
615 exact_Bytes = 0;
|
|
616 }
|
|
617 d12_write_buffer_ep0();
|
|
618 break;
|
|
619
|
|
620 case TYPE_STRING_DESCRIPTOR:
|
|
621 switch (setuppkt->wValue & 0xFF) {
|
|
622
|
|
623 case 0:
|
|
624 pSendBuffer = (const uint8_t *)&LANGID_Descriptor;
|
26
|
625 BytesToSend = LANGID_Descriptor.bLength;
|
23
|
626 break;
|
|
627
|
|
628 case 1:
|
|
629 pSendBuffer = (const uint8_t *)&Manufacturer_Descriptor;
|
26
|
630 BytesToSend = Manufacturer_Descriptor.bLength;
|
23
|
631 break;
|
|
632
|
|
633 case 2:
|
|
634 pSendBuffer = (const uint8_t *)&Product_Descriptor;
|
26
|
635 BytesToSend = Product_Descriptor.bLength;
|
23
|
636 break;
|
|
637
|
|
638 case 3:
|
|
639 pSendBuffer = (const uint8_t *)&Serial_Descriptor;
|
26
|
640 BytesToSend = Serial_Descriptor.bLength;
|
23
|
641 break;
|
|
642
|
|
643 default:
|
|
644 pSendBuffer = NULL;
|
|
645 BytesToSend = 0;
|
|
646 }
|
|
647 send_Bytes = 1;
|
|
648 if (BytesToSend >= setuppkt->wLength) {
|
|
649 BytesToSend = setuppkt->wLength;
|
|
650 exact_Bytes = 1;
|
|
651 } else {
|
|
652 exact_Bytes = 0;
|
|
653 }
|
|
654 d12_write_buffer_ep0();
|
|
655 break;
|
|
656 default:
|
|
657 d12_stallctrlendpt();
|
|
658 break;
|
|
659 }
|
|
660 }
|
|
661
|
|
662
|
|
663 void
|
|
664 d12_stallctrlendpt(void) {
|
|
665 uint8_t Buffer[] = {0x01};
|
|
666 /*
|
|
667 * 9.2.7 RequestError - return STALL PID in response to next DATA
|
|
668 * Stage Transaction
|
|
669 */
|
|
670 d12_write_cmd(D12_SET_ENDPOINT_STATUS + D12_ENDPOINT_EP0_IN, Buffer, 1);
|
|
671 /* or in the status stage of the message. */
|
|
672 d12_write_cmd(D12_SET_ENDPOINT_STATUS + D12_ENDPOINT_EP0_OUT, Buffer, 1);
|
|
673 }
|
|
674
|
|
675 uint8_t
|
|
676 d12_read_endpt(uint8_t endpt, uint8_t *buffer) {
|
|
677 uint8_t d12header[2];
|
|
678 uint8_t status = 0;
|
|
679 uint8_t i;
|
|
680
|
|
681 /* Select Endpoint */
|
|
682 d12_read_cmd(endpt, &status, 1);
|
|
683
|
|
684 /* Check if Buffer is Full */
|
|
685 if (status & 0x01) {
|
|
686 set_d12_cmd(D12_READ_BUFFER);
|
|
687 d12header[0] = d12_get_data();
|
|
688 d12header[1] = d12_get_data();
|
|
689 if (d12header[1]) {
|
|
690 for (i = 0; i < d12header[1]; i++)
|
|
691 buffer[i] = d12_get_data();
|
|
692 }
|
|
693 /* Allow new packets to be accepted */
|
|
694 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0);
|
|
695
|
|
696 }
|
|
697 return d12header[1];
|
|
698 }
|
|
699
|
|
700 void
|
|
701 d12_write_endpt(uint8_t endpt, const uint8_t *buffer, uint8_t bytes) {
|
|
702 uint8_t status = 0;
|
|
703 uint8_t i;
|
|
704
|
|
705 /* Select Endpoint */
|
|
706 d12_read_cmd(endpt, &status, 1);
|
|
707 /* Write Header */
|
|
708 set_d12_cmd(D12_WRITE_BUFFER);
|
|
709 set_d12_data(0x00);
|
|
710 set_d12_data(bytes);
|
|
711 /* Write Packet */
|
|
712 if (bytes) {
|
|
713 for (i = 0; i < bytes; i++) {
|
|
714 set_d12_data(buffer[i]);
|
|
715 }
|
|
716 }
|
|
717 /* Validate Buffer */
|
|
718 d12_write_cmd(D12_VALIDATE_BUFFER, NULL, 0);
|
|
719 }
|
|
720
|
|
721 void
|
|
722 d12_write_buffer_ep0(void) {
|
|
723 uint8_t BufferStatus = 1;
|
|
724
|
|
725 if (send_Bytes == 0) {
|
|
726 return;
|
|
727 }
|
|
728
|
|
729 /* Read Buffer Full Status */
|
|
730 d12_read_cmd(D12_ENDPOINT_EP0_IN, &BufferStatus, 1);
|
|
731 if (BufferStatus != 0) {/* Buffer Full */
|
|
732 return;
|
|
733 }
|
|
734
|
|
735 if (BytesToSend == 0) {
|
|
736 /*
|
|
737 * If BytesToSend is Zero and we get called again, assume
|
|
738 * buffer is smaller
|
|
739 * than Setup Request Size and indicate end by sending Zero
|
26
|
740 * Length packet
|
23
|
741 */
|
|
742 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
|
|
743 send_Bytes = 0;
|
|
744 } else if (BytesToSend >= EP0_SIZE) {
|
|
745 /* Write another EP0_SIZE Bytes to buffer and send */
|
|
746 d12_write_endpt(D12_ENDPOINT_EP0_IN, pSendBuffer, EP0_SIZE);
|
|
747 pSendBuffer += EP0_SIZE;
|
|
748 BytesToSend -= EP0_SIZE;
|
|
749 if (BytesToSend == 0 && exact_Bytes) {
|
|
750 send_Bytes = 0;
|
|
751 }
|
|
752 } else {
|
|
753 /* Buffer must have less than EP0_SIZE bytes left */
|
|
754 d12_write_endpt(D12_ENDPOINT_EP0_IN, pSendBuffer, BytesToSend);
|
|
755
|
|
756 BytesToSend = 0;
|
|
757 send_Bytes = 0;
|
|
758 }
|
|
759 }
|
|
760
|
|
761 void
|
|
762 d12_send_data_ep2(void) {
|
|
763 uint8_t BufferStatus = 1;
|
|
764
|
|
765 /* Read Buffer Full Status */
|
|
766 d12_read_cmd(D12_ENDPOINT_EP2_IN, &BufferStatus, 1);
|
|
767 if (BufferStatus == 0) { /* Buffer Empty */
|
|
768 if (BytesToSend2 == 0) {
|
|
769 /* Nothing to do */
|
|
770 send_packet2 = 0;
|
|
771 } else if (BytesToSend2 >= 64) {
|
|
772 /* Write another 64 Bytes to buffer and send */
|
|
773 d12_write_endpt(D12_ENDPOINT_EP2_IN, pSendBuffer2, 64);
|
|
774 pSendBuffer2 += 64;
|
|
775 BytesToSend2 -= 64;
|
|
776 } else {
|
|
777 /* Buffer must have less than 64 bytes left */
|
|
778 d12_write_endpt(D12_ENDPOINT_EP2_IN, pSendBuffer2, BytesToSend2);
|
|
779 BytesToSend2 = 0;
|
|
780 send_packet2 = 0;
|
|
781 }
|
|
782 }
|
|
783 }
|
|
784
|
|
785 void
|
|
786 d12_receive_data_ep2(void) {
|
|
787 uint8_t D12Header[2];
|
|
788 uint8_t bytes;
|
|
789 uint8_t BufferStatus = 0;
|
|
790 uint8_t i;
|
|
791
|
|
792 /* Select Endpoint */
|
|
793 d12_read_cmd(D12_ENDPOINT_EP2_OUT, &BufferStatus, 1);
|
|
794 /* Check if Buffer is Full */
|
|
795 if (BufferStatus & 0x01) {
|
|
796 /* Read header */
|
|
797 set_d12_cmd(D12_READ_BUFFER);
|
|
798 D12Header[0] = d12_get_data();
|
|
799 D12Header[1] = d12_get_data();
|
|
800 bytes = D12Header[1];
|
|
801 /* TODO check if the packet is not too long */
|
|
802 uart_putsP(PSTR("Got data\n\r"));
|
|
803 for (i = 0; i < bytes; i++) {
|
|
804 packet2[packetlen2 + i] = d12_get_data();
|
|
805 uart_puts_hex(packet2[packetlen2 + i]);
|
|
806 uart_putsP(PSTR(" "));
|
|
807 }
|
|
808 uart_putsP(PSTR("\n\r"));
|
|
809 packetlen2 += bytes;
|
|
810 /* Allow new packets to be accepted */
|
|
811 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0);
|
|
812 if (bytes == 0 || bytes < 64) { /* request complete */
|
|
813 pSendBuffer2 = packet2;
|
|
814 send_packet2 = 1;
|
|
815 packetlen2 = 0;
|
|
816 d12_send_data_ep2();
|
|
817 }
|
|
818 }
|
|
819 }
|