comparison usb.c @ 23:845934a4e7fe

Add code to talk to a Phillips PDIUSBB12.
author darius
date Mon, 12 Dec 2005 23:32:59 +1030
parents
children 350e8655cbb7
comparison
equal deleted inserted replaced
22:bd792ebf813d 23:845934a4e7fe
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
135 /* These are really STRING_DESCRIPTOR's but we can't statically
136 * declare them as that and have the compiler generate the right size
137 * structure */
138 typedef struct {
139 uint8_t bLenght;
140 uint8_t bDescriptorType;
141 char bString[32];
142 } MANUFACTURER_DESCRIPTOR, *PMANUFACTURER_DESCRIPTOR;
143
144 const MANUFACTURER_DESCRIPTOR Manufacturer_Descriptor = { /* ManufacturerString 1 */
145 sizeof(MANUFACTURER_DESCRIPTOR), /* bLength */
146 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
147 "G\0e\0n\0e\0s\0i\0s\0 \0S\0o\0f\0t\0w\0a\0r\0e\0" /* ManufacturerString in
148 * UNICODE */
149 };
150
151 typedef struct {
152 uint8_t bLenght;
153 uint8_t bDescriptorType;
154 char bString[48];
155 } PRODUCT_DESCRIPTOR, *PPRODUCT_DESCRIPTOR;
156
157 const PRODUCT_DESCRIPTOR Product_Descriptor = { /* ProductString 2 */
158 sizeof(PRODUCT_DESCRIPTOR), /* bLength */
159 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
160 /* ProductString in
161 * UNICODE */
162 "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"
163 /* XXX: dunno why I need the double quote magic above.. */
164 };
165
166 typedef struct {
167 uint8_t bLenght;
168 uint8_t bDescriptorType;
169 char bString[20];
170 } SERIAL_DESCRIPTOR, *PSERIAL_DESCRIPTOR;
171
172 const SERIAL_DESCRIPTOR EE_Serial_Descriptor __attribute__ ((section (".eeprom"))) = { /* SerialString 3 */
173 sizeof(SERIAL_DESCRIPTOR), /* bLength - must match string below */
174 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
175 "1\02\03\0"
176 };
177
178 SERIAL_DESCRIPTOR Serial_Descriptor;
179
180 /*
181 * The PDIUSBD12 is wired up like so
182 *
183 * PDI AVR
184 * ======================
185 * D7:0 <=> PA7:0
186 * INT_N => PB0
187 * RD_N <= PB1
188 * WR_N <= PB2
189 * A0 <= PB3 (0 = data, 1 = cmd)
190 * SUSPEND <=> PB4
191 */
192 uint8_t
193 d12_get_data(void) {
194 uint8_t data;
195 #if 0
196 _delay_us(1);
197 #endif
198 PORTB &= ~_BV(PB3); /* Data phase */
199 DDRA = 0x00; /* Set to input */
200 PORTB &= ~_BV(PB1); /* Pull RD_N low */
201 PORTB &= ~_BV(PB1); /* Delay 40ns */
202 PORTB &= ~_BV(PB1);
203 PORTB &= ~_BV(PB1);
204 data = PINA; /* Read the data */
205 PORTB |= _BV(PB1); /* Pull RD_N high */
206 return(data);
207 }
208
209 void
210 set_d12_data(uint8_t data) {
211 #if 0
212 _delay_us(1);
213 #endif
214 PORTB &= ~_BV(PB3); /* Data phase */
215 DDRA = 0xff; /* Set to output */
216 PORTA = data; /* Put the data on the bus */
217 PORTB &= ~_BV(PB2); /* Pull WR_N low */
218 PORTB &= ~_BV(PB2); /* Delay 40ns */
219 PORTB &= ~_BV(PB2);
220 PORTB &= ~_BV(PB2);
221 PORTB |= _BV(PB2); /* Pull WR_N high */
222 PORTB |= _BV(PB2); /* Delay 40 ns */
223 PORTB |= _BV(PB2);
224 PORTB |= _BV(PB2);
225 DDRA = 0x00; /* Back to input */
226 }
227
228 void
229 set_d12_cmd(uint8_t cmd) {
230 #if 0
231 _delay_us(1);
232 #endif
233 PORTB |= _BV(PB3); /* Command phase */
234 DDRA = 0xff; /* Set to output */
235 PORTA = cmd; /* Put the data on the bus */
236 PORTB &= ~_BV(PB2); /* Pull WR_N low */
237 PORTB &= ~_BV(PB2); /* Delay 40ns */
238 PORTB &= ~_BV(PB2);
239 PORTB &= ~_BV(PB2);
240 PORTB |= _BV(PB2); /* Pull WR_N high */
241 PORTB |= _BV(PB2); /* Delay 40ns */
242 PORTB |= _BV(PB2);
243 PORTB |= _BV(PB2);
244 DDRA = 0x00; /* Back to input */
245 }
246
247 void
248 d12_write_cmd(uint8_t command, const uint8_t *buffer, uint8_t count) {
249 uint8_t i;
250
251 set_d12_cmd(command);
252 #if 0
253 _delay_us(1);
254 #endif
255 if (count) {
256 for (i = 0; i < count; i++) {
257 set_d12_data(buffer[i]);
258 }
259 }
260 }
261
262 void
263 d12_read_cmd(uint8_t command, uint8_t *buffer, uint8_t count) {
264 uint8_t i;
265
266 set_d12_cmd(command);
267 if (count) {
268 for (i = 0; i < count; i++) {
269 buffer[i] = d12_get_data();
270 }
271 }
272 }
273
274 /* Set up the PDIUSBD12 */
275 void
276 usb_init(void) {
277 uint8_t buffer[2];
278
279 /* pull EE_Serial_Descriptor into RAM */
280 eeprom_read_block(&Serial_Descriptor, &EE_Serial_Descriptor, sizeof(Serial_Descriptor));
281
282 /* Set Address to zero (default) and enable function */
283 buffer[0] = 0x80;
284 d12_write_cmd(D12_SET_ADDRESS_ENABLE, buffer, 1);
285
286 /* Enable function generic endpoints */
287 buffer[0] = 0x01;
288 d12_write_cmd(D12_SET_ENDPOINT_ENABLE, buffer, 1);
289
290 /* Configure the device (soft connect off) */
291 buffer[0] = D12_MODE_0 & 0xef;
292 buffer[1] = D12_MODE_1;
293 d12_write_cmd(D12_SET_MODE, buffer, 2);
294
295 /* Delay long enough for the PC to notice the disconnect */
296 _delay_us(1000);
297
298 buffer[0] |= 0x10; /* Soft connect on */
299 d12_write_cmd(D12_SET_MODE, buffer, 2);
300
301 /* Endpoint 2 IN/OUT IRQ enable */
302 buffer[0] = 0xc0;
303 d12_write_cmd(D12_SET_DMA, buffer, 1);
304 }
305
306 /* Process an interrupt */
307 void
308 usb_intr(void) {
309 uint8_t irq[2];
310 uint8_t buffer[8];
311
312 d12_read_cmd(D12_READ_INTERRUPT_REGISTER, (uint8_t *)&irq, 2);
313
314 /* Why do we get interrupts when this is 0? */
315 if (irq[0] == 0)
316 return;
317
318 if (irq[0] & D12_INT_BUS_RESET) {
319 uart_putsP(PSTR("Bus reset\n\r"));
320 usb_init();
321 return;
322 }
323
324 if (irq[0] & D12_INT_SUSPEND) {
325 uart_putsP(PSTR("Suspend change\n\r"));
326 }
327
328 if (irq[0] & D12_INT_EP0_IN) {
329 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_IN, buffer, 1);
330
331 /* Handle any outgoing data for EP0 */
332 d12_write_buffer_ep0();
333 }
334
335 /* Handle configuration and misc stuff */
336 if (irq[0] & D12_INT_EP0_OUT) {
337 d12_ep0_irq();
338 }
339
340 /* EPx_IN is when the host has had a packet of data and is expecting more */
341 if (irq[0] & D12_INT_EP1_IN) {
342 /* XXX: Not yet implemented */
343 }
344
345 /* EPx_OUT is when we have gotten a packet from the host */
346 if (irq[0] & D12_INT_EP1_OUT) {
347 /* XXX: Not yet implemented */
348 }
349
350 if (irq[0] & D12_INT_EP2_IN) {
351 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_IN, buffer, 1);
352 d12_send_data_ep2();
353 }
354
355 if (irq[0] & D12_INT_EP2_OUT) {
356 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_OUT, buffer, 1);
357 d12_receive_data_ep2();
358 }
359 }
360
361 void
362 usb_gendata(void) {
363 packet2[0] = 'a';
364 packet2[1] = 'b';
365 packet2[2] = 'c';
366 packet2[3] = '\n';
367 packet2[4] = '\r';
368 BytesToSend2 = 5;
369 pSendBuffer2 = (uint8_t *)&packet2[0];
370 send_packet2 = 1;
371
372 /* Kick off the data transfer */
373 d12_send_data_ep2();
374 }
375
376 void
377 d12_ep0_irq(void) {
378 uint8_t buffer[2];
379 USB_SETUP_REQUEST setuppkt;
380
381 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_OUT, buffer, 1);
382
383 if (buffer[0] & D12_LAST_TRAN_SETUP) {
384 /* Read the setup packet */
385 d12_read_endpt(D12_ENDPOINT_EP0_OUT, (uint8_t *)&setuppkt);
386
387 /* Ack the packet to EP0_OUT */
388 d12_write_cmd(D12_ENDPOINT_EP0_OUT, NULL, 0);
389 d12_write_cmd(D12_ACK_SETUP, NULL, 0);
390 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0);
391
392 /* Ack the packet to EP0_IN */
393 d12_write_cmd(D12_ENDPOINT_EP0_IN, NULL, 0);
394 d12_write_cmd(D12_ACK_SETUP, NULL, 0);
395
396 /* It's a new xfer, so forget about any old one */
397 send_Bytes = 0;
398
399 /* Parse request type */
400 switch (setuppkt.bmRequestType & 0x7f) {
401 case STANDARD_DEVICE_REQUEST:
402 switch (setuppkt.bRequest) {
403 case GET_STATUS:
404 /* Get status request should return remote
405 * wakeup and self powered status
406 */
407 buffer[0] = 0x01;
408 buffer[1] = 0x00;
409 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2);
410 break;
411 case CLEAR_FEATURE:
412 case SET_FEATURE:
413 /* We don't support DEVICE_REMOTE_WAKEUP or
414 * TEST_MODE
415 */
416 d12_stallctrlendpt();
417 break;
418
419 case SET_ADDRESS:
420 deviceaddress = setuppkt.wValue | 0x80;
421 d12_write_cmd(D12_SET_ADDRESS_ENABLE, &deviceaddress, 1);
422 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
423 break;
424
425 case GET_DESCRIPTOR:
426 d12_getdescriptor(&setuppkt);
427 break;
428
429 case GET_CONFIGURATION:
430 d12_write_endpt(D12_ENDPOINT_EP0_IN, &deviceconfigured, 1);
431 break;
432
433 case SET_CONFIGURATION:
434 deviceconfigured = setuppkt.wValue & 0xff;
435 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
436 break;
437
438
439 case SET_DESCRIPTOR:
440 default:
441 /* Unsupported, stall */
442 d12_stallctrlendpt();
443 break;
444 }
445 break;
446
447 case STANDARD_INTERFACE_REQUEST:
448 switch (setuppkt.bRequest) {
449 case GET_STATUS:
450 /* Should return 0, 0 (reserved) */
451 buffer[0] = 0x00;
452 buffer[1] = 0x00;
453 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2);
454 break;
455
456 case SET_INTERFACE:
457 if (setuppkt.wIndex == 0 && setuppkt.wValue == 0)
458 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
459 else
460 d12_stallctrlendpt();
461 break;
462
463 case GET_INTERFACE:
464 /* Can only handle interface 0 ... */
465 if (setuppkt.wIndex == 0) {
466 buffer[0] = 0;
467 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 1);
468 break;
469 }
470 /* .. otherwise fall through to error */
471
472 case CLEAR_FEATURE:
473 case SET_FEATURE:
474 default:
475 d12_stallctrlendpt();
476 break;
477 }
478 break;
479
480 case STANDARD_ENDPOINT_REQUEST:
481 switch (setuppkt.bRequest) {
482 case CLEAR_FEATURE:
483 case SET_FEATURE:
484 /* Halt(stall) is required to be implemented on
485 * interrupt and bulk endpoints.
486 */
487 if (setuppkt.wValue == ENDPOINT_HALT) {
488 if (setuppkt.bRequest == CLEAR_FEATURE)
489 buffer[0] = 0x00;
490 else
491 buffer[0] = 0x01;
492 switch (setuppkt.wIndex & 0xFF) {
493 case 0x01:
494 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \
495 D12_ENDPOINT_EP1_OUT, buffer, 1);
496 break;
497 case 0x81:
498 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \
499 D12_ENDPOINT_EP1_IN, buffer, 1);
500 break;
501 case 0x02:
502 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \
503 D12_ENDPOINT_EP2_OUT, buffer, 1);
504 break;
505 case 0x82:
506 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \
507 D12_ENDPOINT_EP2_IN, buffer, 1);
508 break;
509 default: /* Invalid Endpoint -
510 * RequestError */
511 d12_stallctrlendpt();
512 break;
513 }
514 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
515 } else {
516 /*
517 * No other Features for Endpoint -
518 * Request Error
519 */
520 d12_stallctrlendpt();
521 }
522 break;
523
524 case GET_STATUS:
525 /*
526 * Get Status Request to Endpoint should
527 * return Halt Status in D0 for Interrupt and Bulk
528 */
529 switch (setuppkt.wIndex & 0xFF) {
530 case 0x01:
531 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \
532 D12_ENDPOINT_EP1_OUT, buffer, 1);
533 break;
534 case 0x81:
535 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \
536 D12_ENDPOINT_EP1_IN, buffer, 1);
537 break;
538 case 0x02:
539 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \
540 D12_ENDPOINT_EP2_OUT, buffer, 1);
541 break;
542 case 0x82:
543 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \
544 D12_ENDPOINT_EP2_IN, buffer, 1);
545 break;
546 default: /* Invalid Endpoint -
547 * RequestError */
548 d12_stallctrlendpt();
549 break;
550 }
551 if (buffer[0] & 0x08)
552 buffer[0] = 0x01;
553 else
554 buffer[0] = 0x00;
555 buffer[1] = 0x00;
556 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2);
557 break;
558
559 default:
560 /* Unsupported - Request Error - Stall */
561 d12_stallctrlendpt();
562 break;
563 }
564 break;
565 case VENDOR_DEVICE_REQUEST:
566 case VENDOR_ENDPOINT_REQUEST:
567 switch (setuppkt.bRequest) {
568 case VENDOR_RESET:
569 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
570 _delay_us(1000);
571 /* disconnect from USB */
572 buffer[0] = D12_MODE_0 & 0xef;
573 buffer[1] = D12_MODE_1;
574 d12_write_cmd(D12_SET_MODE, buffer, 2);
575 _delay_us(1000);
576 cli();
577 reset();
578 /* NOT REACHED */
579 break;
580 case VENDOR_UPDATE:
581 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
582 _delay_us(1000);
583 /* disconnect from USB */
584 buffer[0] = D12_MODE_0 & 0xef;
585 buffer[1] = D12_MODE_1;
586 d12_write_cmd(D12_SET_MODE, buffer, 2);
587 _delay_us(1000);
588 cli();
589 bootloader();
590 /* NOT REACHED */
591 break;
592 default:
593 d12_stallctrlendpt();
594 break;
595 }
596 break;
597 case VENDOR_INTERFACE_REQUEST:
598 switch (setuppkt.bRequest) {
599 default:
600 d12_stallctrlendpt();
601 break;
602 }
603 break;
604 default:
605 d12_stallctrlendpt();
606 break;
607 }
608 } else {
609 /* This is a Data Packet */
610 }
611
612 }
613
614 /* Reset the micro
615 static void
616 reset(void) {
617 MCUCR = _BV(IVCE);
618 MCUCR = 0;
619 WDTCR = _BV(WDE);
620 for (;;)
621 ;
622 }
623
624 void
625 d12_getdescriptor(USB_SETUP_REQUEST *setuppkt) {
626 switch ((setuppkt->wValue & 0xff00) >> 8) {
627 case TYPE_DEVICE_DESCRIPTOR:
628 pSendBuffer = (const uint8_t *)&DeviceDescriptor;
629 BytesToSend = DeviceDescriptor.bLength;
630 send_Bytes = 1;
631 if (BytesToSend >= setuppkt->wLength) {
632 BytesToSend = setuppkt->wLength;
633 exact_Bytes = 1;
634 } else {
635 exact_Bytes = 0;
636 }
637 d12_write_buffer_ep0();
638 break;
639
640 case TYPE_CONFIGURATION_DESCRIPTOR:
641 pSendBuffer = (const uint8_t *)&ConfigurationDescriptor;
642 BytesToSend = sizeof(ConfigurationDescriptor);
643 send_Bytes = 1;
644 if (BytesToSend >= setuppkt->wLength) {
645 BytesToSend = setuppkt->wLength;
646 exact_Bytes = 1;
647 } else {
648 exact_Bytes = 0;
649 }
650 d12_write_buffer_ep0();
651 break;
652
653 case TYPE_STRING_DESCRIPTOR:
654 switch (setuppkt->wValue & 0xFF) {
655
656 case 0:
657 pSendBuffer = (const uint8_t *)&LANGID_Descriptor;
658 BytesToSend = sizeof(LANGID_Descriptor);
659 break;
660
661 case 1:
662 pSendBuffer = (const uint8_t *)&Manufacturer_Descriptor;
663 BytesToSend = sizeof(Manufacturer_Descriptor);
664 break;
665
666 case 2:
667 pSendBuffer = (const uint8_t *)&Product_Descriptor;
668 BytesToSend = sizeof(Product_Descriptor);
669 break;
670
671 case 3:
672 pSendBuffer = (const uint8_t *)&Serial_Descriptor;
673 BytesToSend = sizeof(Serial_Descriptor);
674 break;
675
676 default:
677 pSendBuffer = NULL;
678 BytesToSend = 0;
679 }
680 send_Bytes = 1;
681 if (BytesToSend >= setuppkt->wLength) {
682 BytesToSend = setuppkt->wLength;
683 exact_Bytes = 1;
684 } else {
685 exact_Bytes = 0;
686 }
687 d12_write_buffer_ep0();
688 break;
689 default:
690 d12_stallctrlendpt();
691 break;
692 }
693 }
694
695
696 void
697 d12_stallctrlendpt(void) {
698 uint8_t Buffer[] = {0x01};
699 /*
700 * 9.2.7 RequestError - return STALL PID in response to next DATA
701 * Stage Transaction
702 */
703 d12_write_cmd(D12_SET_ENDPOINT_STATUS + D12_ENDPOINT_EP0_IN, Buffer, 1);
704 /* or in the status stage of the message. */
705 d12_write_cmd(D12_SET_ENDPOINT_STATUS + D12_ENDPOINT_EP0_OUT, Buffer, 1);
706 }
707
708 uint8_t
709 d12_read_endpt(uint8_t endpt, uint8_t *buffer) {
710 uint8_t d12header[2];
711 uint8_t status = 0;
712 uint8_t i;
713
714 /* Select Endpoint */
715 d12_read_cmd(endpt, &status, 1);
716
717 /* Check if Buffer is Full */
718 if (status & 0x01) {
719 set_d12_cmd(D12_READ_BUFFER);
720 d12header[0] = d12_get_data();
721 d12header[1] = d12_get_data();
722 if (d12header[1]) {
723 for (i = 0; i < d12header[1]; i++)
724 buffer[i] = d12_get_data();
725 }
726 /* Allow new packets to be accepted */
727 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0);
728
729 }
730 return d12header[1];
731 }
732
733 void
734 d12_write_endpt(uint8_t endpt, const uint8_t *buffer, uint8_t bytes) {
735 uint8_t status = 0;
736 uint8_t i;
737
738 /* Select Endpoint */
739 d12_read_cmd(endpt, &status, 1);
740 /* Write Header */
741 set_d12_cmd(D12_WRITE_BUFFER);
742 set_d12_data(0x00);
743 set_d12_data(bytes);
744 /* Write Packet */
745 if (bytes) {
746 for (i = 0; i < bytes; i++) {
747 set_d12_data(buffer[i]);
748 }
749 }
750 /* Validate Buffer */
751 d12_write_cmd(D12_VALIDATE_BUFFER, NULL, 0);
752 }
753
754 void
755 d12_write_buffer_ep0(void) {
756 uint8_t BufferStatus = 1;
757
758 if (send_Bytes == 0) {
759 return;
760 }
761
762 /* Read Buffer Full Status */
763 d12_read_cmd(D12_ENDPOINT_EP0_IN, &BufferStatus, 1);
764 if (BufferStatus != 0) {/* Buffer Full */
765 return;
766 }
767
768 if (BytesToSend == 0) {
769 /*
770 * If BytesToSend is Zero and we get called again, assume
771 * buffer is smaller
772 * than Setup Request Size and indicate end by sending Zero
773 * Lenght packet
774 */
775 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0);
776 send_Bytes = 0;
777 } else if (BytesToSend >= EP0_SIZE) {
778 /* Write another EP0_SIZE Bytes to buffer and send */
779 d12_write_endpt(D12_ENDPOINT_EP0_IN, pSendBuffer, EP0_SIZE);
780 pSendBuffer += EP0_SIZE;
781 BytesToSend -= EP0_SIZE;
782 if (BytesToSend == 0 && exact_Bytes) {
783 send_Bytes = 0;
784 }
785 } else {
786 /* Buffer must have less than EP0_SIZE bytes left */
787 d12_write_endpt(D12_ENDPOINT_EP0_IN, pSendBuffer, BytesToSend);
788
789 BytesToSend = 0;
790 send_Bytes = 0;
791 }
792 }
793
794 void
795 d12_send_data_ep2(void) {
796 uint8_t BufferStatus = 1;
797
798 /* Read Buffer Full Status */
799 d12_read_cmd(D12_ENDPOINT_EP2_IN, &BufferStatus, 1);
800 if (BufferStatus == 0) { /* Buffer Empty */
801 if (BytesToSend2 == 0) {
802 /* Nothing to do */
803 send_packet2 = 0;
804 } else if (BytesToSend2 >= 64) {
805 /* Write another 64 Bytes to buffer and send */
806 d12_write_endpt(D12_ENDPOINT_EP2_IN, pSendBuffer2, 64);
807 pSendBuffer2 += 64;
808 BytesToSend2 -= 64;
809 } else {
810 /* Buffer must have less than 64 bytes left */
811 d12_write_endpt(D12_ENDPOINT_EP2_IN, pSendBuffer2, BytesToSend2);
812 BytesToSend2 = 0;
813 send_packet2 = 0;
814 }
815 }
816 }
817
818 void
819 d12_receive_data_ep2(void) {
820 uint8_t D12Header[2];
821 uint8_t bytes;
822 uint8_t BufferStatus = 0;
823 uint8_t i;
824
825 /* Select Endpoint */
826 d12_read_cmd(D12_ENDPOINT_EP2_OUT, &BufferStatus, 1);
827 /* Check if Buffer is Full */
828 if (BufferStatus & 0x01) {
829 /* Read header */
830 set_d12_cmd(D12_READ_BUFFER);
831 D12Header[0] = d12_get_data();
832 D12Header[1] = d12_get_data();
833 bytes = D12Header[1];
834 /* TODO check if the packet is not too long */
835 uart_putsP(PSTR("Got data\n\r"));
836 for (i = 0; i < bytes; i++) {
837 packet2[packetlen2 + i] = d12_get_data();
838 uart_puts_hex(packet2[packetlen2 + i]);
839 uart_putsP(PSTR(" "));
840 }
841 uart_putsP(PSTR("\n\r"));
842 packetlen2 += bytes;
843 /* Allow new packets to be accepted */
844 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0);
845 if (bytes == 0 || bytes < 64) { /* request complete */
846 pSendBuffer2 = packet2;
847 send_packet2 = 1;
848 packetlen2 = 0;
849 d12_send_data_ep2();
850 }
851 }
852 }