📄 s3c2510usbloopback.c
字号:
/* s3c2510Usb.c - SAMSUNG S3C2510 USB driver */
/* Copyright 2002 SAMSUNG ELECTRONICS */
/*
modification history
--------------------
01 Oct.2003. Ajay Raj Sharma customized for loopback data transfers
01a,22apr02,jmLee created.
*/
/* NOTE:
1. that all loopback tarnsfers must be tested with max of 4k data
*/
#include "vxWorks.h"
#include "intLib.h"
#include "netLib.h"
#include "end.h"
#include "endLib.h"
#include "cacheLib.h"
#include "miiLib.h"
#include "errno.h"
#include "stdio.h"
#include "logLib.h"
#include "taskLib.h"
/* Ajay */
#include "iv.h"
/* Ajay */
#include "drv/multi/s3c2510.h"
/* #include "config.h"*/
#include "drv/intrCtl/s3c2510Intr.h"
#include "s3c2510UsbLoopback.h"
#define GDMA_Transfer_Mode 1
#undef DEBUG_TRACE
#define DEBUG_LOG(x, p1, p2, p3, p4, p5, p6) \
logMsg(x, (int)(UINT32)(p1), (int)(UINT32)(p2), (int)(UINT32)(p3), (int)(UINT32)(p4), (int)(UINT32)(p5), (int)(UINT32)(p6))
/* Forward Function Declarations */
LOCAL void s3c2510UsbReset(void);
LOCAL void s3c2510UsbGetStatus(void);
LOCAL void s3c2510UsbClearFeature(void);
LOCAL void s3c2510UsbSetFeature(void);
LOCAL void s3c2510UsbSetAddress(void);
LOCAL void s3c2510UsbGetDescriptor(void);
LOCAL void s3c2510UsbSetDescriptor(void);
LOCAL void s3c2510UsbGetConfig(void);
LOCAL void s3c2510UsbSetConfig(void);
LOCAL void s3c2510UsbGetInterface(void);
LOCAL void s3c2510UsbSetInterface(void);
LOCAL void s3c2510UsbSyncFrame(void);
LOCAL void s3c2510UsbEp0Tx();
LOCAL void s3c2510UsbEp0Rx();
LOCAL void s3c2510UsbDeviceRequestStandard(void);
LOCAL void s3c2510UsbDeviceRequestClass(void);
LOCAL void s3c2510UsbDeviceRequestVendor(void);
LOCAL void s3c2510UsbInt(void);
LOCAL void s3c2510UsbEP0Handler(void);
LOCAL void s3c2510UsbEP1Handler(void);
LOCAL void s3c2510UsbEP2Handler(void);
LOCAL void s3c2510UsbEP3Handler(void);
LOCAL void s3c2510UsbEP4Handler(void);
#ifdef DEBUG_TRACE
/* Removed Local by Ajay */
void s3c2510UsbDump(UCHAR *p, ULONG l);
#endif /* DEBUG_TRACE */
/* Local Variables */
#define EP0_STATE_IDLE 0
#define EP0_STATE_TRANSMIT 1
#define EP0_STATE_RECEIVE 2
LOCAL UINT32 ep0State;
LOCAL UINT32 *ep0RxBuffer = NULL;
LOCAL UINT32 ep0RxLength = 0;
LOCAL UINT32 ep0RxCount = 0;
LOCAL UINT32 *ep0TxBuffer = NULL;
LOCAL UINT32 ep0TxLength = 0;
LOCAL UINT32 ep0TxCount = 0 ;
LOCAL UINT32 *ep1RxBuffer = NULL;
LOCAL UINT32 ep1RxCount = 0;
LOCAL UINT32 ep12LoopbackLen = 0;
LOCAL UINT32 *ep2TxBuffer = NULL;
LOCAL UINT32 ep2TxCount = 0;
LOCAL UINT32 *ep3RxBuffer = NULL;
LOCAL UINT32 ep3RxCount = 0;
LOCAL UINT32 ep34LoopbackLen = 0;
LOCAL UINT32 *ep4TxBuffer = NULL;
LOCAL UINT32 ep4TxCount = 0;
LOCAL UINT32 deviceStatus;
LOCAL UINT32 deviceConfig;
LOCAL UINT32 deviceInterface;
LOCAL UINT32 ep0Status;
LOCAL UINT32 ep1Status;
LOCAL UINT32 ep2Status;
LOCAL UINT32 ep3Status;
LOCAL UINT32 ep4Status;
LOCAL USB_SETUP usbSetup;
LOCAL UINT8 descrDevice[USB_DEVICE_DESCR_LEN]__attribute__ ((aligned (4))) = {
USB_DEVICE_DESCR_LEN,
USB_DESCRIPTOR_DEVICE,
LSB(USB_RELEASE),
MSB(USB_RELEASE),
USB_DEVICE_CLASS,
USB_DEVICE_SUBCLASS,
USB_DEVICE_PROTOCOL,
USB_EP0_MAXP_SIZE,
LSB(USB_VENDOR_ID),
MSB(USB_VENDOR_ID),
LSB(USB_PRODUCT_ID),
MSB(USB_PRODUCT_ID),
LSB(USB_DEVICE_RELEASE),
MSB(USB_DEVICE_RELEASE),
0,
0,
0,
1
};
LOCAL UINT8 descrConfig[USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN + USB_ENDPOINT_DESCR_LEN * USB_MAX_ENDPOINT]
__attribute__ ((aligned (4))) =
{
USB_CONFIG_DESCR_LEN,
USB_DESCRIPTOR_CONFIGURATION,
LSB(USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN + USB_ENDPOINT_DESCR_LEN * USB_MAX_ENDPOINT),
MSB(USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN + USB_ENDPOINT_DESCR_LEN * USB_MAX_ENDPOINT),
1,
1,
0,
USB_CONFIG_SELF_POWERED,
50,
USB_INTERFACE_DESCR_LEN,
USB_DESCRIPTOR_INTERFACE,
0,
0,
USB_MAX_ENDPOINT,
0,
0,
0,
0,
USB_ENDPOINT_DESCR_LEN,
USB_DESCRIPTOR_ENDPOINT,
#ifdef USB_EP1_IN
1 | USB_ENDPOINT_DIRECTION_IN,
#else /* USB_EP1_IN */
1 | USB_ENDPOINT_DIRECTION_OUT,
#endif /* USB_EP1_IN */
USB_EP1_TYPE,
LSB(USB_EP1_MAXP_SIZE),
MSB(USB_EP1_MAXP_SIZE),
USB_EP1_INTERVAL,
USB_ENDPOINT_DESCR_LEN,
USB_DESCRIPTOR_ENDPOINT,
#ifdef USB_EP2_IN
2 | USB_ENDPOINT_DIRECTION_IN,
#else /* USB_EP2_IN */
2 | USB_ENDPOINT_DIRECTION_OUT,
#endif /* USB_EP2_IN */
USB_EP2_TYPE,
LSB(USB_EP2_MAXP_SIZE),
MSB(USB_EP2_MAXP_SIZE),
USB_EP2_INTERVAL,
USB_ENDPOINT_DESCR_LEN,
USB_DESCRIPTOR_ENDPOINT,
#ifdef USB_EP3_IN
3 | USB_ENDPOINT_DIRECTION_IN,
#else /* USB_EP3_IN */
3 | USB_ENDPOINT_DIRECTION_OUT,
#endif /* USB_EP3_IN */
USB_EP3_TYPE,
LSB(USB_EP3_MAXP_SIZE),
MSB(USB_EP3_MAXP_SIZE),
USB_EP3_INTERVAL,
USB_ENDPOINT_DESCR_LEN,
USB_DESCRIPTOR_ENDPOINT,
#ifdef USB_EP4_IN
4 | USB_ENDPOINT_DIRECTION_IN,
#else /* USB_EP4_IN */
4 | USB_ENDPOINT_DIRECTION_OUT,
#endif /* USB_EP4_IN */
USB_EP4_TYPE,
LSB(USB_EP4_MAXP_SIZE),
MSB(USB_EP4_MAXP_SIZE),
USB_EP4_INTERVAL
};
/* Buffer used for control loopback data */
UINT8 controlLoopbackBuffer[4096]__attribute__ ((aligned (4))) = {0};
/* Buffer used for EP1 and EP2 loopback data */
UINT8 ep12LoopbackBuffer [4096]__attribute__ ((aligned (4)))= {0};
/* Buffer used for EP3 and EP4 loopback data */
UINT8 ep34LoopbackBuffer [4096]__attribute__ ((aligned (4)))= {0};
/*******************************************************************************
*
* s3c2510UsbInit - initialize S3C2510 USB
*
* RETURNS: OK, or ERROR.
*/
STATUS s3c2510UsbInit(void)
{
#ifdef DEBUG_TRACE
printf("s3c2510Usb Init\n");
#endif /* DEBUG_TRACE */
/* Disable interrupt. */
intDisable(INT_LVL_USB);
/* Enable peripheral clock. */
*S3C2510_PCLKDIS &= ~S3C2510_PCLKDIS_USB;
/* Enable the GDMA4 clock */
*S3C2510_PCLKDIS &= ~S3C2510_PCLKDIS_GDMA4;
/* Enable the GDMA5 clock */
*S3C2510_PCLKDIS &= ~S3C2510_PCLKDIS_GDMA5;
/* Initialize USB. */
s3c2510UsbReset();
/* Connect interrupt. */
intConnect(INT_VEC_USB, (VOIDFUNCPTR)s3c2510UsbInt, 0);
/* Disable interrupt. */
intEnable(INT_LVL_USB);
#ifdef DEBUG_TRACE
/* To check alignment */
printf("Addr of usbSetup %x \n", &(usbSetup));
printf("Addr of descrDevice %x \n",descrDevice);
printf("Addr of descrConfig %x \n",(descrConfig));
printf("Addr of controlLoopbackBuffer %x \n",controlLoopbackBuffer);
printf("Addr of ep12LoopbackBuffer %x \n",ep12LoopbackBuffer);
printf("Addr of ep34LoopbackBuffer %x \n",ep34LoopbackBuffer);
/* To check alignment */
#endif
return OK;
}
#if 1 /* Added by Ajay*/
/* GDMA Channels used for USB transfers */
#define GDMA_USB_IN 4
#define GDMA_USB_OUT 5
/*******************************************************************************
*
* s3c2510ResetGDMA - reset GDMA
*
* This function resets the requested DMA channels.
*
* RETURNS : N/A
*/
LOCAL void s3c2510ResetGDMA(unsigned long GDMAChannel)
{
*S3C2510_DCON(GDMAChannel) = 0;
*S3C2510_DSAR(GDMAChannel) = 0;
*S3C2510_DDAR(GDMAChannel) = 0;
*S3C2510_DTCR(GDMAChannel) = 0;
*S3C2510_DRER(GDMAChannel) = 0;
*S3C2510_DIPR(GDMAChannel) = 0;
}/* END of function s3c2510ResetGDMA */
#endif/**/
/*******************************************************************************
*
* s3c2510UsbReset - reset USB.
*
* RETURNS : N/A
*/
void s3c2510UsbReset(void)
{
/* Initialize USB Endpoint 0 Common Status Register. */
*S3C2510_USBCSR(0) = S3C2510_USBEP0CSR_MAXPSET | /* USB MAXP Size Settable */
S3C2510_USBEP0CSR_MAXP_64; /* 64 byte */
/* Initialize USB Endpoint 1 Common Status Register. */
*S3C2510_USBCSR(1) = S3C2510_USBEPCSR_CSR2SET | /* CSR 8~12 Settable */
#ifdef USB_EP1_IN
S3C2510_USBEPCSR_IN | /* IN Mode */
S3C2510_USBEPCSR_IATSET | /* Auto Set USBINRDY */
#else /* USB_EP1_IN */
S3C2510_USBEPCSR_OUT | /* OUT Mode */
S3C2510_USBEPCSR_OATCLR | /* Auto Clear USBORDY */
#endif /* USB_EP1_IN */
S3C2510_USBEPCSR_MAXPSET | /* USB MAXP Size Settable */
S3C2510_USBEPCSR_MAXP_32; /* 32 byte */
/* Initialize USB Endpoint 2 Common Status Register. */
*S3C2510_USBCSR(2) = S3C2510_USBEPCSR_CSR2SET | /* CSR 8~12 Settable */
#ifdef USB_EP2_IN
S3C2510_USBEPCSR_IN | /* IN Mode */
S3C2510_USBEPCSR_IATSET | /* Auto Set USBINRDY */
#else /* USB_EP2_IN */
S3C2510_USBEPCSR_OUT | /* OUT Mode */
S3C2510_USBEPCSR_OATCLR | /* Auto Clear USBORDY */
#endif /* USB_EP2_IN */
S3C2510_USBEPCSR_MAXPSET | /* USB MAXP Size Settable */
S3C2510_USBEPCSR_MAXP_32; /* 32 byte */
/* Initialize USB Endpoint 3 Common Status Register. */
*S3C2510_USBCSR(3) = S3C2510_USBEPCSR_CSR2SET | /* CSR 8~12 Settable */
#ifdef USB_EP3_IN
S3C2510_USBEPCSR_IN | /* IN Mode */
S3C2510_USBEPCSR_IATSET | /* Auto Set USBINRDY */
#else /* USB_EP3_IN */
S3C2510_USBEPCSR_OUT | /* OUT Mode */
S3C2510_USBEPCSR_OATCLR | /* Auto Clear USBORDY */
#endif /* USB_EP3_IN */
S3C2510_USBEPCSR_MAXPSET | /* USB MAXP Size Settable */
S3C2510_USBEPCSR_MAXP_64; /* 64 byte */
/* Initialize USB Endpoint 4 Common Status Register. */
*S3C2510_USBCSR(4) = S3C2510_USBEPCSR_CSR2SET | /* CSR 8~12 Settable */
#ifdef USB_EP4_IN
S3C2510_USBEPCSR_IN | /* IN Mode */
S3C2510_USBEPCSR_IATSET | /* Auto Set USBINRDY */
#else /* USB_EP4_IN */
S3C2510_USBEPCSR_OUT | /* OUT Mode */
S3C2510_USBEPCSR_OATCLR | /* Auto Clear USBORDY */
#endif /* USB_EP4_IN */
S3C2510_USBEPCSR_MAXPSET | /* USB MAXP Size Settable */
S3C2510_USBEPCSR_MAXP_64; /* 64 byte */
/* Enable suspend mode. */
*S3C2510_USBPM = SS3C2510_USBPM_SUSPENDEN; /* Suspend Enable */
#if 1
/* GDMA channel 4 is used in IN transfer*/
s3c2510ResetGDMA(GDMA_USB_IN);
*S3C2510_DCON(GDMA_USB_IN) = S3C2510_DCON_DD_FIX |
S3C2510_DCON_SD_INC |
S3C2510_DCON_TS_32|
/* S3C2510_DCON_SB |*/
S3C2510_DCON_MODE_SOFT;
/* GDMA channel 5 is used in OUT transfer */
s3c2510ResetGDMA(GDMA_USB_OUT);
*S3C2510_DCON(GDMA_USB_OUT) = S3C2510_DCON_DD_INC |
S3C2510_DCON_SD_FIX |
S3C2510_DCON_TS_32|
/* S3C2510_DCON_SB |*/
S3C2510_DCON_MODE_SOFT;
#endif
/* Added by Ajay to test ---end */
/* Initialize Endpoint 0 state. */
ep0State = EP0_STATE_IDLE;
ep0RxBuffer = NULL;
ep0RxLength = 0;
ep0RxCount = 0;
ep0TxBuffer = NULL;
ep0TxLength = 0;
ep0TxCount = 0;
memset(ep12LoopbackBuffer,0,sizeof(ep12LoopbackBuffer));
memset(ep34LoopbackBuffer,0,sizeof(ep34LoopbackBuffer));
ep3RxBuffer = (UINT32 *)ep34LoopbackBuffer;
ep1RxBuffer = (UINT32 *)ep12LoopbackBuffer;
/* Initialize Device status. */
deviceStatus = 0;
deviceConfig = 1;
deviceInterface = 1;
/* Initialize Endpoint status. */
ep0Status = 0;
ep1Status = 0;
ep2Status = 0;
ep3Status = 0;
ep4Status = 0;
/* Clear status. */
*S3C2510_USBINTR = *S3C2510_USBINTR;
/* Initialize USB Iterrupt Enable Register. */
*S3C2510_USBINTRE = S3C2510_USBINTRE_RESET | /* Reset Interrupt */
S3C2510_USBINTRE_SUSPEND | /* Suspend Interrupt */
S3C2510_USBINTRE_EP4 | /* EP4 Interrupt Enable */
S3C2510_USBINTRE_EP3 | /* EP3 Interrupt Enable */
S3C2510_USBINTRE_EP2 | /* EP2 Interrupt Enable */
S3C2510_USBINTRE_EP1 | /* EP1 Interrupt Enable */
S3C2510_USBINTRE_EP0; /* EP0 Interrupt Enable */
}
/*******************************************************************************
*
* s3c2510UsbGetStatus - get status.
*
* RETURNS : N/A
*/
void s3c2510UsbGetStatus(void)
{
UINT8 recipient = usbSetup.bmRequestType & USB_RT_RECIPIENT_MASK;
UINT8 index = LSB(FROM_LITTLEW(usbSetup.wIndex));
#ifdef DEBUG_TRACE
printf("s3c2510Usb GetStatus, 0x%02X, 0x%02X\n", recipient, index);
#endif /* DEBUG_TRACE */
switch (recipient)
{
case USB_RT_DEVICE:
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY;
*S3C2510_USBWCEP(0) = USB_STANDARD_STATUS_LEN << S3C2510_USBWCEP_CPUWRTCNT_SHIFT;
*S3C2510_USBFIFO(0) = TO_LITTLEL(deviceStatus);
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBINRDY | S3C2510_USBEP0CSR_USBDEND;
break;
case USB_RT_ENDPOINT:
switch (index & 0x7f)
{
case 0:
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY;
*S3C2510_USBWCEP(0) = USB_STANDARD_STATUS_LEN << S3C2510_USBWCEP_CPUWRTCNT_SHIFT;
*S3C2510_USBFIFO(0) = TO_LITTLEL(ep0Status);
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBINRDY | S3C2510_USBEP0CSR_USBDEND;
break;
case 1:
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY;
*S3C2510_USBWCEP(0) = USB_STANDARD_STATUS_LEN << S3C2510_USBWCEP_CPUWRTCNT_SHIFT;
*S3C2510_USBFIFO(0) = TO_LITTLEL(ep1Status);
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBINRDY | S3C2510_USBEP0CSR_USBDEND;
break;
case 2:
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY;
*S3C2510_USBWCEP(0) = USB_STANDARD_STATUS_LEN << S3C2510_USBWCEP_CPUWRTCNT_SHIFT;
*S3C2510_USBFIFO(0) = TO_LITTLEL(ep2Status);
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBINRDY | S3C2510_USBEP0CSR_USBDEND;
break;
case 3:
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY;
*S3C2510_USBWCEP(0) = USB_STANDARD_STATUS_LEN << S3C2510_USBWCEP_CPUWRTCNT_SHIFT;
*S3C2510_USBFIFO(0) = TO_LITTLEL(ep3Status);
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBINRDY | S3C2510_USBEP0CSR_USBDEND;
break;
case 4:
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY;
*S3C2510_USBWCEP(0) = USB_STANDARD_STATUS_LEN << S3C2510_USBWCEP_CPUWRTCNT_SHIFT;
*S3C2510_USBFIFO(0) = TO_LITTLEL(ep4Status);
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBINRDY | S3C2510_USBEP0CSR_USBDEND;
break;
default:
printf("s3c2510Usb Error: Unknown endpoint, 0x%02X\n", index);
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY;
*S3C2510_USBWCEP(0) = 0;
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBINRDY | S3C2510_USBEP0CSR_USBDEND;
break;
}
break;
default:
printf("s3c2510Usb Error: Unknown recipient, 0x%02X\n", recipient);
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY;
*S3C2510_USBWCEP(0) = 0;
*S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBINRDY | S3C2510_USBEP0CSR_USBDEND;
break;
}
}
/*******************************************************************************
*
* s3c2510UsbClearFeature - clear feature.
*
* RETURNS : N/A
*/
void s3c2510UsbClearFeature(void)
{
UINT16 feature = FROM_LITTLEW(usbSetup.wValue);
UINT8 index = LSB(FROM_LITTLEW(usbSetup.wIndex));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -