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

📄 s3c2510usb.c

📁 VxWorks BSP for S3C2510A
💻 C
📖 第 1 页 / 共 3 页
字号:
/* s3c2510Usb.c - SAMSUNG S3C2510 USB driver  */

/* Copyright 2002 SAMSUNG ELECTRONICS */

/*
modification history
--------------------
01a,22apr02,jmLee   created.
*/


#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"

#include "drv/multi/s3c2510.h"
#include "config.h"
#include "drv/intrCtl/s3c2510Intr.h"
#include "s3c2510Usb.h"

#if 0
#undef  DEBUG_TRACE
#else
#define DEBUG_TRACE
#endif
#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 s3c2510UsbEp0Out();
LOCAL void s3c2510UsbEp0In();
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
LOCAL 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;
LOCAL UINT32 ep0RxLength;
LOCAL UINT32 ep0RxCount;
LOCAL UINT32 *ep0TxBuffer;
LOCAL UINT32 ep0TxLength;
LOCAL UINT32 ep0TxCount;

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] = {
    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] = {
    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_EP1_IN
    2 | USB_ENDPOINT_DIRECTION_IN,
#else   /* USB_EP1_IN */
    2 | USB_ENDPOINT_DIRECTION_OUT,
#endif  /* USB_EP1_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_EP1_IN
    3 | USB_ENDPOINT_DIRECTION_IN,
#else   /* USB_EP1_IN */
    3 | USB_ENDPOINT_DIRECTION_OUT,
#endif  /* USB_EP1_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_EP1_IN
    4 | USB_ENDPOINT_DIRECTION_IN,
#else   /* USB_EP1_IN */
    4 | USB_ENDPOINT_DIRECTION_OUT,
#endif  /* USB_EP1_IN */
    USB_EP4_TYPE,
    LSB(USB_EP4_MAXP_SIZE),
    MSB(USB_EP4_MAXP_SIZE),
    USB_EP4_INTERVAL
};


/*******************************************************************************
*
* 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;

    /* Initialize USB. */
    s3c2510UsbReset();

    /* Connect interrupt. */
    intConnect(INT_VEC_USB, (VOIDFUNCPTR)s3c2510UsbInt, 0);

    /* Disable interrupt. */
    intEnable(INT_LVL_USB);

    return OK;
}

/*******************************************************************************
*
* 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 */
#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 */
#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 3 Common Status Register. */
    *S3C2510_USBCSR(3) = S3C2510_USBEPCSR_CSR2SET |         /* CSR 8~12 Settable */
#ifdef  USB_EP3_IN
                         S3C2510_USBEPCSR_IN  |             /* IN Mode */
#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_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 */
#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_64;          /* 64 byte */

    /* Enable suspend mode. */
    *S3C2510_USBPM = SS3C2510_USBPM_SUSPENDEN;              /* Suspend Enable */

    /* Initialize Endpoint 0 state. */
    ep0State    = EP0_STATE_IDLE;
    ep0RxBuffer = NULL;
    ep0RxLength = 0;
    ep0RxCount  = 0;
    ep0TxBuffer = NULL;
    ep0TxLength = 0;
    ep0TxCount  = 0;

    /* 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));

#ifdef  DEBUG_TRACE
    printf("s3c2510Usb ClearFeature, 0x%04X, 0x%02X\n", feature, index);
#endif  /* DEBUG_TRACE */

    switch (feature)
    {
    case USB_FEATURE_ENDPOINT_STALL:
#ifdef  DEBUG_TRACE
        printf("USB_FEATURE_ENDPOINT_STALL\n");
#endif  /* DEBUG_TRACE */
        switch (index & 0x7f)
        {
        case 0:
            ep0Status = 0;
            break;

        case 1:
            ep1Status = 0;
            break;

        case 2:
            ep2Status = 0;
            break;

        case 3:
            ep3Status = 0;
            break;

        case 4:
            ep4Status = 0;
            break;

        default:
            printf("s3c2510Usb Error: Unknown endpoint, 0x%02X\n", index);
            break;
        }
        *S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY | S3C2510_USBEP0CSR_USBDEND;
        break;

    case USB_FEATURE_REMOTE_WAKEUP:
#ifdef  DEBUG_TRACE
        printf("USB_FEATURE_REMOTE_WAKEUP\n");
#endif  /* DEBUG_TRACE */
        deviceStatus = 0;
        *S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY | S3C2510_USBEP0CSR_USBDEND;
        break;

    default:
        printf("s3c2510Usb Error: Unknown feature, 0x%04X\n", feature);
        *S3C2510_USBCSR(0) |= S3C2510_USBEP0CSR_USBSVORDY | S3C2510_USBEP0CSR_USBDEND;
        break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -