⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2510usbloopback.c

📁 VxWorks BSP for S3C2510A
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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 + -