]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/libs4c/usb/lpcusb/lpc.c
159c899851883ec9c1a94e88c05756de8f14c870
[lincan.git] / embedded / libs4c / usb / lpcusb / lpc.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 <system_def.h>
8 #include <usb/usb.h>
9 #include <usb/lpcusb.h>
10
11 /* set device address */
12 int usb_lpc_set_addr( usb_device_t *udev, unsigned char addr) {
13   lpc_usb_set_addr(addr);
14   return 0;
15 }
16
17 int usb_lpc_set_configuration( usb_device_t *udev, unsigned char iCfg) {
18   lpc_usb_config_device(iCfg);
19   if ( iCfg) {
20     int i;
21     for(i = 0; i < udev->cntep; i++) {
22       lpc_usb_configEP(udev->ep[i].epnum, udev->ep[i].max_packet_size);
23     }
24   }
25   return 0;
26 }
27
28 /* connect usb */
29 int usb_lpc_connect( usb_device_t *udev) {
30   lpc_write_cmd_data(USB_CMD_SET_DEV_STAT,USB_DAT_WR_BYTE(USBC_DEV_CON));
31   return 0;
32 }
33
34 /* disconnect usb */
35 int usb_lpc_disconnect( usb_device_t *udev) {
36   lpc_write_cmd_data(USB_CMD_SET_DEV_STAT,USB_DAT_WR_BYTE(0));
37   return 0;
38 }
39
40 /* acknowledge control transfer */
41 void usb_lpc_ack_setup( usb_device_t *udev) {
42   lpc_usb_write_endpoint(0x80|0x00, NULL, 0);
43 }
44
45 /* stall endpoint X */
46 void usb_lpc_stall( usb_ep_t *ep) {
47   if (!ep->epnum)
48     lpc_usb_setstallEP(0x80|ep->epnum);
49   lpc_usb_setstallEP(ep->epnum);
50 }
51
52 /* unstall endpoint X */
53 void usb_lpc_unstall( usb_ep_t *ep) {
54   if (!ep->epnum)
55     lpc_usb_clrstallEP(0x80|ep->epnum);
56   lpc_usb_clrstallEP(ep->epnum);
57 }
58
59 /**
60  * usb_lpc_check events
61  * function reads interrupt register and sets event flags
62  * function returns 1 if there is some new event.
63  * function returns 0 if there isn't new event but all is OK
64  * function returns -1 if there is any error
65 */
66 int usb_lpc_check_events( usb_device_t *udev) 
67 {
68   unsigned int disr,val,last_int;
69   int ret=0,n,m,i;
70
71   disr=USBDevIntSt;
72
73   /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
74   if (disr & USBDevInt_DEV_STAT) {
75     USBDevIntClr = USBDevInt_DEV_STAT;
76     disr&=~USBDevInt_DEV_STAT;
77     lpc_write_cmd(USB_CMD_GET_DEV_STAT);
78     val=lpc_read_cmd_data(USB_DAT_GET_DEV_STAT);
79     if (val & USBC_DEV_RST) {               /* Reset */
80       lpc_usb_reset();
81       udev->flags |= USB_FLAG_BUS_RESET;
82       ret = 1;
83     }
84     if (val & USBC_DEV_SUS_CH) {            /* Suspend/Resume */
85       if (val & USBC_DEV_SUS) {             /* Suspend */
86         udev->flags |= USB_FLAG_SUSPEND;
87         ret = 1;
88       } else {                              /* Resume */
89         /* todo */
90       }
91     }
92   }
93
94   /* Endpoint's Slow Interrupt */
95   if (disr & USBDevInt_EP_SLOW) {
96     USBDevIntClr = USBDevInt_EP_SLOW;
97     disr&=~USBDevInt_EP_SLOW;
98
99     last_int = USBEpIntSt;
100
101     /* EP0_OUT */
102     if (last_int & (1 << 0)) {
103       last_int &= ~(1 << 0);
104       USBEpIntClr = 1 << 0;
105       lpc_wait4devint(USBDevInt_CDFULL);
106       val = USBCmdData;
107       /* Setup Packet */
108       if (val & USBC_EP_SEL_STP)   
109         udev->flags |= USB_FLAG_SETUP;
110       else
111         udev->flags |= USB_FLAG_EVENT_RX0;
112       ret = 1;
113     }
114
115     /* EP0_IN */
116     if (last_int & (1 << 1)) {
117       last_int &= ~(1 << 1);
118       USBEpIntClr = 1 << 1;
119       lpc_wait4devint(USBDevInt_CDFULL);
120       val = USBCmdData;
121       udev->flags |= USB_FLAG_EVENT_TX0;
122       ret = 1;
123     }    
124
125     /* user endpoints */
126     for( i=0; i<udev->cntep; i++) {
127       if ( last_int & (udev->ep+i)->event_mask) {
128         last_int &= ~((udev->ep+i)->event_mask);
129         USBEpIntClr = (udev->ep+i)->event_mask;
130         lpc_wait4devint(USBDevInt_CDFULL);
131         val = USBCmdData;
132         udev->ep_events |= 1<<i;
133         ret = 1;
134       }
135     }
136
137     while (last_int) {                    /* Endpoint Interrupt Status */
138       for (n = 0; n < USB_EP_NUM; n++) {    /* Check All Endpoints */
139         if (last_int & (1 << n)) {
140           last_int &= ~(1 << n);
141           USBEpIntClr = 1 << n;
142           m = n >> 1;
143           if (n&1) m|=0x80;
144           lpc_wait4devint(USBDevInt_CDFULL);
145           val = USBCmdData;
146           lpc_usb_setstallEP(m);
147         }
148       }
149     }
150   }
151   if (!disr)
152     USBDevIntClr = disr;
153   return ret;
154 }
155
156 int usb_lpc_read_endpoint( usb_ep_t *ep, void *ptr, int size)
157 {
158   return lpc_usb_read_endpoint(ep->epnum, ptr, size);
159 }
160
161 int usb_lpc_write_endpoint( usb_ep_t *ep, const void *ptr, int size)
162 {
163   return lpc_usb_write_endpoint(0x80|ep->epnum, ptr, size);
164 }
165
166
167 /* init usb structures and chip */
168 int usb_lpc_init( usb_device_t *udev) {
169
170   udev->connect = usb_lpc_connect;
171   udev->set_addr = usb_lpc_set_addr;
172   udev->set_configuration = usb_lpc_set_configuration;
173   udev->disconnect = usb_lpc_disconnect;
174   udev->ack_setup = usb_lpc_ack_setup; 
175   udev->ack_control_setup = NULL;
176   udev->stall = usb_lpc_stall;
177   udev->unstall = usb_lpc_unstall;
178   udev->check_events = usb_lpc_check_events;
179   udev->read_endpoint = usb_lpc_read_endpoint;
180   udev->write_endpoint = usb_lpc_write_endpoint;
181
182   udev->ep0.max_packet_size = USB_MAX_PACKET0;
183
184   lpc_usb_hw_init();  
185   return 0;
186 }