]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/libs4c/usb/lpcusb/lpcusb.c
Embedded code-base updated to actual version from uLan repository.
[lincan.git] / embedded / libs4c / usb / lpcusb / lpcusb.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 unsigned int lpc_ep2addr(unsigned int ep_num) 
12 {
13   unsigned int val;
14   val = (ep_num & 0x0F) << 1;
15   if (ep_num & 0x80) 
16     val += 1;
17   return val;
18
19
20 void lpc_wait4devint(unsigned int intrs) 
21 {
22   while ((USBDevIntSt & intrs) != intrs);
23   USBDevIntClr = intrs;  
24 }
25
26
27 void lpc_write_cmd(unsigned int cmd) 
28 {
29   USBDevIntClr = USBDevInt_CCEMTY | USBDevInt_CDFULL;
30   USBCmdCode = cmd;
31   lpc_wait4devint(USBDevInt_CCEMTY);
32 }
33
34 void lpc_write_cmd_data (unsigned int cmd, unsigned int val) 
35 {
36   lpc_write_cmd(cmd);
37   USBCmdCode = val;
38   lpc_wait4devint(USBDevInt_CCEMTY);
39 }
40
41 unsigned int lpc_read_cmd_data (unsigned int cmd)
42 {
43   lpc_write_cmd(cmd);
44   lpc_wait4devint(USBDevInt_CDFULL);
45   return USBCmdData;
46
47
48 void lpc_usb_realizeEP(unsigned int idx,unsigned int wmaxpsize)
49 {
50   USBReEp |= (1 << idx);
51   USBEpInd = idx;
52   USBMaxPSize = wmaxpsize;
53   lpc_wait4devint(USBDevInt_EP_RLZED);
54 }
55
56 void lpc_usb_configEP(unsigned int ep_num,unsigned int wmaxpsize)
57 {
58   lpc_usb_realizeEP(lpc_ep2addr(ep_num),wmaxpsize);
59   lpc_usb_enableEP(ep_num);
60 }
61
62 void lpc_usb_setstallEP(unsigned int ep_num) 
63 {
64   lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(USBC_EP_STAT_ST));
65 }
66
67 void lpc_usb_clrstallEP(unsigned int ep_num) 
68 {
69   lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(0));
70 }
71
72 void lpc_usb_enableEP(unsigned int ep_num) 
73 {
74   lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(0));
75 }
76
77 void lpc_usb_disableEP(unsigned int ep_num) 
78 {
79   lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(USBC_EP_STAT_DA));
80 }
81
82 void lpc_usb_set_addr(unsigned int adr)
83 {
84   lpc_write_cmd_data(USB_CMD_SET_ADDR,USB_DAT_WR_BYTE(USBC_DEV_EN | adr)); /*  Setup Status Phase */
85 }
86
87 void lpc_usb_config_device(int fConfigured)
88 {
89   lpc_write_cmd_data(USB_CMD_CFG_DEV,USB_DAT_WR_BYTE(fConfigured ? USBC_CONF_DEVICE : 0)); /*  Setup Status Phase */
90 }
91
92 void lpc_usb_reset(void)
93 {
94   USBEpIntClr  = 0xFFFFFFFF;
95   USBEpIntEn   = 0xFFFFFFFF ^ USB_DMA_EP;
96   USBDevIntClr = 0xFFFFFFFF;
97   USBDevIntEn  = USBDevInt_DEV_STAT | USBDevInt_EP_SLOW;
98
99   lpc_usb_configEP(0x00, USB_MAX_PACKET0);
100   lpc_usb_configEP(0x80, USB_MAX_PACKET0);
101 }
102
103 void lpc_usb_hw_init (void) 
104 {
105
106   PINSEL1 &= ~0xC000C000;
107 //  PINSEL1 |=  0x40004000;                   /* Select USB Link, VBUS */
108   PINSEL1 |=  0x80000000;                   /* Select USB Link, VBUS */
109
110   PCONP |= 0x80000000;                      /* Turn On USB PCLK */
111
112   /* Configure 48MHz USB Clock;  FOsc = 12MHz, M = 4, P = 2 */
113   PLLCFG48  = 0x23;                         /* M = 4, P = 2 */
114   PLLCON48  = PLLCON_PLLE;                  /* PLL Enable */
115   PLLFEED48 = 0xAA;                         /* Feed Sequence 1 */
116   PLLFEED48 = 0x55;                         /* Feed Sequence 2 */
117
118   while ((PLLSTAT48 & PLLSTAT_LOCK) == 0);  /* Wait for PLL Lock */
119
120   PLLCON48  = PLLCON_PLLE | PLLCON_PLLC;    /* PLL Enable & Connect */
121   PLLFEED48 = 0xAA;                         /* Feed Sequence 1 */
122   PLLFEED48 = 0x55;                         /* Feed Sequence 2 */
123
124   USBDevIntEn  = USBDevInt_DEV_STAT;        /* Enable Device Status Interrupt */
125
126   /* Partial Manual Reset since Automatic Bus Reset is not working */
127   lpc_usb_reset();
128   lpc_usb_set_addr(0);
129 }
130
131 /*
132  * lpc_usb_read_endpoint: Read USB Endpoint Data
133  * @EPNum: Endpoint Number - EPNum.0..3: Address, EPNum.7: Dir
134  * @ptr: Pointer to Data Buffer
135  * @size:
136  * Return Value: Number of bytes read
137  */
138 int lpc_usb_read_endpoint( unsigned int ep_num, void *ptr, int size)
139 {
140   unsigned int cnt,i,dwData;
141   unsigned char *p=ptr;
142
143   USBCtrl = ((ep_num & 0x0F) << 2) | USBCtrl_RD_EN;
144   do {
145     cnt = USBRxPLen;
146   } while ((cnt & USBRxPLen_PKT_RDY) == 0);
147   cnt &= USBRxPLen_PKT_LNGTH;
148
149   // get data
150   while (USBCtrl & USBCtrl_RD_EN) {
151     dwData = USBRxData;
152     if (p != NULL) {
153       for (i = 0; (i < 4) && size; i++) {
154         size--;
155         *p = dwData & 0xFF;
156         p++;
157         dwData >>= 8;
158       }
159     }
160   }
161
162   lpc_write_cmd(USB_CMD_SEL_EP(lpc_ep2addr(ep_num)));
163   lpc_write_cmd(USB_CMD_CLR_BUF);
164
165   return cnt;
166 }
167
168 /*
169  * lpc_usb_write_endpoint: Write USB Endpoint Data
170  * @ep_num: Endpoint Number - ep_num.0..3: Address, ep_num.7: Dir
171  * @ptr: Pointer to Data Buffer
172  * @size:   Number of bytes to write
173  * Return Value:    Number of bytes written
174  */
175 int lpc_usb_write_endpoint( unsigned int ep_num, const void *ptr, int size)
176 {
177   unsigned int n;
178   const unsigned char *p=ptr;
179
180   USBCtrl = ((ep_num & 0x0F) << 2) | USBCtrl_WR_EN;
181   USBTxPLen = size;
182
183   for (n = 0; n < (size + 3) / 4; n++) {
184     USBTxData = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
185     p += 4;
186   }
187
188   USBCtrl=0;
189
190   lpc_write_cmd(USB_CMD_SEL_EP(lpc_ep2addr(ep_num)));
191   lpc_write_cmd(USB_CMD_VALID_BUF);
192
193   return size;
194 }