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