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
|
|
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 }
|