]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/libs4c/usb/pdiusb/pdi.c
3229d360b54476fc699f9d0d6f0ea4d528b1cf4b
[lincan.git] / embedded / libs4c / usb / pdiusb / pdi.c
1 /*****************************************************/
2 /***   Module : USB PDI                            ***/
3 /***   Author : Roman Bartosinski (C) 28.04.2002   ***/
4 /***   Modify : 08.08.2002, 16.04.2003             ***/
5 /*****************************************************/
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <system_def.h>
10
11 #define USB_PDI_EXPORT_FNC
12
13 #include <usb/pdiusb.h>
14 #include <usb/pdi.h>
15 #include <usb/usbdebug.h>
16
17
18 /* init chip state */
19   void pdiInitChipState( void) {
20    #ifdef PDIUSBD11
21     pdiSetHUBAddressEnable( 0, 0);
22    #endif /*PDIUSBD11*/
23     pdiSetAddressEnable( PDI_ENAD_ENABLE);
24     pdiSetEndpointEnable( PDI_EPEN_ENABLE);
25   }
26  
27 #ifdef PDIUSBD11
28
29   #define PDI_MODE_BASE_VALUE (PDI_MODE_MUSTBEONE | \
30   PDI_MODE_REMOTE_WAKEUP | PDI_MODE_NO_LAZY_CLOCK | \
31   PDI_MODE_CLOCK_RUNNING | PDI_CLOCK_4M)
32
33 #else /*PDIUSBD11*/
34
35   #define PDI_MODE_BASE_VALUE (PDI_CLOCK_SET_TO_ONE | \
36   PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING | \
37   PDI_CLOCK_4M)
38
39 #endif /*PDIUSBD11*/
40
41
42 /* connect usb */
43   int usb_pdi_connect( usb_device_t *udev) {
44     pdiSetMode( PDI_MODE_BASE_VALUE | PDI_MODE_SOFT_CONNECT );
45     return 0;
46   }
47
48 /* disconnect usb */
49   int usb_pdi_disconnect( usb_device_t *udev) {
50     pdiSetMode( PDI_MODE_BASE_VALUE & ~PDI_MODE_SOFT_CONNECT );
51     return 0;
52   }
53
54 /* acknowledge control transfer */
55   void usb_pdi_ack_setup( usb_device_t *udev) {
56     pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
57   }
58
59
60 /* acknowledge control transfer */
61   void usb_pdi_ack_control_setup( usb_device_t *udev) {
62     pdiAckSetupControl();
63   }
64
65   
66 /**
67  * usb_pdi_check events
68  * function reads interrupt register and sets event flags
69  * function returns 1 if there is some new event.
70  * function returns 0 if there isn't new event but all is OK
71  * function returns -1 if there is any error
72 */
73   int usb_pdi_check_events( usb_device_t *udev) {
74     volatile unsigned char LastTrans = 0;
75     volatile unsigned int LastInt;
76     int ret = 0, i;
77
78     LastInt = pdiGetInterrupt();
79 if ( LastInt) {
80   usb_debug_print( DEBUG_LEVEL_LOW, ("PI=0x%04X\n", LastInt));
81 }
82     usb_debug_print( DEBUG_LEVEL_HIGH, ("PDI Int=0x%04X\n", LastInt));
83     
84     if ( LastInt & PDI_INT_BUSRESET) {                 // D12 - Bus reset reached
85       pdiInitChipState();
86       udev->flags |= USB_FLAG_BUS_RESET;
87       ret = 1;
88     } else {
89       #ifdef PDIUSBD12
90       if ( LastInt & PDI_INT_SUSPEND) {                 // D12 - Suspend flag changed
91         udev->flags |= USB_FLAG_SUSPEND;
92         ret = 1;
93       }
94       #endif
95
96             
97       if ( LastInt & PDI_INT_EP0_OUT) {                // D12 - Ep0RxDone - some data was received in EP0
98         LastTrans = pdiGetLastTransStatus( PDI_EP0_RX);
99         if ( LastTrans & PDI_LTSTAT_SETUP) { // setup packet
100           udev->flags |= USB_FLAG_SETUP;
101         } else {
102           udev->flags |= USB_FLAG_EVENT_RX0;
103         }
104         ret = 1;
105       }      
106       if ( LastInt & PDI_INT_EP0_IN) {                 // D12 - Ep0TxDone - data in EP0 was sended
107         LastTrans = pdiGetLastTransStatus( PDI_EP0_TX);
108         udev->flags |= USB_FLAG_EVENT_TX0;
109         ret = 1;
110       }
111
112       
113       for( i=0; i<udev->cntep; i++) {
114         if ( LastInt & (udev->ep+i)->event_mask) {
115           LastTrans = pdiGetLastTransStatus( (udev->ep+i)->epnum);
116           udev->ep_events |= 1<<i;
117           LastInt &= ~((udev->ep+i)->event_mask);
118           ret = 1;
119         }
120       }
121
122       /* check unsupported endpoints */
123       if ( LastInt & PDI_INT_EP1_OUT) {                // D12 - Ep1RxDone - some data was received in EP1
124         LastTrans = pdiGetLastTransStatus( PDI_EP1_RX);
125         pdiSetEpStatus( PDI_EP1_RX, PDI_SET_EP_STALLED);
126       }
127       if ( LastInt & PDI_INT_EP1_IN) {                 // D12 - Ep1TxDone - data in EP1 was sended
128         LastTrans = pdiGetLastTransStatus( PDI_EP1_TX);
129         pdiSetEpStatus( PDI_EP1_TX, PDI_SET_EP_STALLED);
130       }
131       if ( LastInt & PDI_INT_EP2_OUT) {                // D12 - Ep2RxDone - some data was received in EP2
132         LastTrans = pdiGetLastTransStatus( PDI_EP2_RX);
133         pdiSetEpStatus( PDI_EP2_RX, PDI_SET_EP_STALLED);
134       }
135       if ( LastInt & PDI_INT_EP2_IN) {                 // D12 - Ep2TxDone - data in EP2 was sended
136         LastTrans = pdiGetLastTransStatus( PDI_EP2_TX);
137         pdiSetEpStatus( PDI_EP2_TX, PDI_SET_EP_STALLED);
138       }
139      #if defined(PDIUSBD11) || defined(PDIUSBH11A_SINGLE)  // D11,H11_S
140       if ( LastInt & PDI_INT_EP3_OUT) {                // D11 - Ep3RxDone - some data was received in EP3
141         LastTrans = pdiGetLastTransStatus( PDI_EP3_RX);
142         pdiSetEpStatus( PDI_EP3_RX, PDI_SET_EP_STALLED);
143       }    
144       if ( LastInt & PDI_INT_EP3_IN) {                 // D11 - Ep3TxDone - data in EP3 was sended
145         LastTrans = pdiGetLastTransStatus( PDI_EP3_TX);
146         pdiSetEpStatus( PDI_EP3_TX, PDI_SET_EP_STALLED);
147       }
148      #endif /* D11,H11_S */
149     }
150     return ret;
151   }
152
153
154 /* stall endpoint X */
155   void usb_pdi_stall( usb_ep_t *ep) {
156     if ( ep->epnum) {
157       pdiSetEpStatus( ep->epnum, PDI_SET_EP_STALLED);
158     } else { // endpoint0
159       pdiSetEpStatus( PDI_EP0_TX, PDI_SET_EP_STALLED);
160       pdiSetEpStatus( PDI_EP0_RX, PDI_SET_EP_STALLED);    
161     }
162   }
163
164   int usb_pdi_read_endpoint( usb_ep_t *ep, void *ptr, int size) USB_UDEV_REENTRANT_SIGN
165   {
166     if(!ep->epnum)
167        return pdiReadEndpoint( PDI_EP0_RX, size, ptr);
168     else
169        return pdiReadEndpoint( ep->epnum, size, ptr);
170   }
171  
172   int usb_pdi_write_endpoint( usb_ep_t *ep, const void *ptr, int size) USB_UDEV_REENTRANT_SIGN
173   {
174     if(!ep->epnum)
175        pdiWriteEndpoint( PDI_EP0_TX, size, ptr);
176     else
177        pdiWriteEndpoint( ep->epnum, size, ptr);
178     return size;
179   }
180
181     
182 /* init usb structures and chip */
183   int usb_pdi_init( usb_device_t *udev) {
184
185    #ifndef USB_PDI_DIRECT_FNC
186     udev->connect = usb_pdi_connect;
187     udev->disconnect = usb_pdi_disconnect;
188     udev->ack_setup = usb_pdi_ack_setup;
189     udev->ack_control_setup = usb_pdi_ack_control_setup;
190     udev->stall = usb_pdi_stall;
191     udev->check_events = usb_pdi_check_events;
192     udev->read_endpoint = usb_pdi_read_endpoint;
193     udev->write_endpoint = usb_pdi_write_endpoint;
194    #endif /*USB_PDI_DIRECT_FNC*/
195
196     udev->ep0.max_packet_size = PDI_EP0_PACKET_SIZE;
197
198     pdiInitChipState();
199     pdiSetMode( PDI_MODE_BASE_VALUE);
200     return 0;
201   }