1 /*****************************************************/
2 /*** Module : USB PDI ***/
3 /*** Author : Roman Bartosinski (C) 28.04.2002 ***/
4 /*** Modify : 08.08.2002, 16.04.2003 ***/
5 /*****************************************************/
7 #include <system_def.h>
9 #include <usb/lpcusb.h>
15 #define PINSEL1 (PINCON->PINSEL1)
16 #define PINSEL3 (PINCON->PINSEL3)
17 #define PINSEL4 (PINCON->PINSEL4)
20 #define PCONP (SC->PCONP)
24 #ifndef USB_VBUS_PIN_USED
25 #define USB_VBUS_PIN_USED 1
28 unsigned int lpc_ep2addr(unsigned int ep_num)
31 val = (ep_num & 0x0F) << 1;
37 void lpc_wait4devint(unsigned int intrs)
39 while ((USBDevIntSt & intrs) != intrs);
44 void lpc_write_cmd(unsigned int cmd)
46 USBDevIntClr = USBDevInt_CCEMTY | USBDevInt_CDFULL;
48 lpc_wait4devint(USBDevInt_CCEMTY);
51 void lpc_write_cmd_data (unsigned int cmd, unsigned int val)
55 lpc_wait4devint(USBDevInt_CCEMTY);
58 unsigned int lpc_read_cmd_data (unsigned int cmd)
61 lpc_wait4devint(USBDevInt_CDFULL);
65 void lpc_usb_realizeEP(unsigned int idx,unsigned int wmaxpsize)
67 USBReEp |= (1 << idx);
69 USBMaxPSize = wmaxpsize;
70 lpc_wait4devint(USBDevInt_EP_RLZED);
73 void lpc_usb_configEP(unsigned int ep_num,unsigned int wmaxpsize)
75 lpc_usb_realizeEP(lpc_ep2addr(ep_num),wmaxpsize);
76 lpc_usb_enableEP(ep_num);
79 void lpc_usb_setstallEP(unsigned int ep_num)
81 lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(USBC_EP_STAT_ST));
84 void lpc_usb_clrstallEP(unsigned int ep_num)
86 lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(0));
89 void lpc_usb_enableEP(unsigned int ep_num)
91 lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(0));
94 void lpc_usb_disableEP(unsigned int ep_num)
96 lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(USBC_EP_STAT_DA));
99 void lpc_usb_set_addr(unsigned int adr)
101 lpc_write_cmd_data(USB_CMD_SET_ADDR,USB_DAT_WR_BYTE(USBC_DEV_EN | adr)); /* Setup Status Phase */
104 void lpc_usb_config_device(int fConfigured)
106 lpc_write_cmd_data(USB_CMD_CFG_DEV,USB_DAT_WR_BYTE(fConfigured ? USBC_CONF_DEVICE : 0)); /* Setup Status Phase */
109 void lpc_usb_reset(void)
111 USBEpIntClr = 0xFFFFFFFF;
112 USBEpIntEn = 0xFFFFFFFF ^ USB_DMA_EP;
113 USBDevIntClr = 0xFFFFFFFF;
114 USBDevIntEn = USBDevInt_DEV_STAT | USBDevInt_EP_SLOW;
116 lpc_usb_configEP(0x00, USB_MAX_PACKET0);
117 lpc_usb_configEP(0x80, USB_MAX_PACKET0);
120 void lpc_usb_hw_init (void)
123 #if defined(INC_LPC214x_H) || defined(MACH_LPC21XX)
124 PINSEL1 &= ~0xC000C000;
125 // PINSEL1 |= 0x40004000; /* Select USB Link, VBUS */
126 PINSEL1 |= 0x80000000; /* Select USB Link, VBUS */
128 PCONP |= 0x80000000; /* Turn On USB PCLK */
130 /* Configure 48MHz USB Clock; FOsc = 12MHz, M = 4, P = 2 */
131 PLLCFG48 = 0x23; /* M = 4, P = 2 */
132 PLLCON48 = PLLCON_PLLE; /* PLL Enable */
133 PLLFEED48 = 0xAA; /* Feed Sequence 1 */
134 PLLFEED48 = 0x55; /* Feed Sequence 2 */
136 while ((PLLSTAT48 & PLLSTAT_LOCK) == 0); /* Wait for PLL Lock */
138 PLLCON48 = PLLCON_PLLE | PLLCON_PLLC; /* PLL Enable & Connect */
139 PLLFEED48 = 0xAA; /* Feed Sequence 1 */
140 PLLFEED48 = 0x55; /* Feed Sequence 2 */
142 USBDevIntEn = USBDevInt_DEV_STAT; /* Enable Device Status Interrupt */
143 #endif /* MACH_LPC21XX */
145 #if defined(MACH_LPC23XX) || defined(MACH_LPC17XX)
148 ** USB clock (48MHz) should be set up externally before calling this fn
149 ** by setting USBCLKCFG (eg. USBCLKCFG = 5 for f_cco=288MHz).
150 ** If some of the pins shared with USB device are to be used for
151 ** different purpose, following PINSELs must be changed after retutn
155 /* set up USB pins */
156 PINSEL1 = (PINSEL1 & ~(0x3<<26)) | (0x1<<26); /* USB_D+,- @ P0.29,30 */
157 PINSEL4 = (PINSEL4 & ~(0x3<<18)) | (0x1<<18); /* USB_CONNECT @ P2.9 */
158 #if USB_VBUS_PIN_USED
159 PINSEL3 = (PINSEL3 & ~(0x3<<28)) | (0x2<<28); /* Vbus @ P1.30 */
161 /* switch USB power on */
163 /* switch USB internal clock switch on */
165 while ((USBClkSt & 0x12) != 0x12);
167 #endif /* MACH_LPC23XX */
169 /* Partial Manual Reset since Automatic Bus Reset is not working */
175 * lpc_usb_read_endpoint: Read USB Endpoint Data
176 * @EPNum: Endpoint Number - EPNum.0..3: Address, EPNum.7: Dir
177 * @ptr: Pointer to Data Buffer
179 * Return Value: Number of bytes read
181 int lpc_usb_read_endpoint( unsigned int ep_num, void *ptr, int size)
183 unsigned int cnt,i,dwData;
184 unsigned char *p=ptr;
186 USBCtrl = ((ep_num & 0x0F) << 2) | USBCtrl_RD_EN;
189 } while ((cnt & USBRxPLen_PKT_RDY) == 0);
190 cnt &= USBRxPLen_PKT_LNGTH;
193 while (USBCtrl & USBCtrl_RD_EN) {
196 for (i = 0; (i < 4) && size; i++) {
205 lpc_write_cmd(USB_CMD_SEL_EP(lpc_ep2addr(ep_num)));
206 lpc_write_cmd(USB_CMD_CLR_BUF);
212 * lpc_usb_write_endpoint: Write USB Endpoint Data
213 * @ep_num: Endpoint Number - ep_num.0..3: Address, ep_num.7: Dir
214 * @ptr: Pointer to Data Buffer
215 * @size: Number of bytes to write
216 * Return Value: Number of bytes written
218 int lpc_usb_write_endpoint( unsigned int ep_num, const void *ptr, int size)
221 const unsigned char *p=ptr;
223 USBCtrl = ((ep_num & 0x0F) << 2) | USBCtrl_WR_EN;
226 for (n = 0; n < (size + 3) / 4; n++) {
227 USBTxData = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
233 lpc_write_cmd(USB_CMD_SEL_EP(lpc_ep2addr(ep_num)));
234 lpc_write_cmd(USB_CMD_VALID_BUF);