--- /dev/null
+/*****************************************************/
+/*** Module : USB PDI ***/
+/*** Author : Roman Bartosinski (C) 28.04.2002 ***/
+/*** Modify : 08.08.2002, 16.04.2003 ***/
+/*****************************************************/
+
+#include <system_def.h>
+#include <usb/usb.h>
+#include <usb/lpcusb.h>
+
+unsigned int lpc_ep2addr(unsigned int ep_num)
+{
+ unsigned int val;
+ val = (ep_num & 0x0F) << 1;
+ if (ep_num & 0x80)
+ val += 1;
+ return val;
+}
+
+void lpc_wait4devint(unsigned int intrs)
+{
+ while ((USBDevIntSt & intrs) != intrs);
+ USBDevIntClr = intrs;
+}
+
+
+void lpc_write_cmd(unsigned int cmd)
+{
+ USBDevIntClr = USBDevInt_CCEMTY | USBDevInt_CDFULL;
+ USBCmdCode = cmd;
+ lpc_wait4devint(USBDevInt_CCEMTY);
+}
+
+void lpc_write_cmd_data (unsigned int cmd, unsigned int val)
+{
+ lpc_write_cmd(cmd);
+ USBCmdCode = val;
+ lpc_wait4devint(USBDevInt_CCEMTY);
+}
+
+unsigned int lpc_read_cmd_data (unsigned int cmd)
+{
+ lpc_write_cmd(cmd);
+ lpc_wait4devint(USBDevInt_CDFULL);
+ return USBCmdData;
+}
+
+void lpc_usb_realizeEP(unsigned int idx,unsigned int wmaxpsize)
+{
+ USBReEp |= (1 << idx);
+ USBEpInd = idx;
+ USBMaxPSize = wmaxpsize;
+ lpc_wait4devint(USBDevInt_EP_RLZED);
+}
+
+void lpc_usb_configEP(unsigned int ep_num,unsigned int wmaxpsize)
+{
+ lpc_usb_realizeEP(lpc_ep2addr(ep_num),wmaxpsize);
+ lpc_usb_enableEP(ep_num);
+}
+
+void lpc_usb_setstallEP(unsigned int ep_num)
+{
+ lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(USBC_EP_STAT_ST));
+}
+
+void lpc_usb_clrstallEP(unsigned int ep_num)
+{
+ lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(0));
+}
+
+void lpc_usb_enableEP(unsigned int ep_num)
+{
+ lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(0));
+}
+
+void lpc_usb_disableEP(unsigned int ep_num)
+{
+ lpc_write_cmd_data(USB_CMD_SET_EP_STAT(lpc_ep2addr(ep_num)),USB_DAT_WR_BYTE(USBC_EP_STAT_DA));
+}
+
+void lpc_usb_set_addr(unsigned int adr)
+{
+ lpc_write_cmd_data(USB_CMD_SET_ADDR,USB_DAT_WR_BYTE(USBC_DEV_EN | adr)); /* Setup Status Phase */
+}
+
+void lpc_usb_config_device(int fConfigured)
+{
+ lpc_write_cmd_data(USB_CMD_CFG_DEV,USB_DAT_WR_BYTE(fConfigured ? USBC_CONF_DEVICE : 0)); /* Setup Status Phase */
+}
+
+void lpc_usb_reset(void)
+{
+ USBEpIntClr = 0xFFFFFFFF;
+ USBEpIntEn = 0xFFFFFFFF ^ USB_DMA_EP;
+ USBDevIntClr = 0xFFFFFFFF;
+ USBDevIntEn = USBDevInt_DEV_STAT | USBDevInt_EP_SLOW;
+
+ lpc_usb_configEP(0x00, USB_MAX_PACKET0);
+ lpc_usb_configEP(0x80, USB_MAX_PACKET0);
+}
+
+void lpc_usb_hw_init (void)
+{
+
+ PINSEL1 &= ~0xC000C000;
+// PINSEL1 |= 0x40004000; /* Select USB Link, VBUS */
+ PINSEL1 |= 0x80000000; /* Select USB Link, VBUS */
+
+ PCONP |= 0x80000000; /* Turn On USB PCLK */
+
+ /* Configure 48MHz USB Clock; FOsc = 12MHz, M = 4, P = 2 */
+ PLLCFG48 = 0x23; /* M = 4, P = 2 */
+ PLLCON48 = PLLCON_PLLE; /* PLL Enable */
+ PLLFEED48 = 0xAA; /* Feed Sequence 1 */
+ PLLFEED48 = 0x55; /* Feed Sequence 2 */
+
+ while ((PLLSTAT48 & PLLSTAT_LOCK) == 0); /* Wait for PLL Lock */
+
+ PLLCON48 = PLLCON_PLLE | PLLCON_PLLC; /* PLL Enable & Connect */
+ PLLFEED48 = 0xAA; /* Feed Sequence 1 */
+ PLLFEED48 = 0x55; /* Feed Sequence 2 */
+
+ USBDevIntEn = USBDevInt_DEV_STAT; /* Enable Device Status Interrupt */
+
+ /* Partial Manual Reset since Automatic Bus Reset is not working */
+ lpc_usb_reset();
+ lpc_usb_set_addr(0);
+}
+
+/*
+ * lpc_usb_read_endpoint: Read USB Endpoint Data
+ * @EPNum: Endpoint Number - EPNum.0..3: Address, EPNum.7: Dir
+ * @ptr: Pointer to Data Buffer
+ * @size:
+ * Return Value: Number of bytes read
+ */
+int lpc_usb_read_endpoint( unsigned int ep_num, void *ptr, int size)
+{
+ unsigned int cnt,i,dwData;
+ unsigned char *p=ptr;
+
+ USBCtrl = ((ep_num & 0x0F) << 2) | USBCtrl_RD_EN;
+ do {
+ cnt = USBRxPLen;
+ } while ((cnt & USBRxPLen_PKT_RDY) == 0);
+ cnt &= USBRxPLen_PKT_LNGTH;
+
+ // get data
+ while (USBCtrl & USBCtrl_RD_EN) {
+ dwData = USBRxData;
+ if (p != NULL) {
+ for (i = 0; i < 4; i++) {
+ if (size-- != 0) {
+ *p = dwData & 0xFF;
+ p++;
+ }
+ dwData >>= 8;
+ }
+ }
+ }
+
+ lpc_write_cmd(USB_CMD_SEL_EP(lpc_ep2addr(ep_num)));
+ lpc_write_cmd(USB_CMD_CLR_BUF);
+
+ return cnt;
+}
+
+/*
+ * lpc_usb_write_endpoint: Write USB Endpoint Data
+ * @ep_num: Endpoint Number - ep_num.0..3: Address, ep_num.7: Dir
+ * @ptr: Pointer to Data Buffer
+ * @size: Number of bytes to write
+ * Return Value: Number of bytes written
+ */
+int lpc_usb_write_endpoint( unsigned int ep_num, const void *ptr, int size)
+{
+ unsigned int n;
+ const unsigned char *p=ptr;
+
+ USBCtrl = ((ep_num & 0x0F) << 2) | USBCtrl_WR_EN;
+ USBTxPLen = size;
+
+ for (n = 0; n < (size + 3) / 4; n++) {
+ USBTxData = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
+ p += 4;
+ }
+
+ USBCtrl=0;
+
+ lpc_write_cmd(USB_CMD_SEL_EP(lpc_ep2addr(ep_num)));
+ lpc_write_cmd(USB_CMD_VALID_BUF);
+
+ return size;
+}