Mercurial > ~darius > hgwebdir.cgi > avr
comparison usb.c @ 31:4e417d84365e
- Rename some more functions to be consistent.
- Add some delays when talking to the 'D12 - probably not needed.
- Add some comments at the top of each function.
- Log endpoint errors.
- Whitespace changes.
- Remove exact_Bytes crap.
- Many other changes I have made in an attempt to get it to work
consistently (but no luck yet).
author | darius |
---|---|
date | Mon, 10 Apr 2006 17:27:48 +0930 |
parents | 350e8655cbb7 |
children | fed32b382de2 |
comparison
equal
deleted
inserted
replaced
30:48056516b3eb | 31:4e417d84365e |
---|---|
4 #include <avr/interrupt.h> | 4 #include <avr/interrupt.h> |
5 #include <avr/eeprom.h> | 5 #include <avr/eeprom.h> |
6 #include <util/delay.h> | 6 #include <util/delay.h> |
7 | 7 |
8 #include "usb.h" | 8 #include "usb.h" |
9 | 9 #include "1wire.h" |
10 #define EP0_SIZE 16 | 10 |
11 | 11 /* Maximum FIFO sizes for each endpoint */ |
12 #define EP0_FIFO_SZ 16 | |
13 #define EP1_FIFO_SZ 16 | |
14 #define EP2_FIFO_SZ 64 | |
15 | |
16 /* PDIUSBD12 mode */ | |
12 #define D12_MODE_0 0x14 /* Endpoint config = 0, SoftConnect = 1, IRQ Mode = 1, | 17 #define D12_MODE_0 0x14 /* Endpoint config = 0, SoftConnect = 1, IRQ Mode = 1, |
13 * Clock running = 0, No Lazy Clock = 0 | 18 * Clock running = 0, No Lazy Clock = 0 |
14 */ | 19 */ |
15 #define D12_MODE_1 0x02 /* SOF mode = 0, Set-to-one = 0, Clock div = 2 (16Mhz) */ | 20 #define D12_MODE_1 0x02 /* SOF mode = 0, Set-to-one = 0, Clock div = 2 (16Mhz) */ |
21 | |
16 /* Debugging stuff */ | 22 /* Debugging stuff */ |
17 void uart_putsP(const char *addr); | 23 void uart_putsP(const char *addr); |
18 void uart_puts(const char *addr); | 24 void uart_puts(const char *addr); |
19 int uart_putc(char c); | 25 int uart_putc(char c); |
20 void uart_puts_dec(uint8_t a, uint8_t l); | 26 void uart_puts_dec(uint8_t a, uint8_t l); |
21 void uart_puts_hex(uint8_t a); | 27 void uart_puts_hex(uint8_t a); |
22 | 28 |
29 void parsebuf(uint8_t *buffer, uint8_t ep); | |
30 | |
23 /* USB administrivia */ | 31 /* USB administrivia */ |
24 uint8_t deviceaddress; | 32 uint8_t deviceaddress; |
25 uint8_t deviceconfigured; | 33 uint8_t deviceconfigured; |
26 | 34 |
27 /* End point buffer points and such */ | 35 /* Endpoint buffers and such */ |
28 const uint8_t *pSendBuffer; | 36 /* EP0 in */ |
29 uint8_t BytesToSend; | 37 static const uint8_t *sendbuffer0; |
30 static uint8_t send_Bytes; | 38 static uint8_t sendbytes0; |
31 static uint8_t exact_Bytes; | 39 |
32 | 40 /* EP0 out */ |
33 static const uint8_t *pSendBuffer2; | 41 /* This is unbuffered as we don't handle packets > EP0_FIFO_SZ */ |
34 static uint8_t BytesToSend2; | 42 |
35 | 43 /* EP1 */ |
36 /* Data packet buffer */ | 44 /* Unbuffered as yet */ |
37 static uint8_t send_packet2; | 45 static uint8_t packet1[270]; |
46 static uint16_t packetlen1; | |
47 | |
48 /* EP2 in */ | |
49 static const uint8_t *sendbuffer2; | |
50 static uint8_t sendbytes2; | |
51 | |
52 /* EP2 out */ | |
38 static uint8_t packet2[270]; | 53 static uint8_t packet2[270]; |
39 static uint16_t packetlen2; | 54 static uint16_t packetlen2; |
40 | 55 |
41 /* XXX: Not actually used */ | 56 /* XXX: Not actually used */ |
42 void (*bootloader)(void) = (void*)0xe000; | 57 void (*bootloader)(void) = (void*)0xe000; |
47 TYPE_DEVICE_DESCRIPTOR, /* bDescriptorType */ | 62 TYPE_DEVICE_DESCRIPTOR, /* bDescriptorType */ |
48 0x0110, /* bcdUSB USB Version 1.1 */ | 63 0x0110, /* bcdUSB USB Version 1.1 */ |
49 0, /* bDeviceClass */ | 64 0, /* bDeviceClass */ |
50 0, /* bDeviceSubclass */ | 65 0, /* bDeviceSubclass */ |
51 0, /* bDeviceProtocol */ | 66 0, /* bDeviceProtocol */ |
52 EP0_SIZE, /* bMaxPacketSize in Bytes */ | 67 EP0_FIFO_SZ, /* bMaxPacketSize in Bytes */ |
53 0x4753, /* idVendor (inofficial GS) */ | 68 0x4753, /* idVendor (unofficial GS) */ |
54 0x0001, /* idProduct */ | 69 0x0001, /* idProduct */ |
55 0x0100, /* bcdDevice */ | 70 0x0100, /* bcdDevice */ |
56 1, /* iManufacturer String Index */ | 71 1, /* iManufacturer String Index */ |
57 2, /* iProduct String Index */ | 72 2, /* iProduct String Index */ |
58 3, /* iSerialNumber String Index */ | 73 3, /* iSerialNumber String Index */ |
74 sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ | 89 sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ |
75 TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */ | 90 TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */ |
76 0, /* bInterface Number */ | 91 0, /* bInterface Number */ |
77 0, /* bAlternateSetting */ | 92 0, /* bAlternateSetting */ |
78 2, /* bNumEndpoints */ | 93 2, /* bNumEndpoints */ |
79 0xFF, /* bInterfaceClass (Vendor specific) */ | 94 0xff, /* bInterfaceClass (Vendor specific) */ |
80 0x02, /* bInterfaceSubClass */ | 95 0x02, /* bInterfaceSubClass */ |
81 0x00, /* bInterfaceProtocol */ | 96 0x00, /* bInterfaceProtocol */ |
82 0 /* iInterface String Index */ | 97 0 /* iInterface String Index */ |
83 }, | 98 }, |
84 { /* endpoint descriptor */ | 99 { /* endpoint descriptor */ |
101 sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ | 116 sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ |
102 TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */ | 117 TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */ |
103 1, /* bInterface Number */ | 118 1, /* bInterface Number */ |
104 0, /* bAlternateSetting */ | 119 0, /* bAlternateSetting */ |
105 2, /* bNumEndpoints */ | 120 2, /* bNumEndpoints */ |
106 0xFF, /* bInterfaceClass (Vendor specific) */ | 121 0xff, /* bInterfaceClass (Vendor specific) */ |
107 0x02, /* bInterfaceSubClass */ | 122 0x02, /* bInterfaceSubClass */ |
108 0x00, /* bInterfaceProtocol */ | 123 0x00, /* bInterfaceProtocol */ |
109 0 /* iInterface String Index */ | 124 0 /* iInterface String Index */ |
110 }, | 125 }, |
111 { /* endpoint descriptor */ | 126 { /* endpoint descriptor */ |
165 * RD_N <= PB1 | 180 * RD_N <= PB1 |
166 * WR_N <= PB2 | 181 * WR_N <= PB2 |
167 * A0 <= PB3 (0 = data, 1 = cmd) | 182 * A0 <= PB3 (0 = data, 1 = cmd) |
168 * SUSPEND <=> PB4 | 183 * SUSPEND <=> PB4 |
169 */ | 184 */ |
185 | |
186 /******************************************************************************* | |
187 ** d12_get_data | |
188 ** | |
189 ** Read a data byte | |
190 */ | |
170 uint8_t | 191 uint8_t |
171 d12_get_data(void) { | 192 d12_get_data(void) { |
172 uint8_t data; | 193 uint8_t data; |
173 | 194 |
195 _delay_us(1); | |
174 PORTB &= ~_BV(PB3); /* Data phase */ | 196 PORTB &= ~_BV(PB3); /* Data phase */ |
175 DDRA = 0x00; /* Set to input */ | 197 DDRA = 0x00; /* Set to input */ |
176 PORTB &= ~_BV(PB1); /* Pull RD_N low */ | 198 PORTB &= ~_BV(PB1); /* Pull RD_N low */ |
177 PORTB &= ~_BV(PB1); /* Delay 40ns */ | 199 PORTB &= ~_BV(PB1); /* Delay 40ns */ |
178 PORTB &= ~_BV(PB1); | 200 PORTB &= ~_BV(PB1); |
179 PORTB &= ~_BV(PB1); | 201 PORTB &= ~_BV(PB1); |
180 data = PINA; /* Read the data */ | 202 data = PINA; /* Read the data */ |
181 PORTB |= _BV(PB1); /* Pull RD_N high */ | 203 PORTB |= _BV(PB1); /* Pull RD_N high */ |
204 | |
182 return(data); | 205 return(data); |
183 } | 206 } |
184 | 207 |
208 /******************************************************************************* | |
209 ** d12_set_data | |
210 ** | |
211 ** Write a data byte | |
212 */ | |
185 void | 213 void |
186 set_d12_data(uint8_t data) { | 214 d12_set_data(uint8_t data) { |
215 _delay_us(1); | |
187 PORTB &= ~_BV(PB3); /* Data phase */ | 216 PORTB &= ~_BV(PB3); /* Data phase */ |
188 DDRA = 0xff; /* Set to output */ | 217 DDRA = 0xff; /* Set to output */ |
189 PORTA = data; /* Put the data on the bus */ | 218 PORTA = data; /* Put the data on the bus */ |
190 PORTB &= ~_BV(PB2); /* Pull WR_N low */ | 219 PORTB &= ~_BV(PB2); /* Pull WR_N low */ |
191 PORTB &= ~_BV(PB2); /* Delay 40ns */ | 220 PORTB &= ~_BV(PB2); /* Delay 40ns */ |
196 PORTB |= _BV(PB2); | 225 PORTB |= _BV(PB2); |
197 PORTB |= _BV(PB2); | 226 PORTB |= _BV(PB2); |
198 DDRA = 0x00; /* Back to input */ | 227 DDRA = 0x00; /* Back to input */ |
199 } | 228 } |
200 | 229 |
230 /******************************************************************************* | |
231 ** d12_set_cmd | |
232 ** | |
233 ** Start a command | |
234 */ | |
201 void | 235 void |
202 set_d12_cmd(uint8_t cmd) { | 236 d12_set_cmd(uint8_t cmd) { |
237 _delay_us(1); | |
203 PORTB |= _BV(PB3); /* Command phase */ | 238 PORTB |= _BV(PB3); /* Command phase */ |
204 DDRA = 0xff; /* Set to output */ | 239 DDRA = 0xff; /* Set to output */ |
205 PORTA = cmd; /* Put the data on the bus */ | 240 PORTA = cmd; /* Put the data on the bus */ |
206 PORTB &= ~_BV(PB2); /* Pull WR_N low */ | 241 PORTB &= ~_BV(PB2); /* Pull WR_N low */ |
207 PORTB &= ~_BV(PB2); /* Delay 40ns */ | 242 PORTB &= ~_BV(PB2); /* Delay 40ns */ |
212 PORTB |= _BV(PB2); | 247 PORTB |= _BV(PB2); |
213 PORTB |= _BV(PB2); | 248 PORTB |= _BV(PB2); |
214 DDRA = 0x00; /* Back to input */ | 249 DDRA = 0x00; /* Back to input */ |
215 } | 250 } |
216 | 251 |
252 /******************************************************************************* | |
253 ** d12_write_cmd | |
254 ** | |
255 ** Issue a command with associated data | |
256 */ | |
217 void | 257 void |
218 d12_write_cmd(uint8_t command, const uint8_t *buffer, uint8_t count) { | 258 d12_write_cmd(uint8_t command, const uint8_t *buffer, uint8_t count) { |
219 uint8_t i; | 259 uint8_t i; |
220 | 260 |
221 set_d12_cmd(command); | 261 d12_set_cmd(command); |
222 if (count) { | 262 if (count) { |
223 for (i = 0; i < count; i++) { | 263 for (i = 0; i < count; i++) { |
224 set_d12_data(buffer[i]); | 264 d12_set_data(buffer[i]); |
225 } | 265 } |
226 } | 266 } |
227 } | 267 } |
228 | 268 |
269 /******************************************************************************* | |
270 ** d12_read_cmd | |
271 ** | |
272 ** Issue a command and read back the data | |
273 */ | |
229 void | 274 void |
230 d12_read_cmd(uint8_t command, uint8_t *buffer, uint8_t count) { | 275 d12_read_cmd(uint8_t command, uint8_t *buffer, uint8_t count) { |
231 uint8_t i; | 276 uint8_t i; |
232 | 277 |
233 set_d12_cmd(command); | 278 d12_set_cmd(command); |
234 if (count) { | 279 if (count) { |
235 for (i = 0; i < count; i++) { | 280 for (i = 0; i < count; i++) { |
236 buffer[i] = d12_get_data(); | 281 buffer[i] = d12_get_data(); |
237 } | 282 } |
238 } | 283 } |
239 } | 284 } |
240 | 285 |
241 /* Set up the PDIUSBD12 */ | 286 /******************************************************************************* |
287 ** usb_init | |
288 ** | |
289 ** Configure the PDIUSBD12 | |
290 */ | |
242 void | 291 void |
243 usb_init(void) { | 292 usb_init(void) { |
244 uint8_t buffer[2]; | 293 uint8_t buffer[2]; |
245 | 294 |
246 /* pull EE_Serial_Descriptor into RAM */ | 295 /* pull EE_Serial_Descriptor into RAM */ |
268 /* Endpoint 2 IN/OUT IRQ enable */ | 317 /* Endpoint 2 IN/OUT IRQ enable */ |
269 buffer[0] = 0xc0; | 318 buffer[0] = 0xc0; |
270 d12_write_cmd(D12_SET_DMA, buffer, 1); | 319 d12_write_cmd(D12_SET_DMA, buffer, 1); |
271 } | 320 } |
272 | 321 |
273 /* Process an interrupt */ | 322 /******************************************************************************* |
323 ** usb_intr | |
324 ** | |
325 ** Process any pending interrupts | |
326 */ | |
274 void | 327 void |
275 usb_intr(void) { | 328 usb_intr(void) { |
276 uint8_t irq[2]; | 329 uint8_t irq[2]; |
277 uint8_t buffer[8]; | 330 uint8_t buffer[8]; |
278 | 331 |
292 uart_putsP(PSTR("Suspend change\n\r")); | 345 uart_putsP(PSTR("Suspend change\n\r")); |
293 } | 346 } |
294 | 347 |
295 if (irq[0] & D12_INT_EP0_IN) { | 348 if (irq[0] & D12_INT_EP0_IN) { |
296 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_IN, buffer, 1); | 349 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_IN, buffer, 1); |
350 if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { | |
351 uart_putsP(PSTR("EP0_IN error ")); | |
352 uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); | |
353 uart_putsP(PSTR("\n\r")); | |
354 } | |
297 | 355 |
298 /* Handle any outgoing data for EP0 */ | 356 /* Handle any outgoing data for EP0 */ |
299 d12_write_buffer_ep0(); | 357 d12_send_data_ep0(); |
300 } | 358 } |
301 | 359 |
302 /* Handle configuration and misc stuff */ | 360 /* Handle configuration and misc stuff */ |
303 if (irq[0] & D12_INT_EP0_OUT) { | 361 if (irq[0] & D12_INT_EP0_OUT) { |
304 d12_ep0_irq(); | 362 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_OUT, buffer, 1); |
363 if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { | |
364 uart_putsP(PSTR("EP0_OUT error ")); | |
365 uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); | |
366 uart_putsP(PSTR("\n\r")); | |
367 } | |
368 | |
369 if (buffer[0] & D12_LAST_TRAN_SETUP) | |
370 d12_handle_setup(); | |
371 else { | |
372 /* Data packet */ | |
373 } | |
305 } | 374 } |
306 | 375 |
307 /* EPx_IN is when the host has had a packet of data and is expecting more */ | 376 /* EPx_IN is when the host has had a packet of data and is expecting more */ |
308 if (irq[0] & D12_INT_EP1_IN) { | 377 if (irq[0] & D12_INT_EP1_IN) { |
309 /* XXX: Not yet implemented */ | 378 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP1_IN, buffer, 1); |
379 if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { | |
380 uart_putsP(PSTR("EP1_IN error ")); | |
381 uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); | |
382 uart_putsP(PSTR("\n\r")); | |
383 } | |
384 | |
385 /* Select endpoint */ | |
386 d12_read_cmd(D12_ENDPOINT_EP1_IN, buffer, 1); | |
387 | |
388 if (buffer[0] & 0x01) | |
389 uart_putsP(PSTR("EP1_IN is full\n\r")); | |
390 | |
391 if (buffer[0] & 0x02) | |
392 uart_putsP(PSTR("EP1_IN is stalled\n\r")); | |
393 | |
394 d12_write_endpt(D12_ENDPOINT_EP1_IN, NULL, 0); | |
310 } | 395 } |
311 | 396 |
312 /* EPx_OUT is when we have gotten a packet from the host */ | 397 /* EPx_OUT is when we have gotten a packet from the host */ |
313 if (irq[0] & D12_INT_EP1_OUT) { | 398 if (irq[0] & D12_INT_EP1_OUT) { |
314 /* XXX: Not yet implemented */ | 399 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP1_OUT, buffer, 1); |
315 } | 400 if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { |
316 | 401 uart_putsP(PSTR("EP1_OUT error ")); |
317 if (irq[0] & D12_INT_EP2_IN) { | 402 uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); |
403 uart_putsP(PSTR("\n\r")); | |
404 } | |
405 | |
406 d12_receive_data_ep1(); | |
407 } | |
408 | |
409 if (irq[0] & D12_INT_EP2_IN) { | |
318 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_IN, buffer, 1); | 410 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_IN, buffer, 1); |
411 if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { | |
412 uart_putsP(PSTR("EP2_IN error ")); | |
413 uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); | |
414 uart_putsP(PSTR("\n\r")); | |
415 } | |
416 | |
319 d12_send_data_ep2(); | 417 d12_send_data_ep2(); |
320 } | 418 } |
321 | 419 |
322 if (irq[0] & D12_INT_EP2_OUT) { | 420 if (irq[0] & D12_INT_EP2_OUT) { |
323 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_OUT, buffer, 1); | 421 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP2_OUT, buffer, 1); |
422 if ((buffer[0] & D12_LAST_TRAN_ERRMSK) != 0) { | |
423 uart_putsP(PSTR("EP2_OUT error ")); | |
424 uart_puts_hex((buffer[0] & D12_LAST_TRAN_ERRMSK) >> 1); | |
425 uart_putsP(PSTR("\n\r")); | |
426 } | |
324 d12_receive_data_ep2(); | 427 d12_receive_data_ep2(); |
325 } | 428 } |
326 } | 429 } |
327 | 430 |
431 /******************************************************************************* | |
432 ** usb_gendata | |
433 ** | |
434 ** Fake up some data for testing purposes | |
435 */ | |
328 void | 436 void |
329 usb_gendata(void) { | 437 usb_gendata(void) { |
330 packet2[0] = 'a'; | 438 packet2[0] = 'a'; |
331 packet2[1] = 'b'; | 439 packet2[1] = 'b'; |
332 packet2[2] = 'c'; | 440 packet2[2] = 'c'; |
333 packet2[3] = '\n'; | 441 packet2[3] = '\n'; |
334 packet2[4] = '\r'; | 442 packet2[4] = '\r'; |
335 BytesToSend2 = 5; | 443 sendbytes2 = 5; |
336 pSendBuffer2 = (uint8_t *)&packet2[0]; | 444 sendbuffer2 = (uint8_t *)&packet2[0]; |
337 send_packet2 = 1; | |
338 | 445 |
339 /* Kick off the data transfer */ | 446 /* Kick off the data transfer */ |
340 d12_send_data_ep2(); | 447 d12_send_data_ep2(); |
341 } | 448 } |
342 | 449 |
450 /******************************************************************************* | |
451 ** d12_handle_setup | |
452 ** | |
453 ** Handle setup packet stuff for endpoint 0 | |
454 */ | |
343 void | 455 void |
344 d12_ep0_irq(void) { | 456 d12_handle_setup(void) { |
345 uint8_t buffer[2]; | 457 uint8_t buffer[2]; |
346 USB_SETUP_REQUEST setuppkt; | 458 USB_SETUP_REQUEST setuppkt; |
347 | 459 |
348 d12_read_cmd(D12_READ_LAST_TRANSACTION + D12_ENDPOINT_EP0_OUT, buffer, 1); | 460 /* Read the setup packet */ |
349 | 461 d12_read_endpt(D12_ENDPOINT_EP0_OUT, (uint8_t *)&setuppkt); |
350 if (buffer[0] & D12_LAST_TRAN_SETUP) { | 462 |
351 /* Read the setup packet */ | 463 /* Ack the packet to EP0_OUT */ |
352 d12_read_endpt(D12_ENDPOINT_EP0_OUT, (uint8_t *)&setuppkt); | 464 d12_write_cmd(D12_ENDPOINT_EP0_OUT, NULL, 0); |
465 d12_write_cmd(D12_ACK_SETUP, NULL, 0); | |
466 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); | |
353 | 467 |
354 /* Ack the packet to EP0_OUT */ | 468 /* Ack the packet to EP0_IN */ |
355 d12_write_cmd(D12_ENDPOINT_EP0_OUT, NULL, 0); | 469 d12_write_cmd(D12_ENDPOINT_EP0_IN, NULL, 0); |
356 d12_write_cmd(D12_ACK_SETUP, NULL, 0); | 470 d12_write_cmd(D12_ACK_SETUP, NULL, 0); |
357 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); | |
358 | 471 |
359 /* Ack the packet to EP0_IN */ | 472 /* Parse request type */ |
360 d12_write_cmd(D12_ENDPOINT_EP0_IN, NULL, 0); | 473 switch (setuppkt.bmRequestType & 0x7f) { |
361 d12_write_cmd(D12_ACK_SETUP, NULL, 0); | 474 case STANDARD_DEVICE_REQUEST: |
362 | 475 switch (setuppkt.bRequest) { |
363 /* It's a new xfer, so forget about any old one */ | 476 case GET_STATUS: |
364 send_Bytes = 0; | 477 /* Get status request should return remote |
365 | 478 * wakeup and self powered status |
366 /* Parse request type */ | 479 */ |
367 switch (setuppkt.bmRequestType & 0x7f) { | 480 buffer[0] = 0x01; |
368 case STANDARD_DEVICE_REQUEST: | 481 buffer[1] = 0x00; |
369 switch (setuppkt.bRequest) { | 482 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2); |
370 case GET_STATUS: | 483 break; |
371 /* Get status request should return remote | 484 case CLEAR_FEATURE: |
372 * wakeup and self powered status | 485 case SET_FEATURE: |
373 */ | 486 /* We don't support DEVICE_REMOTE_WAKEUP or |
374 buffer[0] = 0x01; | 487 * TEST_MODE |
375 buffer[1] = 0x00; | 488 */ |
376 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2); | 489 |
490 d12_stallendpt(D12_ENDPOINT_EP0_IN); | |
491 d12_stallendpt(D12_ENDPOINT_EP0_OUT); | |
492 break; | |
493 | |
494 case SET_ADDRESS: | |
495 deviceaddress = setuppkt.wValue | 0x80; | |
496 d12_write_cmd(D12_SET_ADDRESS_ENABLE, &deviceaddress, 1); | |
497 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); | |
498 break; | |
499 | |
500 case GET_DESCRIPTOR: | |
501 d12_getdescriptor(&setuppkt); | |
502 break; | |
503 | |
504 case GET_CONFIGURATION: | |
505 d12_write_endpt(D12_ENDPOINT_EP0_IN, &deviceconfigured, 1); | |
506 break; | |
507 | |
508 case SET_CONFIGURATION: | |
509 deviceconfigured = setuppkt.wValue & 0xff; | |
510 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); | |
511 break; | |
512 | |
513 | |
514 case SET_DESCRIPTOR: | |
515 default: | |
516 /* Unsupported, stall */ | |
517 d12_stallendpt(D12_ENDPOINT_EP0_IN); | |
518 d12_stallendpt(D12_ENDPOINT_EP0_OUT); | |
519 break; | |
520 } | |
521 break; | |
522 | |
523 case STANDARD_INTERFACE_REQUEST: | |
524 switch (setuppkt.bRequest) { | |
525 case GET_STATUS: | |
526 /* Should return 0, 0 (reserved) */ | |
527 buffer[0] = 0x00; | |
528 buffer[1] = 0x00; | |
529 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2); | |
530 break; | |
531 | |
532 case SET_INTERFACE: | |
533 if (setuppkt.wIndex == 0 && setuppkt.wValue == 0) | |
534 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); | |
535 else { | |
536 d12_stallendpt(D12_ENDPOINT_EP0_IN); | |
537 d12_stallendpt(D12_ENDPOINT_EP0_OUT); | |
538 } | |
539 | |
540 break; | |
541 | |
542 case GET_INTERFACE: | |
543 /* Can only handle interface 0 ... */ | |
544 if (setuppkt.wIndex == 0) { | |
545 buffer[0] = 0; | |
546 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 1); | |
377 break; | 547 break; |
378 case CLEAR_FEATURE: | 548 } |
379 case SET_FEATURE: | 549 /* .. otherwise fall through to error */ |
380 /* We don't support DEVICE_REMOTE_WAKEUP or | 550 |
381 * TEST_MODE | 551 case CLEAR_FEATURE: |
382 */ | 552 case SET_FEATURE: |
383 d12_stallctrlendpt(); | 553 default: |
384 break; | 554 d12_stallendpt(D12_ENDPOINT_EP0_IN); |
385 | 555 d12_stallendpt(D12_ENDPOINT_EP0_OUT); |
386 case SET_ADDRESS: | 556 break; |
387 deviceaddress = setuppkt.wValue | 0x80; | 557 } |
388 d12_write_cmd(D12_SET_ADDRESS_ENABLE, &deviceaddress, 1); | 558 break; |
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 | 559 |
414 case STANDARD_INTERFACE_REQUEST: | 560 case STANDARD_ENDPOINT_REQUEST: |
415 switch (setuppkt.bRequest) { | 561 switch (setuppkt.bRequest) { |
416 case GET_STATUS: | 562 case CLEAR_FEATURE: |
417 /* Should return 0, 0 (reserved) */ | 563 case SET_FEATURE: |
418 buffer[0] = 0x00; | 564 /* Halt(stall) is required to be implemented on |
419 buffer[1] = 0x00; | 565 * interrupt and bulk endpoints. |
420 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2); | 566 */ |
421 break; | 567 if (setuppkt.wValue == ENDPOINT_HALT) { |
422 | 568 if (setuppkt.bRequest == CLEAR_FEATURE) |
423 case SET_INTERFACE: | 569 buffer[0] = 0x00; |
424 if (setuppkt.wIndex == 0 && setuppkt.wValue == 0) | |
425 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); | |
426 else | 570 else |
427 d12_stallctrlendpt(); | 571 buffer[0] = 0x01; |
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) { | 572 switch (setuppkt.wIndex & 0xFF) { |
497 case 0x01: | 573 case 0x01: |
498 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ | 574 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \ |
499 D12_ENDPOINT_EP1_OUT, buffer, 1); | 575 D12_ENDPOINT_EP1_OUT, buffer, 1); |
500 break; | 576 break; |
501 case 0x81: | 577 case 0x81: |
502 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ | 578 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \ |
503 D12_ENDPOINT_EP1_IN, buffer, 1); | 579 D12_ENDPOINT_EP1_IN, buffer, 1); |
504 break; | 580 break; |
505 case 0x02: | 581 case 0x02: |
506 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ | 582 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \ |
507 D12_ENDPOINT_EP2_OUT, buffer, 1); | 583 D12_ENDPOINT_EP2_OUT, buffer, 1); |
508 break; | 584 break; |
509 case 0x82: | 585 case 0x82: |
510 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ | 586 d12_write_cmd(D12_SET_ENDPOINT_STATUS + \ |
511 D12_ENDPOINT_EP2_IN, buffer, 1); | 587 D12_ENDPOINT_EP2_IN, buffer, 1); |
512 break; | 588 break; |
513 default: /* Invalid Endpoint - | 589 default: /* Invalid Endpoint - |
514 * RequestError */ | 590 * RequestError */ |
515 d12_stallctrlendpt(); | 591 d12_stallendpt(D12_ENDPOINT_EP0_IN); |
592 d12_stallendpt(D12_ENDPOINT_EP0_OUT); | |
516 break; | 593 break; |
517 } | 594 } |
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); | 595 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); |
537 _delay_us(1000); | 596 } else { |
538 /* disconnect from USB */ | 597 /* |
539 buffer[0] = D12_MODE_0 & 0xef; | 598 * No other Features for Endpoint - |
540 buffer[1] = D12_MODE_1; | 599 * Request Error |
541 d12_write_cmd(D12_SET_MODE, buffer, 2); | 600 */ |
542 _delay_us(1000); | 601 d12_stallendpt(D12_ENDPOINT_EP0_IN); |
543 cli(); | 602 d12_stallendpt(D12_ENDPOINT_EP0_OUT); |
544 reset(); | 603 } |
545 /* NOT REACHED */ | 604 break; |
546 break; | 605 |
547 case VENDOR_UPDATE: | 606 case GET_STATUS: |
548 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); | 607 /* |
549 _delay_us(1000); | 608 * Get Status Request to Endpoint should |
550 /* disconnect from USB */ | 609 * return Halt Status in D0 for Interrupt and Bulk |
551 buffer[0] = D12_MODE_0 & 0xef; | 610 */ |
552 buffer[1] = D12_MODE_1; | 611 switch (setuppkt.wIndex & 0xFF) { |
553 d12_write_cmd(D12_SET_MODE, buffer, 2); | 612 case 0x01: |
554 _delay_us(1000); | 613 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ |
555 cli(); | 614 D12_ENDPOINT_EP1_OUT, buffer, 1); |
556 bootloader(); | 615 break; |
557 /* NOT REACHED */ | 616 case 0x81: |
558 break; | 617 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ |
559 default: | 618 D12_ENDPOINT_EP1_IN, buffer, 1); |
560 d12_stallctrlendpt(); | 619 break; |
561 break; | 620 case 0x02: |
562 } | 621 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ |
563 break; | 622 D12_ENDPOINT_EP2_OUT, buffer, 1); |
564 case VENDOR_INTERFACE_REQUEST: | 623 break; |
565 switch (setuppkt.bRequest) { | 624 case 0x82: |
566 default: | 625 d12_read_cmd(D12_READ_ENDPOINT_STATUS + \ |
567 d12_stallctrlendpt(); | 626 D12_ENDPOINT_EP2_IN, buffer, 1); |
568 break; | 627 break; |
569 } | 628 default: /* Invalid Endpoint - |
570 break; | 629 * RequestError */ |
571 default: | 630 d12_stallendpt(D12_ENDPOINT_EP0_IN); |
572 d12_stallctrlendpt(); | 631 d12_stallendpt(D12_ENDPOINT_EP0_OUT); |
573 break; | 632 break; |
574 } | 633 } |
575 } else { | 634 if (buffer[0] & 0x08) |
576 /* This is a Data Packet */ | 635 buffer[0] = 0x01; |
577 } | 636 else |
578 | 637 buffer[0] = 0x00; |
579 } | 638 buffer[1] = 0x00; |
580 | 639 d12_write_endpt(D12_ENDPOINT_EP0_IN, buffer, 2); |
581 /* Reset the micro */ | 640 break; |
641 | |
642 default: | |
643 /* Unsupported - Request Error - Stall */ | |
644 d12_stallendpt(D12_ENDPOINT_EP0_IN); | |
645 d12_stallendpt(D12_ENDPOINT_EP0_OUT); | |
646 break; | |
647 } | |
648 break; | |
649 case VENDOR_DEVICE_REQUEST: | |
650 case VENDOR_ENDPOINT_REQUEST: | |
651 switch (setuppkt.bRequest) { | |
652 case VENDOR_RESET: | |
653 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); | |
654 _delay_us(1000); | |
655 /* disconnect from USB */ | |
656 buffer[0] = D12_MODE_0 & 0xef; | |
657 buffer[1] = D12_MODE_1; | |
658 d12_write_cmd(D12_SET_MODE, buffer, 2); | |
659 _delay_us(1000); | |
660 cli(); | |
661 reset(); | |
662 /* NOT REACHED */ | |
663 break; | |
664 | |
665 case VENDOR_UPDATE: | |
666 d12_write_endpt(D12_ENDPOINT_EP0_IN, NULL, 0); | |
667 _delay_us(1000); | |
668 /* disconnect from USB */ | |
669 buffer[0] = D12_MODE_0 & 0xef; | |
670 buffer[1] = D12_MODE_1; | |
671 d12_write_cmd(D12_SET_MODE, buffer, 2); | |
672 _delay_us(1000); | |
673 cli(); | |
674 bootloader(); | |
675 /* NOT REACHED */ | |
676 break; | |
677 | |
678 default: | |
679 d12_stallendpt(D12_ENDPOINT_EP0_IN); | |
680 d12_stallendpt(D12_ENDPOINT_EP0_OUT); | |
681 break; | |
682 } | |
683 break; | |
684 case VENDOR_INTERFACE_REQUEST: | |
685 switch (setuppkt.bRequest) { | |
686 default: | |
687 d12_stallendpt(D12_ENDPOINT_EP0_IN); | |
688 d12_stallendpt(D12_ENDPOINT_EP0_OUT); | |
689 break; | |
690 } | |
691 break; | |
692 default: | |
693 d12_stallendpt(D12_ENDPOINT_EP0_IN); | |
694 d12_stallendpt(D12_ENDPOINT_EP0_OUT); | |
695 break; | |
696 } | |
697 } | |
698 | |
699 | |
700 /******************************************************************************* | |
701 ** reset | |
702 ** | |
703 ** Reset the micro by triggering the watchdog timer. | |
704 ** | |
705 */ | |
582 static void | 706 static void |
583 reset(void) { | 707 reset(void) { |
708 uart_putsP(PSTR("Resetting!\n\r")); | |
709 _delay_us(1000); | |
710 | |
711 /* Disable the interrupts */ | |
584 MCUCR = _BV(IVCE); | 712 MCUCR = _BV(IVCE); |
585 MCUCR = 0; | 713 MCUCR = 0; |
714 | |
715 /* Enable watchdog, smallest prescaler */ | |
586 WDTCR = _BV(WDE); | 716 WDTCR = _BV(WDE); |
717 | |
718 /* Wait for oblivion! */ | |
587 for (;;) | 719 for (;;) |
588 ; | 720 ; |
589 } | 721 } |
590 | 722 |
723 /******************************************************************************* | |
724 ** d12_getdescriptor | |
725 ** | |
726 ** Handle returning the various descriptor to the host | |
727 ** | |
728 ** Note: that we need to truncate the request because the host first | |
729 ** requests the first 2 bytes to find out then size, then requests the | |
730 ** rest. | |
731 */ | |
591 void | 732 void |
592 d12_getdescriptor(USB_SETUP_REQUEST *setuppkt) { | 733 d12_getdescriptor(USB_SETUP_REQUEST *setuppkt) { |
593 switch ((setuppkt->wValue & 0xff00) >> 8) { | 734 switch ((setuppkt->wValue & 0xff00) >> 8) { |
594 case TYPE_DEVICE_DESCRIPTOR: | 735 case TYPE_DEVICE_DESCRIPTOR: |
595 pSendBuffer = (const uint8_t *)&DeviceDescriptor; | 736 sendbuffer0 = (const uint8_t *)&DeviceDescriptor; |
596 BytesToSend = DeviceDescriptor.bLength; | 737 sendbytes0 = DeviceDescriptor.bLength; |
597 send_Bytes = 1; | 738 if (sendbytes0 >= setuppkt->wLength) |
598 if (BytesToSend >= setuppkt->wLength) { | 739 sendbytes0 = setuppkt->wLength; |
599 BytesToSend = setuppkt->wLength; | 740 |
600 exact_Bytes = 1; | 741 d12_send_data_ep0(); |
601 } else { | |
602 exact_Bytes = 0; | |
603 } | |
604 d12_write_buffer_ep0(); | |
605 break; | 742 break; |
606 | 743 |
607 case TYPE_CONFIGURATION_DESCRIPTOR: | 744 case TYPE_CONFIGURATION_DESCRIPTOR: |
608 pSendBuffer = (const uint8_t *)&ConfigurationDescriptor; | 745 sendbuffer0 = (const uint8_t *)&ConfigurationDescriptor; |
609 BytesToSend = sizeof(ConfigurationDescriptor); | 746 sendbytes0 = sizeof(ConfigurationDescriptor); |
610 send_Bytes = 1; | 747 if (sendbytes0 >= setuppkt->wLength) |
611 if (BytesToSend >= setuppkt->wLength) { | 748 sendbytes0 = setuppkt->wLength; |
612 BytesToSend = setuppkt->wLength; | 749 |
613 exact_Bytes = 1; | 750 d12_send_data_ep0(); |
614 } else { | |
615 exact_Bytes = 0; | |
616 } | |
617 d12_write_buffer_ep0(); | |
618 break; | 751 break; |
619 | 752 |
620 case TYPE_STRING_DESCRIPTOR: | 753 case TYPE_STRING_DESCRIPTOR: |
621 switch (setuppkt->wValue & 0xFF) { | 754 switch (setuppkt->wValue & 0xFF) { |
622 | |
623 case 0: | 755 case 0: |
624 pSendBuffer = (const uint8_t *)&LANGID_Descriptor; | 756 sendbuffer0 = (const uint8_t *)&LANGID_Descriptor; |
625 BytesToSend = LANGID_Descriptor.bLength; | 757 sendbytes0 = LANGID_Descriptor.bLength; |
626 break; | 758 break; |
627 | 759 |
628 case 1: | 760 case 1: |
629 pSendBuffer = (const uint8_t *)&Manufacturer_Descriptor; | 761 sendbuffer0 = (const uint8_t *)&Manufacturer_Descriptor; |
630 BytesToSend = Manufacturer_Descriptor.bLength; | 762 sendbytes0 = Manufacturer_Descriptor.bLength; |
631 break; | 763 break; |
632 | 764 |
633 case 2: | 765 case 2: |
634 pSendBuffer = (const uint8_t *)&Product_Descriptor; | 766 sendbuffer0 = (const uint8_t *)&Product_Descriptor; |
635 BytesToSend = Product_Descriptor.bLength; | 767 sendbytes0 = Product_Descriptor.bLength; |
636 break; | 768 break; |
637 | 769 |
638 case 3: | 770 case 3: |
639 pSendBuffer = (const uint8_t *)&Serial_Descriptor; | 771 sendbuffer0 = (const uint8_t *)&Serial_Descriptor; |
640 BytesToSend = Serial_Descriptor.bLength; | 772 sendbytes0 = Serial_Descriptor.bLength; |
641 break; | 773 break; |
642 | 774 |
643 default: | 775 default: |
644 pSendBuffer = NULL; | 776 sendbuffer0 = NULL; |
645 BytesToSend = 0; | 777 sendbytes0 = 0; |
646 } | 778 } |
647 send_Bytes = 1; | 779 if (sendbytes0 >= setuppkt->wLength) |
648 if (BytesToSend >= setuppkt->wLength) { | 780 sendbytes0 = setuppkt->wLength; |
649 BytesToSend = setuppkt->wLength; | 781 |
650 exact_Bytes = 1; | 782 d12_send_data_ep0(); |
651 } else { | 783 break; |
652 exact_Bytes = 0; | 784 |
653 } | |
654 d12_write_buffer_ep0(); | |
655 break; | |
656 default: | 785 default: |
657 d12_stallctrlendpt(); | 786 d12_stallendpt(D12_ENDPOINT_EP0_IN); |
658 break; | 787 d12_stallendpt(D12_ENDPOINT_EP0_OUT); |
659 } | 788 break; |
660 } | 789 } |
661 | 790 } |
662 | 791 |
792 /******************************************************************************* | |
793 ** d12_stallendpt | |
794 ** | |
795 ** Stall the nominated endpoint. | |
796 ** | |
797 */ | |
663 void | 798 void |
664 d12_stallctrlendpt(void) { | 799 d12_stallendpt(uint8_t ep) { |
665 uint8_t Buffer[] = {0x01}; | 800 uint8_t buffer[] = {0x01}; |
666 /* | 801 |
667 * 9.2.7 RequestError - return STALL PID in response to next DATA | 802 d12_write_cmd(D12_SET_ENDPOINT_STATUS + ep, buffer, 1); |
668 * Stage Transaction | 803 } |
669 */ | 804 |
670 d12_write_cmd(D12_SET_ENDPOINT_STATUS + D12_ENDPOINT_EP0_IN, Buffer, 1); | 805 /******************************************************************************* |
671 /* or in the status stage of the message. */ | 806 ** d12_read_cmd |
672 d12_write_cmd(D12_SET_ENDPOINT_STATUS + D12_ENDPOINT_EP0_OUT, Buffer, 1); | 807 ** |
673 } | 808 ** Read data from the nominated endpoint if it's full. |
674 | 809 ** |
810 */ | |
675 uint8_t | 811 uint8_t |
676 d12_read_endpt(uint8_t endpt, uint8_t *buffer) { | 812 d12_read_endpt(uint8_t endpt, uint8_t *buffer) { |
677 uint8_t d12header[2]; | 813 uint8_t d12header[2], status, i; |
678 uint8_t status = 0; | 814 |
679 uint8_t i; | 815 d12header[1] = 0; |
680 | 816 |
681 /* Select Endpoint */ | 817 /* Select Endpoint */ |
682 d12_read_cmd(endpt, &status, 1); | 818 d12_read_cmd(endpt, &status, 1); |
683 | 819 |
684 /* Check if Buffer is Full */ | 820 /* Check if buffer is Full */ |
685 if (status & 0x01) { | 821 if (status & 0x01) { |
686 set_d12_cmd(D12_READ_BUFFER); | 822 d12_set_cmd(D12_READ_BUFFER); |
687 d12header[0] = d12_get_data(); | 823 d12header[0] = d12_get_data(); |
688 d12header[1] = d12_get_data(); | 824 d12header[1] = d12_get_data(); |
689 if (d12header[1]) { | 825 if (d12header[1]) { |
690 for (i = 0; i < d12header[1]; i++) | 826 for (i = 0; i < d12header[1]; i++) |
691 buffer[i] = d12_get_data(); | 827 buffer[i] = d12_get_data(); |
695 | 831 |
696 } | 832 } |
697 return d12header[1]; | 833 return d12header[1]; |
698 } | 834 } |
699 | 835 |
836 /******************************************************************************* | |
837 ** d12_read_cmd | |
838 ** | |
839 ** Write data to the nominated endpoint. | |
840 ** | |
841 */ | |
700 void | 842 void |
701 d12_write_endpt(uint8_t endpt, const uint8_t *buffer, uint8_t bytes) { | 843 d12_write_endpt(uint8_t endpt, const uint8_t *buffer, uint8_t bytes) { |
702 uint8_t status = 0; | 844 uint8_t status, i; |
703 uint8_t i; | |
704 | 845 |
705 /* Select Endpoint */ | 846 /* Select Endpoint */ |
706 d12_read_cmd(endpt, &status, 1); | 847 d12_read_cmd(endpt, &status, 1); |
848 if ((status & 0x01) != 0) { | |
849 uart_putsP(PSTR("Endpoint ")); | |
850 uart_puts_dec(endpt / 2, 0); | |
851 uart_putsP(PSTR(" IN is full..\n\r")); | |
852 return; | |
853 } | |
854 | |
707 /* Write Header */ | 855 /* Write Header */ |
708 set_d12_cmd(D12_WRITE_BUFFER); | 856 d12_set_cmd(D12_WRITE_BUFFER); |
709 set_d12_data(0x00); | 857 d12_set_data(0x00); |
710 set_d12_data(bytes); | 858 d12_set_data(bytes); |
711 /* Write Packet */ | 859 /* Write Packet */ |
712 if (bytes) { | 860 if (bytes) { |
713 for (i = 0; i < bytes; i++) { | 861 for (i = 0; i < bytes; i++) |
714 set_d12_data(buffer[i]); | 862 d12_set_data(buffer[i]); |
715 } | 863 } |
716 } | 864 /* Validate buffer */ |
717 /* Validate Buffer */ | |
718 d12_write_cmd(D12_VALIDATE_BUFFER, NULL, 0); | 865 d12_write_cmd(D12_VALIDATE_BUFFER, NULL, 0); |
719 } | 866 } |
720 | 867 |
868 /******************************************************************************* | |
869 ** d12_send_data_ep0 | |
870 ** | |
871 ** Send the next FIFOs worth of data to the endpoint and update the | |
872 ** pointer and counters. | |
873 ** | |
874 ** d12_send_data_epX should be collapsed together but it's more | |
875 ** complex than it looks. | |
876 ** | |
877 */ | |
721 void | 878 void |
722 d12_write_buffer_ep0(void) { | 879 d12_send_data_ep0(void) { |
723 uint8_t BufferStatus = 1; | 880 uint8_t status; |
724 | 881 |
725 if (send_Bytes == 0) { | 882 /* Select endpoint */ |
883 d12_read_cmd(D12_ENDPOINT_EP0_IN, &status, 1); | |
884 | |
885 if (status & 0x01) /* Bail if the buffer is full */ | |
726 return; | 886 return; |
727 } | 887 |
728 | 888 if (sendbytes0 == 0) { |
729 /* Read Buffer Full Status */ | 889 /* Nothing to do */ |
730 d12_read_cmd(D12_ENDPOINT_EP0_IN, &BufferStatus, 1); | 890 } else if (sendbytes0 >= EP0_FIFO_SZ) { |
731 if (BufferStatus != 0) {/* Buffer Full */ | 891 /* Write another EP0_FIFO_SZ Bytes to buffer and send */ |
732 return; | 892 d12_write_endpt(D12_ENDPOINT_EP0_IN, sendbuffer0, EP0_FIFO_SZ); |
733 } | 893 sendbuffer0 += EP0_FIFO_SZ; |
734 | 894 sendbytes0 -= EP0_FIFO_SZ; |
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 | |
740 * Length packet | |
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 { | 895 } else { |
753 /* Buffer must have less than EP0_SIZE bytes left */ | 896 /* Buffer must have less than EP0_FIFO_SZ bytes left */ |
754 d12_write_endpt(D12_ENDPOINT_EP0_IN, pSendBuffer, BytesToSend); | 897 d12_write_endpt(D12_ENDPOINT_EP0_IN, sendbuffer0, sendbytes0); |
755 | 898 sendbytes0 = 0; |
756 BytesToSend = 0; | 899 } |
757 send_Bytes = 0; | 900 } |
758 } | 901 |
759 } | 902 /******************************************************************************* |
760 | 903 ** d12_send_data_ep2 |
904 ** | |
905 ** Send the next FIFOs worth of data to the endpoint and update the | |
906 ** pointer and counters. | |
907 ** | |
908 */ | |
761 void | 909 void |
762 d12_send_data_ep2(void) { | 910 d12_send_data_ep2(void) { |
763 uint8_t BufferStatus = 1; | 911 uint8_t status; |
764 | 912 |
765 /* Read Buffer Full Status */ | 913 /* Select endpoint */ |
766 d12_read_cmd(D12_ENDPOINT_EP2_IN, &BufferStatus, 1); | 914 d12_read_cmd(D12_ENDPOINT_EP2_IN, &status, 1); |
767 if (BufferStatus == 0) { /* Buffer Empty */ | 915 |
768 if (BytesToSend2 == 0) { | 916 if (status & 0x01) /* Bail if the buffer is full */ |
769 /* Nothing to do */ | 917 return; |
770 send_packet2 = 0; | 918 |
771 } else if (BytesToSend2 >= 64) { | 919 if (sendbytes2 == 0) { |
772 /* Write another 64 Bytes to buffer and send */ | 920 /* Nothing to do */ |
773 d12_write_endpt(D12_ENDPOINT_EP2_IN, pSendBuffer2, 64); | 921 } else if (sendbytes2 >= EP2_FIFO_SZ) { |
774 pSendBuffer2 += 64; | 922 /* Write another EP2_FIFO_SZ Bytes to buffer and send */ |
775 BytesToSend2 -= 64; | 923 d12_write_endpt(D12_ENDPOINT_EP2_IN, sendbuffer2, EP2_FIFO_SZ); |
776 } else { | 924 sendbuffer2 += EP2_FIFO_SZ; |
777 /* Buffer must have less than 64 bytes left */ | 925 sendbytes2 -= EP2_FIFO_SZ; |
778 d12_write_endpt(D12_ENDPOINT_EP2_IN, pSendBuffer2, BytesToSend2); | 926 } else { |
779 BytesToSend2 = 0; | 927 /* Buffer must have less than EP2_FIFO_SZ bytes left */ |
780 send_packet2 = 0; | 928 d12_write_endpt(D12_ENDPOINT_EP2_IN, sendbuffer2, sendbytes2); |
781 } | 929 sendbytes2 = 0; |
782 } | 930 } |
783 } | 931 } |
784 | 932 |
933 /******************************************************************************* | |
934 ** d12_receive_data_ep2 | |
935 ** | |
936 ** Get the next FIFOs worth of data from the endpoint | |
937 ** | |
938 */ | |
785 void | 939 void |
786 d12_receive_data_ep2(void) { | 940 d12_receive_data_ep2(void) { |
787 uint8_t D12Header[2]; | 941 uint8_t d12header[2], bytes, i, status; |
788 uint8_t bytes; | 942 |
789 uint8_t BufferStatus = 0; | |
790 uint8_t i; | |
791 | |
792 /* Select Endpoint */ | 943 /* Select Endpoint */ |
793 d12_read_cmd(D12_ENDPOINT_EP2_OUT, &BufferStatus, 1); | 944 d12_read_cmd(D12_ENDPOINT_EP2_OUT, &status, 1); |
945 | |
946 if (!(status & 0x01)) /* Bail if the buffer is empty */ | |
947 return; | |
948 | |
949 /* Read header */ | |
950 d12_set_cmd(D12_READ_BUFFER); | |
951 d12header[0] = d12_get_data(); | |
952 d12header[1] = d12_get_data(); | |
953 bytes = d12header[1]; | |
954 | |
955 packetlen2 = 0; | |
956 | |
957 for (i = 0; i < bytes; i++) | |
958 packet2[i] = d12_get_data(); | |
959 | |
960 packetlen2 += bytes; | |
961 | |
962 /* Allow new packets to be accepted */ | |
963 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); | |
964 | |
965 uart_putsP(PSTR("Got ")); | |
966 uart_puts_dec(bytes, 0); | |
967 uart_putsP(PSTR(" bytes from the host\n\r")); | |
968 | |
969 parsebuf(packet2, D12_ENDPOINT_EP2_IN); | |
970 | |
971 } | |
972 | |
973 /******************************************************************************* | |
974 ** d12_receive_data_ep1 | |
975 ** | |
976 ** Get the next FIFOs worth of data from the endpoint | |
977 ** | |
978 */ | |
979 void | |
980 d12_receive_data_ep1(void) { | |
981 uint8_t d12header[2], bytes, i, status; | |
982 | |
983 /* Select Endpoint */ | |
984 d12_read_cmd(D12_ENDPOINT_EP1_OUT, &status, 1); | |
985 | |
794 /* Check if Buffer is Full */ | 986 /* Check if Buffer is Full */ |
795 if (BufferStatus & 0x01) { | 987 if (!(status & 0x01)) |
796 /* Read header */ | 988 return; |
797 set_d12_cmd(D12_READ_BUFFER); | 989 |
798 D12Header[0] = d12_get_data(); | 990 /* Read header */ |
799 D12Header[1] = d12_get_data(); | 991 d12_set_cmd(D12_READ_BUFFER); |
800 bytes = D12Header[1]; | 992 d12header[0] = d12_get_data(); |
801 /* TODO check if the packet is not too long */ | 993 d12header[1] = d12_get_data(); |
802 uart_putsP(PSTR("Got data\n\r")); | 994 bytes = d12header[1]; |
803 for (i = 0; i < bytes; i++) { | 995 |
804 packet2[packetlen2 + i] = d12_get_data(); | 996 packetlen1 = 0; |
805 uart_puts_hex(packet2[packetlen2 + i]); | 997 |
806 uart_putsP(PSTR(" ")); | 998 for (i = 0; i < bytes; i++) |
807 } | 999 packet1[i] = d12_get_data(); |
808 uart_putsP(PSTR("\n\r")); | 1000 |
809 packetlen2 += bytes; | 1001 packetlen1 += bytes; |
810 /* Allow new packets to be accepted */ | 1002 |
811 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); | 1003 uart_putsP(PSTR("Got ")); |
812 if (bytes == 0 || bytes < 64) { /* request complete */ | 1004 uart_puts_dec(bytes, 0); |
813 pSendBuffer2 = packet2; | 1005 uart_putsP(PSTR(" bytes from the host\n\r")); |
814 send_packet2 = 1; | 1006 |
815 packetlen2 = 0; | 1007 /* Allow new packets to be accepted */ |
816 d12_send_data_ep2(); | 1008 d12_write_cmd(D12_CLEAR_BUFFER, NULL, 0); |
817 } | 1009 |
818 } | 1010 parsebuf(packet1, D12_ENDPOINT_EP1_IN); |
819 } | 1011 } |
1012 | |
1013 void | |
1014 parsebuf(uint8_t *buffer, uint8_t ep) { | |
1015 int i; | |
1016 | |
1017 switch (buffer[0]) { | |
1018 case 0x00: | |
1019 uart_putsP(PSTR("OWTouchReset()\n\r")); | |
1020 (int8_t)buffer[0] = OWTouchReset(); | |
1021 d12_write_endpt(ep, buffer, 1); | |
1022 break; | |
1023 | |
1024 case 0x01: | |
1025 uart_putsP(PSTR("OWFirst()\n\r")); | |
1026 (int8_t)buffer[0] = OWFirst(&buffer[1], 1, 0); | |
1027 for (i = 0; i < 9; i++) { | |
1028 uart_puts_hex(buffer[i + 1]); | |
1029 uart_putsP(PSTR(" ")); | |
1030 } | |
1031 uart_putsP(PSTR("\n\r")); | |
1032 d12_write_endpt(ep, buffer, 9); | |
1033 break; | |
1034 | |
1035 case 0x02: | |
1036 uart_putsP(PSTR("OWNext()\n\r")); | |
1037 (int8_t)buffer[0] = OWNext(&buffer[1], 1, 0); | |
1038 d12_write_endpt(ep, buffer, 9); | |
1039 break; | |
1040 | |
1041 case 0x03: | |
1042 uart_putsP(PSTR(" bytes, asked to do temperature conversion for ")); | |
1043 for (i = 0; i < 8; i++) { | |
1044 uart_puts_hex(buffer[i + 1]); | |
1045 if (i != 7) | |
1046 uart_putsP(PSTR(":")); | |
1047 } | |
1048 | |
1049 uart_putsP(PSTR("\n\r")); | |
1050 d12_write_endpt(ep, buffer, 9); | |
1051 | |
1052 break; | |
1053 | |
1054 default: | |
1055 uart_putsP(PSTR("Unknown command on endpoint 1\n\r")); | |
1056 break; | |
1057 } | |
1058 } |