1 /****************************************************************************************/
2 /* Example Source Code for USB Enumeration using a PDIUSBD11 connected to a PIC16F87x */
3 /* Copyright 2002 Craig Peacock, Craig.Peacock@beyondlogic.org */
4 /* Version 1.2, 6th April 2002 http://www.beyondlogic.org */
5 /****************************************************************************************/
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <drivers/ioport.h>
10 #include <drivers/usb.h>
11 #include "usbfull.h"
12 #include <ATJ2085_Ports.h>
13
14 void EP0SETUPInterrupt( void );
15
16 USB_DEVICE_DESCRIPTOR DeviceDescriptor = {
17 USB_DEVICE_DESCRIPTOR_SIZE, /* bLength */
18 TYPE_DEVICE_DESCRIPTOR, /* bDescriptorType */
19 0x0110, /* bcdUSB USB Version 1.1 */
20 0, /* bDeviceClass */
21 0, /* bDeviceSubclass */
22 0, /* bDeviceProtocol */
23 8, /* bMaxPacketSize 8 Bytes */
24 0x04B4, /* idVendor (Cypress Semi) */
25 0x0002, /* idProduct (USB Thermometer Example) */
26 0x0000, /* bcdDevice */
27 1, /* iManufacturer String Index */
28 0, /* iProduct String Index */
29 0, /* iSerialNumber String Index */
30 1 /* bNumberConfigurations */
31 };
32
33 #ifdef oldone
34 USB_CONFIG_DATA ConfigurationDescriptor = {
35 { /* configuration descriptor */
36 USB_CONFIGURATION_DESCRIPTOR_SIZE, /* bLength */
37 TYPE_CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
38 USB_CONFIG_DATA_SIZE, /* wTotalLength */
39 1, /* bNumInterfaces */
40 1, /* bConfigurationValue */
41 0, /* iConfiguration String Index */
42 0x80, /* bmAttributes Bus Powered, No Remote Wakeup */
43 0x32 /* bMaxPower, 100mA */
44 },
45 { /* interface descriptor */
46 USB_INTERFACE_DESCRIPTOR_SIZE, /* bLength */
47 TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */
48 0, /* bInterface Number */
49 0, /* bAlternateSetting */
50 2, /* bNumEndpoints */
51 0xFF, /* bInterfaceClass (Vendor specific) */
52 0xFF, /* bInterfaceSubClass */
53 0xFF, /* bInterfaceProtocol */
54 0 /* iInterface String Index */
55 },
56 { /* endpoint descriptor */
57 USB_ENDPOINT_DESCRIPTOR_SIZE, /* bLength */
58 TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */
59 0x01, /* bEndpoint Address EP1 OUT */
60 0x02, /* bmAttributes - Interrupt */
61 0x0008, /* wMaxPacketSize */
62 0x00 /* bInterval */
63 },
64 { /* endpoint descriptor */
65 USB_ENDPOINT_DESCRIPTOR_SIZE, /* bLength */
66 TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */
67 0x81, /* bEndpoint Address EP1 IN */
68 0x02, /* bmAttributes - Interrupt */
69 0x0008, /* wMaxPacketSize */
70 0x00 /* bInterval */
71 }
72 };
73 #endif
74
75 #define SIZEOF_CONFIG_DESCRIPTOR 32
76 static unsigned char ConfigurationDescriptor[]=
77 { 0x09, TYPE_CONFIGURATION_DESCRIPTOR, SIZEOF_CONFIG_DESCRIPTOR, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32,
78 0x09, TYPE_INTERFACE_DESCRIPTOR, 0x00, 0x00, 0x02, 0x08, 0x05, 0x50, 0x00,
79 0x07, TYPE_ENDPOINT_DESCRIPTOR, 0x01, 0x02, 0x40, 0x00, 0x00,
80 0x07, TYPE_ENDPOINT_DESCRIPTOR, 0x82, 0x02, 0x40, 0x00, 0x00 };
81
82 LANGID_DESCRIPTOR LANGID_Descriptor = { /* LANGID String Descriptor Zero */
83 LANGID_DESCRIPTOR_SIZE, /* bLength */
84 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
85 0x0409 /* LANGID US English */
86 };
87
88 MANUFACTURER_DESCRIPTOR ManufacturerDescriptor = { /* ManufacturerString 1 */
89 MANUFACTURER_DESCRIPTOR_SIZE, /* bLength */
90 TYPE_STRING_DESCRIPTOR, /* bDescriptorType */
91 "B\0e\0y\0o\0n\0d\0 l\0o\0g\0i\0c\0" /* ManufacturerString in UNICODE */
92 };
93
94 #define MAX_BUFFER_SIZE 80
95
96 unsigned char irqrcvd = 0xFF;
97
98 unsigned char circularbuffer[MAX_BUFFER_SIZE];
99 unsigned char inpointer;
100 unsigned char outpointer;
101
102 unsigned char *pSendBuffer;
103 unsigned char BytesToSend;
104 unsigned char CtlTransferInProgress;
105 unsigned char USBDeviceAddress = 0xAA;
106 unsigned char DeviceConfigured;
107
108 static unsigned char IPM_IDM_FB_Keeper;
109 static unsigned char ACK_Request_Sense_command = 0;
110 static unsigned char First_inquiry_command_flag = 0;
111 static unsigned char ConfigValue = 0;
112 static unsigned char AlternateSetting = 0;
113 static unsigned char USBPowerConnected = 0;
114 static unsigned char EP0DataCount;
115 unsigned char UramXAddr[30];
116
117 static unsigned int SPKeeper;
118 static unsigned int DeviceStatus = 0;
119 static unsigned int InterfaceStatus = 0;
120 static unsigned int EndPoint1OUTStatus = 0;
121 static unsigned int EndPoint1INStatus = 0;
122
123 #define PROGRESS_IDLE 0
124 #define PROGRESS_ADDRESS 3
125
126 #ifdef NOPE
D11GetIRQ(void)127 void D11GetIRQ(void)
128 {
129 if (Irq & USB_EP_CONTROL_READ)
130 {
131 if (CtlTransferInProgress == PROGRESS_ADDRESS)
132 {
133 D11CmdDataWrite(D11_SET_ADDRESS_ENABLE,&USBDeviceAddress,1);
134 D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP0_IN, Buffer, 1);
135
136 IOPORT_Set( USB_DEVADDR_REG, USB_DEVADDR_ENABLE + USBDeviceAddress );
137 CtlTransferInProgress = PROGRESS_IDLE;
138 }
139 else
140 {
141 D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP0_IN, Buffer, 1);
142 WriteBufferToEP0();
143 }
144 }
145
146 if (Irq & USB_EP_ENDPOINT1_OUT)
147 {
148 D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP1_OUT, Buffer, 1);
149 bytes = D11ReadEndpoint(D11_ENDPOINT_EP1_OUT, Buffer);
150 for (count = 0; count < bytes; count++)
151 {
152 circularbuffer[inpointer++] = Buffer[count];
153 if (inpointer >= MAX_BUFFER_SIZE)
154 inpointer = 0;
155 }
156 loadfromcircularbuffer(); //Kick Start
157 }
158
159 if (Irq & USB_EP_ENDPOINT1_IN)
160 {
161 D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP1_IN, Buffer, 1);
162 loadfromcircularbuffer();
163 }
164
165 }
166 #endif
167
168
ConfigureStall_EP1_OUT(void)169 void ConfigureStall_EP1_OUT( void )
170 {
171 #asm
172 ConfigureStall_EP1_OUT:
173 ld bc,01bfh ; Stall EP1_OUT
174 call SetEp1OutMode ; b->(USB_EPI_MODE_REG), c->(USB_EPI_MPS_REG)
175 xor a
176 out (USB_EPI_CNTR_HI_REG),a
177 ld a,64
178 out (USB_EPI_CNTR_LO_REG),a ;Stall
179
180 jp ConfigureStall_EP1_OUT_end
181
182 ;----------------------------------------------------------------------
183 ; b->(USB_EPI_MODE_REG), c->(USB_EPI_MPS_REG)
184 SetEp1OutMode:
185 ld a,USB_EPI_ENDPOINT1_OUT
186 out (USB_EPI_REG),a ; EPI=EP1_OUT
187 ld a,b
188 out (USB_EPI_MODE_REG),a
189 ld a,c
190 out (USB_EPI_MPS_REG),a
191 xor a
192 out (USB_EPI_START_ADDR_HI_REG),a
193 out (USB_EPI_START_ADDR_LO_REG),a
194 ld a,USB_EP_ENDPOINT1_OUT
195 out (USB_EP_STATUS_REG),a
196 ret
197
198 ConfigureStall_EP1_OUT_end:
199 #endasm
200 }
201
202
ConfigureStall_EP1_IN(void)203 void ConfigureStall_EP1_IN( void )
204 {
205 #asm
206 ConfigureStall_EP1_IN:
207 ld bc,01bfh ; Stall EP1_IN
208 call SetEp1InMode ; b->(USB_EPI_MODE_REG), c->(USB_EPI_MPS_REG)
209 xor a
210 out (USB_EPI_CNTR_HI_REG),a
211 ld a,64
212 out (USB_EPI_CNTR_LO_REG),a ; Stall
213
214 jp ConfigureStall_EP1_IN_end
215
216 ;----------------------------------------------------------------------
217 ; b->(USB_EPI_MODE_REG), c->(USB_EPI_MPS_REG)
218 SetEp1InMode:
219 ld a,USB_EPI_ENDPOINT1_IN
220 out (USB_EPI_REG),a ; EPI=EP1_IN
221 ld a,b ; Stall EP1_OUT
222 out (USB_EPI_MODE_REG),a
223 ld a,c
224 out (USB_EPI_MPS_REG),a
225 xor a
226 out (USB_EPI_START_ADDR_HI_REG),a
227 out (USB_EPI_START_ADDR_LO_REG),a
228 ld a,USB_EP_ENDPOINT1_IN
229 out (USB_EP_STATUS_REG),a
230 ret
231
232 ConfigureStall_EP1_IN_end:
233 #endasm
234 }
235
USBResetISR(void)236 void USBResetISR( void )
237 {
238 #asm
239 ;----------------------------------------------------------------------
240 ; USB Reset interrupt service routine
241 xor a
242 ld (_ACK_Request_Sense_command),a
243 ld (_First_inquiry_command_flag),a
244 ld (_ConfigValue),a
245 ld (_AlternateSetting),a
246
247 ld hl,0
248 ld (_DeviceStatus),hl
249 ld (_InterfaceStatus),hl
250 ld (_EndPoint1OUTStatus),hl
251 ld (_EndPoint1INStatus),hl
252
253 ld a,USB_DEVADDR_ENABLE ; enable USB SIE with address 0
254 out (USB_DEVADDR_REG),a
255
256 USBResetISR_ClearBR:
257 ld a, USB_EPI_CONTROL_READ
258 out (USB_EPI_REG),a ; EPI=Control_read
259 out (USB_EPI_CNTR_HI_REG),a
260 ld a, USB_EPI_CONTROL_WRITE
261 out (USB_EPI_REG),a ; EPI=Control_write
262 out (USB_EPI_CNTR_HI_REG),a
263 ld a, USB_EPI_ENDPOINT1_IN
264 out (USB_EPI_REG),a ; EPI=EP1_IN
265 out (USB_EPI_CNTR_HI_REG),a
266 ld a, USB_EPI_ENDPOINT1_OUT
267 out (USB_EPI_REG),a ; EPI=EP1_OUT
268 out (USB_EPI_CNTR_HI_REG),a
269 ld a, USB_EPI_ENDPOINT2_IN
270 out (USB_EPI_REG),a ; EPI=EP2_IN
271 out (USB_EPI_CNTR_HI_REG),a
272 ld a, USB_EPI_ENDPOINT2_OUT
273 out (USB_EPI_REG),a ; EPI=EP2_OUT
274 out (USB_EPI_CNTR_HI_REG),a
275 ld a, USB_EPI_ENDPOINT3_IN
276 out (USB_EPI_REG),a ; EPI=EP3_IN
277 out (USB_EPI_CNTR_HI_REG),a
278 ld a, USB_EPI_ENDPOINT3_OUT
279 out (USB_EPI_REG),a ; EPI=EP3_OUT
280 out (USB_EPI_CNTR_HI_REG),a
281
282 in a,(USB_EPI_EPSBR_REG)
283 cp 0
284 jr nz, USBResetISR_ClearBR
285
286 ld a,0xff ; Clear all pending interrupts
287 out (USB_INT_STATUS_REG),a
288 out (USB_EP_STATUS_REG),a
289 out (USB_EPI_EPSNS_REG),a
290 out (USB_EPI_EPSST_REG),a
291 #endasm
292 }
293
USBConnectISR(void)294 void USBConnectISR( void )
295 {
296 #asm
297 in a, (USB_STATUS_CONTROL_REG)
298 bit 6, a ; USB_STATUS_POWER
299 jr nz, USBConnectISR_Connected
300 xor a
301 ld (_USBPowerConnected),a
302 jp USBConnectISR_Exit
303
304 USBConnectISR_Connected:
305 ld a,0x01
306 ld (_USBPowerConnected),a
307 USBConnectISR_Exit:
308 #endasm
309 }
310
USB_ISREP_ControlRead(void)311 void USB_ISREP_ControlRead( void )
312 {
313
314
315 irqrcvd = 0x04;
316
317 #ifdef crap
318 if (CtlTransferInProgress == PROGRESS_ADDRESS)
319 {
320 #asm
321 ld a,(_USBDeviceAddress)
322 or USB_DEVADDR_ENABLE
323 out (USB_DEVADDR_REG),a ; Enable device with address
324 #endasm
325 /* IOPORT_Set( USB_DEVADDR_REG, USB_DEVADDR_ENABLE + USBDeviceAddress );*/
326 CtlTransferInProgress = PROGRESS_IDLE;
327 }
328 else
329 {
330 WriteBufferToEP0();
331 }
332 #endif
333 }
334
USB_ISR(void)335 void USB_ISR( void )
336 {
337 #asm
338 in a,(INTERNAL_MROM_SRAM_PAGE_REG)
339 ld (_IPM_IDM_FB_Keeper),a
340 ld (_SPKeeper),sp
341
342 in a,(USB_INT_STATUS_REG)
343
344 USB_ISR_Reset:
345 bit 7,a ;USB_INT_BUS_RESET
346 jp z, USB_ISR_EP0Setup
347 call _USBResetISR
348 ld a,USB_INT_BUS_RESET
349 out (USB_INT_STATUS_REG),a
350 jp USB_ISR_End
351
352 USB_ISR_EP0Setup:
353 bit 5,a ;USB_INT_EP0_SETUP
354 jp z, USB_ISR_Connect
355 call _EP0SETUPInterrupt
356 ld a,USB_INT_EP0_SETUP
357 out (USB_INT_STATUS_REG),a
358 jp USB_ISR_End
359
360 USB_ISR_Connect:
361 bit 6,a ;USB_INT_BUS_CON_DISC
362 jp z, USB_ISR_Wakeup
363 call _USBConnectISR
364 in a,(USB_INT_STATUS_REG)
365 or USB_INT_BUS_CON_DISC
366 out (USB_INT_STATUS_REG),a
367 jp USB_ISR_End
368
369 USB_ISR_Wakeup:
370 bit 4,a ;USB_INT_WAKEUP_IRQ
371 jp z, USB_ISR_EndPoint
372 ld a,USB_INT_WAKEUP_IRQ ; Clear the interrupt
373 out (USB_INT_STATUS_REG),a
374 jp USB_ISR_End
375
376 USB_ISR_EndPoint:
377 in a,(USB_EP_STATUS_REG)
378
379 bit 0,a ; USB_EP_CONTROL_READ
380 jp z, USB_ISR_EndPoint3
381 call _USB_ISREP_ControlRead
382 jp USB_ISR_End
383
384 USB_ISR_EndPoint3:
385 ; in a,(USB_EP_STATUS_REG)
386 ; bit 3,a ;USB_EP_ENDPOINT1_OUT
387 ; jp nz, EP1_OUT_ISR
388
389 ; ld a,0ffh ; All Irqs
390 ; out (USB_EP_STATUS_REG),a
391
392 USB_ISR_End:
393 ld sp,(_SPKeeper)
394 ld a,(_IPM_IDM_FB_Keeper)
395 out (INTERNAL_MROM_SRAM_PAGE_REG),a
396
397 ld a,0ffh ; All Irqs
398 out (USB_EP_STATUS_REG),a
399 ld a, 0xff
400 out (USB_INT_STATUS_REG), a
401 in a, (USB_IRQSTATUS_REG)
402 out (USB_IRQSTATUS_REG), a
403 #endasm
404 }
405
EP0StandardDeviceRequest(void)406 void EP0StandardDeviceRequest( void )
407 {
408 unsigned char ucEP0DataReg1;
409 unsigned char ucEP0DataReg2;
410 unsigned char Buffer[2];
411
412 ucEP0DataReg1 = IOPORT_Read( USB_SETUP_DATA1_REG );
413 ucEP0DataReg2 = IOPORT_Read( USB_SETUP_DATA2_REG );
414
415 switch (ucEP0DataReg1)
416 {
417 case GET_STATUS:
418 /* Get Status Request to Device should return */
419 /* Remote Wakeup and Self Powered Status */
420 Buffer[0] = 0x01;
421 Buffer[1] = 0x00;
422 WriteEP0( Buffer,2 );
423 break;
424
425 case CLEAR_FEATURE:
426 case SET_FEATURE:
427 /* We don't support DEVICE_REMOTE_WAKEUP or TEST_MODE */
428 ErrorStallControlEndPoint();
429 break;
430
431 case SET_ADDRESS:
432 USBDeviceAddress = ucEP0DataReg2;
433 WriteEP0( NULL, 0 );
434 CtlTransferInProgress = PROGRESS_ADDRESS;
435 break;
436
437 case GET_DESCRIPTOR:
438 GetDescriptor();
439 break;
440
441 case GET_CONFIGURATION:
442 WriteEP0( &DeviceConfigured, 1 );
443 break;
444
445 case SET_CONFIGURATION:
446 DeviceConfigured = ucEP0DataReg2;
447 WriteEP0( NULL, 0 );
448 break;
449
450 case SET_DESCRIPTOR:
451 default:
452 /* Unsupported - Request Error - Stall */
453 ErrorStallControlEndPoint();
454 break;
455
456 }
457 }
458
EP0StandardInterfaceRequest(void)459 void EP0StandardInterfaceRequest( void )
460 {
461 unsigned char ucEP0DataReg1;
462 unsigned char ucEP0DataReg2;
463 unsigned char ucEP0DataReg4;
464 unsigned char dummy_variable_for_stack_alignment;
465 unsigned char Buffer[2];
466
467 ucEP0DataReg1 = IOPORT_Read( USB_SETUP_DATA1_REG );
468 ucEP0DataReg2 = IOPORT_Read( USB_SETUP_DATA2_REG );
469 ucEP0DataReg4 = IOPORT_Read( USB_SETUP_DATA4_REG );
470
471 switch (ucEP0DataReg1)
472 {
473 case GET_STATUS:
474 /* Get Status Request to Interface should return */
475 /* Zero, Zero (Reserved for future use) */
476 Buffer[0] = 0x00;
477 Buffer[1] = 0x00;
478 WriteEP0( Buffer, 2 );
479 break;
480 case SET_INTERFACE:
481 /* Device Only supports default setting, Stall may be */
482 /* returned in the status stage of the request */
483 if (ucEP0DataReg2 == 0 && ucEP0DataReg4 == 0)
484 {
485 /* Interface Zero, Alternative Setting = 0 */
486 WriteEP0( NULL, 0 );
487 }
488 else
489 {
490 ErrorStallControlEndPoint();
491 }
492 break;
493 case GET_INTERFACE:
494 if (ucEP0DataReg4 == 0)
495 { /* Interface Zero */
496 Buffer[0] = 0; /* Alternative Setting */
497 WriteEP0( Buffer, 1 );
498 break;
499 } /* else fall through as RequestError */
500 case CLEAR_FEATURE:
501 case SET_FEATURE:
502 /* Interface has no defined features. Return RequestError */
503 default:
504 ErrorStallControlEndPoint();
505 break;
506 }
507 }
508
EP0StandardEndpointRequest(void)509 void EP0StandardEndpointRequest( void )
510 {
511 unsigned char ucEP0DataReg1;
512 unsigned char ucEP0DataReg2;
513 unsigned char ucEP0DataReg4;
514 unsigned char ucEP0DataReg5;
515 unsigned char dummy_variable_for_stack_alignment;
516 unsigned char Buffer[2];
517
518 ucEP0DataReg1 = IOPORT_Read( USB_SETUP_DATA1_REG );
519 ucEP0DataReg2 = IOPORT_Read( USB_SETUP_DATA2_REG );
520
521 ucEP0DataReg4 = IOPORT_Read( USB_SETUP_DATA4_REG );
522 ucEP0DataReg5 = IOPORT_Read( USB_SETUP_DATA5_REG );
523
524 switch (ucEP0DataReg1)
525 {
526 case CLEAR_FEATURE:
527 case SET_FEATURE:
528 /* Halt(Stall) feature required to be implemented on all Interrupt and */
529 /* Bulk Endpoints. It is not required nor recommended on the Default Pipe */
530
531 if (ucEP0DataReg2 == ENDPOINT_HALT)
532 {
533 if (ucEP0DataReg1 == CLEAR_FEATURE)
534 {
535 Buffer[0] = 0x00;
536 }
537 else
538 {
539 Buffer[0] = 0x01;
540 }
541 switch (ucEP0DataReg4)
542 {
543 case 0x01 :
544 EndPoint1OUTStatus = 0x01; /* Enabled */
545 ConfigureStall_EP1_OUT();
546 break;
547 case 0x81 :
548 EndPoint1INStatus = 0x01; /* Enabled */
549 ConfigureStall_EP1_IN();
550 break;
551 default :
552 /* Invalid Endpoint - RequestError */
553 ErrorStallControlEndPoint();
554 break;
555 }
556
557 WriteEP0( NULL, 0);
558 }
559 else
560 {
561 /* No other Features for Endpoint - Request Error */
562 ErrorStallControlEndPoint();
563 }
564 break;
565
566 case GET_STATUS:
567 /* Get Status Request to Endpoint should return */
568 /* Halt Status in D0 for Interrupt and Bulk */
569 switch (ucEP0DataReg4)
570 {
571 case 0x01 :
572 Buffer[0] = EndPoint1OUTStatus;
573 break;
574 case 0x81 :
575 Buffer[0] = EndPoint1INStatus;
576 break;
577 default :
578 /* Invalid Endpoint - RequestError */
579 ErrorStallControlEndPoint();
580 break;
581 }
582
583 Buffer[1] = 0x00;
584 WriteEP0( Buffer, 2);
585 break;
586
587 default:
588 /* Unsupported - Request Error - Stall */
589 ErrorStallControlEndPoint();
590 break;
591 }
592 }
593
594
EP0SETUPInterrupt(void)595 void EP0SETUPInterrupt( void )
596 {
597
598 irqrcvd = 0x02;
599 /* unsigned char dummy_variable_for_stack_alignment;
600 unsigned char Buffer[2];
601 unsigned char ucEP0DataReg0;*/
602
603 /* ucEP0DataReg0 = IOPORT_Read( USB_SETUP_DATA0_REG );
604 */
605 /* switch (ucEP0DataReg0&0x7F)*/
606 /*#ifdef crap*/
607 switch (0x01)
608 {
609 case STANDARD_DEVICE_REQUEST:
610 irqrcvd |= 0x01;
611 EP0StandardDeviceRequest();
612 break;
613 case STANDARD_INTERFACE_REQUEST:
614 irqrcvd |= 0x02;
615 EP0StandardInterfaceRequest();
616 break;
617 case STANDARD_ENDPOINT_REQUEST:
618 irqrcvd |= 0x04;
619 EP0StandardEndpointRequest();
620 break;
621 default:
622 irqrcvd |= 0x08;
623 ErrorStallControlEndPoint();
624 break;
625 }
626 /* #endif*/
627 }
628
GetDescriptor(void)629 void GetDescriptor( void )
630 {
631 unsigned char ucEP0DataReg2;
632 unsigned char ucEP0DataReg3;
633 unsigned char ucEP0DataReg6;
634
635 ucEP0DataReg2 = IOPORT_Read( USB_SETUP_DATA2_REG );
636 ucEP0DataReg3 = IOPORT_Read( USB_SETUP_DATA3_REG );
637 ucEP0DataReg6 = IOPORT_Read( USB_SETUP_DATA6_REG );
638
639 switch(ucEP0DataReg3)
640 {
641 case TYPE_DEVICE_DESCRIPTOR:
642 /* pSendBuffer = (unsigned char *)&DeviceDescriptor;*/
643 pSendBuffer = DeviceDescriptor;
644 BytesToSend = DeviceDescriptor.bLength;
645 if (BytesToSend > ucEP0DataReg6)
646 BytesToSend = ucEP0DataReg6;
647 WriteBufferToEP0();
648 break;
649
650 case TYPE_CONFIGURATION_DESCRIPTOR:
651 pSendBuffer = ConfigurationDescriptor;
652 BytesToSend = sizeof(ConfigurationDescriptor);
653 if (BytesToSend > ucEP0DataReg6)
654 BytesToSend = ucEP0DataReg6;
655 WriteBufferToEP0();
656 break;
657
658 case TYPE_STRING_DESCRIPTOR:
659 switch (ucEP0DataReg2)
660 {
661 case 0 :
662 /* pSendBuffer = (unsigned char*)&LANGID_Descriptor;*/
663 pSendBuffer = LANGID_Descriptor;
664 BytesToSend = sizeof(LANGID_Descriptor);
665 break;
666
667 case 1 :
668 /* pSendBuffer = (unsigned char *)&ManufacturerDescriptor; */
669 pSendBuffer = ManufacturerDescriptor;
670 BytesToSend = sizeof(ManufacturerDescriptor);
671 break;
672
673 default : pSendBuffer = NULL;
674 BytesToSend = 0;
675 }
676 if (BytesToSend > ucEP0DataReg6)
677 BytesToSend = ucEP0DataReg6;
678 WriteBufferToEP0();
679 break;
680 default:
681 ErrorStallControlEndPoint();
682 break;
683 }
684 }
685
ErrorStallControlEndPoint(void)686 void ErrorStallControlEndPoint(void)
687 {
688 #asm
689 ld b, USB_EPI_MODE_STALL
690 ld c, 0xc7 ; data = 8 | USB_EPI_MPS_FORCE_TOGGLE | USB_EPI_MPS_CURRENT_TOGGLE
691 call SetEp0WrMode ; b->(USB_EPI_MODE_REG), c->(USB_EPI_MPS_REG)
692 xor a
693 out (USB_EPI_CNTR_LO_REG),a
694
695 jp end_ErrorStallControlEndPoint
696
697 ;----------------------------------------------------------------------
698 ; b->(USB_EPI_MODE_REG), c->(USB_EPI_MPS_REG)
699 SetEp0WrMode:
700 ld a,USB_EPI_CONTROL_WRITE
701 out (USB_EPI_REG),a ; EPI=Control-write
702 ld a,b
703 out (USB_EPI_MODE_REG),a ; STALL IN/OUT
704 ld a,c
705 out (USB_EPI_MPS_REG),a
706 xor a
707 out (USB_EPI_START_ADDR_HI_REG),a
708 out (USB_EPI_START_ADDR_LO_REG),a
709 out (USB_EPI_CNTR_HI_REG),a
710 ret
711
712 end_ErrorStallControlEndPoint:
713 #endasm
714 }
715
WriteEP0(unsigned char * Buffer,unsigned char Bytes)716 void WriteEP0( unsigned char *Buffer, unsigned char Bytes )
717 {
718 /*
719 Buffer = 0x1234;
720 Bytes = 2;
721
722 ;Buffer = 0x1234;
723 LINE 710
724 ld hl,4 ;const
725 add hl,sp
726 ld de,4660 ;const
727 ex de,hl
728 call l_pint
729 ;Bytes = 2;
730 LINE 711
731 ld hl,2 ;const
732 add hl,sp
733 ld (hl),#(2 % 256 % 256)
734 ld l,(hl)
735 ld h,0
736 */
737 #asm
738 ; a = Bytes
739 ld hl,2 ;const
740 add hl,sp
741 ld a,(hl)
742
743 ; hl = Buffer
744 ld hl,4 ;const
745 add hl,sp
746 ld d, (hl)
747 dec hl
748 ld e, (hl)
749 ex de,hl
750
751 ;----------------------------------------------------------------------
752 ; Perform control read operation
753 ; hl: start position
754 ; a: size of the data should be returned
755 ;----------------------------------------------------------------------
756 control_read:
757 call get_descriptor_length
758
759 ld c,a
760 ld b,0
761 ld a,0f7h
762 out (INTERNAL_MROM_SRAM_PAGE_REG),a
763 in a,(B1_2_MEMMAP_REG)
764 or B1_2_MEMMAP_B1_B2
765 out (B1_2_MEMMAP_REG),a
766 ld de,_UramXAddr
767 ldir
768
769 in a,(B1_2_MEMMAP_REG)
770 and 0xcf
771 or B1_2_MEMMAP_B2
772 out (B1_2_MEMMAP_REG),a
773
774 ; ld bc,03c7h ; complete=1,stall=1
775 ld b, USB_EPI_MODE_COMPLETE | USB_EPI_MODE_STALL
776 ; MPS = 8 | USB_EPI_MPS_FORCE_TOGGLE | USB_EPI_MPS_CURRENT_TOGGLE
777 ld c, USB_EPI_MPS_FORCE_TOGGLE | USB_EPI_MPS_CURRENT_TOGGLE | 7
778 call sSet_Ep0_Rd_Mode ; b->(USB_EPI_MODE_REG), c->(USB_EPI_MPS_REG)
779
780 ld a,(_EP0DataCount)
781 call sWait_Ep0_Send_Out
782
783 jr lsControlReadRet
784 lsPremature_Terminate:
785 lsControlReadRet:
786 jp ControlRead_end
787
788
789 ;*******************************************************************************
790 ;* Subroutine
791 ;* b->(USB_EPI_MODE_REG), c->(USB_EPI_MPS_REG)
792 ;*******************************************************************************
793 sSet_Ep0_Rd_Mode:
794 xor a ; a = USB_EPI_CONTROL_READ
795 out (USB_EPI_REG),a ; EPI=Control-read
796 ld a,b
797 out (USB_EPI_MODE_REG),a
798 ld a,c
799 out (USB_EPI_MPS_REG),a
800 xor a
801 out (USB_EPI_START_ADDR_HI_REG),a
802 out (USB_EPI_START_ADDR_LO_REG),a
803 out (USB_EPI_CNTR_HI_REG),a
804 ret
805
806 ;----------------------------------------------------------------------
807 get_descriptor_length:
808 ld (_EP0DataCount),a
809 ld b,a
810 in a,(USB_SETUP_DATA7_REG)
811 or a
812 jr nz,use_actual_length
813 in a,(USB_SETUP_DATA6_REG)
814 or a
815 jr z,use_actual_length
816 cp b
817 jr nc,use_actual_length
818 ld (_EP0DataCount),a
819 use_actual_length:
820 ld a,(_EP0DataCount)
821 ret
822
823 ;----------------------------------------------------------------------
824 sWait_Ep0_Send_Out:
825 out (USB_EPI_CNTR_LO_REG),a
826 Check_Control_read_BR_Set:
827 in a,(USB_EPI_EPSBR_REG)
828 bit 0,a ; USB_EPI_EPSBR_CTL_READ
829 jr z,Check_Control_read_BR_Set
830 Check_Control_read_BR_Clear:
831 in a,(USB_EPI_EPSBR_REG)
832 bit 0,a ; USB_EPI_EPSBR_CTL_READ
833 jr nz,Check_Control_read_BR_Clear
834 ld a,USB_EP_CONTROL_READ
835 out (USB_EP_STATUS_REG),a
836 ret
837
838 ControlRead_end:
839 #endasm
840 }
841
842 /*
843 void WriteEP1( unsigned char *Buffer, unsigned char Bytes )
844 {
845 }
846 */
847
WriteBufferToEP0(void)848 void WriteBufferToEP0( void )
849 {
850 if (BytesToSend == 0) {
851 /* If BytesToSend is Zero and we get called again, assume buffer is smaller */
852 /* than Setup Request Size and indicate end by sending Zero Length packet */
853 WriteEP0( NULL, 0);
854 } else if (BytesToSend >= 8) {
855 /* Write another 8 Bytes to buffer and send */
856 WriteEP0( pSendBuffer, 8);
857 pSendBuffer += 8;
858 BytesToSend -= 8;
859 } else {
860 /* Buffer must have less than 8 bytes left */
861 WriteEP0( pSendBuffer, BytesToSend);
862 BytesToSend = 0;
863 }
864 }
865
866 #ifdef crap
loadfromcircularbuffer(void)867 void loadfromcircularbuffer(void)
868 {
869 unsigned char Buffer[10];
870 unsigned char count;
871
872 /* Read Buffer Full Status */
873 /* D11CmdDataRead(D11_ENDPOINT_EP1_IN, Buffer, 1);*/
874 if (Buffer[0] == 0)
875 {
876 /* Buffer Empty */
877 if (inpointer != outpointer)
878 {
879 /* We have bytes to send */
880 count = 0;
881 do
882 {
883 Buffer[count++] = circularbuffer[outpointer++];
884 if (outpointer >= MAX_BUFFER_SIZE)
885 outpointer = 0;
886 if (outpointer == inpointer)
887 break; /* No more data */
888 } while (count < 8); /* Maximum Buffer Size */
889 /* Now load it into EP1_In */
890 WriteEP1IN( Buffer, count);
891 }
892 }
893 }
894
895 #endif
896
897