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

📄 main.c

📁 使用Jungo Windriver開發的USB driver 及其firmware,類型為mass storage,應用於FX2(Cypress CY68013A)上.
💻 C
字号:
/******************************************************************************
*   File:     main.c                                                         
*                                                                             
*   Contents:  Implementation of the firmware's main entry point for
*              l123456 devices, based on the Cypress FX2LP (CY7C68013A)
*              development board.
*
*   Code was generated by DriverWizard v8.02 - http://www.jungo.com
*   Copyright (c) 2008 Jungo Ltd.  http://www.jungo.com
*******************************************************************************/

#include "wdf_cypress.h"
#include "wdf_cypress_lib.h"
#include "periph.h"

//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
#define DELAY_COUNT   0x9248*8L  // Delay for 8 sec at 24Mhz, 4 sec at 48
#define _IFREQ  48000            // IFCLK constant for Synchronization Delay
#define _CFREQ  48000            // CLKOUT constant for Synchronization Delay

#if defined(FX2LP)
    #define INTERNAL_ADDR_HIGH 0x3FFF
#else
    #define INTERNAL_ADDR_HIGH 0x1FFF 
#endif

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
volatile BOOL   GotSUD;
BOOL      Rwuen;
BOOL      Selfpwr;
volatile BOOL   Sleep;                  // Sleep mode enable flag

WORD   pDeviceDscr;   // Pointer to Device Descriptor; Descriptors may be moved
WORD   pDeviceQualDscr;
WORD   pHighSpeedConfigDscr;
WORD   pFullSpeedConfigDscr;   
WORD   pConfigDscr;
WORD   pOtherConfigDscr;   
WORD   pStringDscr;   

void SetupCommand(void);

// this table is used by the epcs macro 
const char code  EPCS_Offset_Lookup_Table[] =
{
    0,    // EP1OUT
    1,    // EP1IN
    2,    // EP2OUT
    2,    // EP2IN
    3,    // EP4OUT
    3,    // EP4IN
    4,    // EP6OUT
    4,    // EP6IN
    5,    // EP8OUT
    5,    // EP8IN
};

// macro for generating the address of an endpoint's control and status register (EPnCS)
#define epcs(EP) (EPCS_Offset_Lookup_Table[(EP & 0x7E) | (EP > 128)] + 0xE6A1)

//-----------------------------------------------------------------------------
// Code
//-----------------------------------------------------------------------------

// Task dispatcher
void main(void)
{
    DWORD i;
    WORD offset;
    DWORD DevDescrLen;
    DWORD j=0;
    WORD IntDescrAddr;
    WORD ExtDescrAddr;
    DWORD nSetupRequests = 0;

    // Initialize Global States
    Sleep = FALSE;               // Disable sleep mode
    GotSUD = FALSE;               // Clear "Got setup data" flag

    // Initialize I2C interface
    WDF_I2CInit();

    // Initialize user device
    WDF_Init();

    // The following section of code is used to relocate the descriptor table. 
    // The frameworks uses SUDPTRH and SUDPTRL to automate the SETUP requests
    // for descriptors.  These registers only work with memory locations
    // in the EZ-USB internal RAM.  Therefore, if the descriptors are located
    // in external RAM, they must be copied to in internal RAM.  
    // The descriptor table is relocated by the frameworks ONLY if it is found 
    // to be located in external memory.
    pDeviceDscr = (WORD)&DeviceDscr;
    pDeviceQualDscr = (WORD)&DeviceQualDscr;
    pHighSpeedConfigDscr = (WORD)&HighSpeedConfigDscr;
    pFullSpeedConfigDscr = (WORD)&FullSpeedConfigDscr;
    pStringDscr = (WORD)&StringDscr;

    // Is the descriptor table in external RAM (> 16Kbytes)?  If yes,
    // then relocate.
    // Note that this code only checks if the descriptors START in 
    // external RAM.  It will not work if the descriptor table spans
    // internal and external RAM.
    DevDescrLen = (WORD)&UserDscr - (WORD)&DeviceDscr + 2;
    if ((WORD)(&DeviceDscr + DevDescrLen) & ~INTERNAL_ADDR_HIGH)
    {
        // first, relocate the descriptors
        IntDescrAddr = INTERNAL_DSCR_ADDR;
        ExtDescrAddr = (WORD)&DeviceDscr;
        for (i = 0; i < DevDescrLen; i++)
            *((BYTE xdata *)IntDescrAddr+i) = *((BYTE xdata *)ExtDescrAddr+i);

        // update all of the descriptor pointers
        pDeviceDscr = IntDescrAddr;
        offset = (WORD)&DeviceDscr - INTERNAL_DSCR_ADDR;
        pDeviceQualDscr -= offset;
        pConfigDscr -= offset;
        pOtherConfigDscr -= offset;
        pHighSpeedConfigDscr -= offset;
        pFullSpeedConfigDscr -= offset;
        pStringDscr -= offset;
    }

    EZUSB_IRQ_ENABLE();            // Enable USB interrupt (INT2)
    EZUSB_ENABLE_RSMIRQ();            // Wake-up interrupt

    INTSETUP |= (bmAV2EN | bmAV4EN);     // Enable INT 2 & 4 autovectoring

    USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT;   // Enable selected interrupts
    EA = 1;                  // Enable 8051 interrupts

#ifndef NO_RENUM
    EZUSB_Discon(TRUE);   // renumerate
#endif

    // unconditionally re-connect.  If we loaded from eeprom we are
    // disconnected and need to connect.  If we just renumerated this
    // is not necessary but doesn't hurt anything
    USBCS &=~bmDISCON;

    CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch

    // Task Dispatcher
    while(TRUE)               // Main Loop
    {
        // Poll User Device
        WDF_Poll();

        // Check for pending SETUP
        if(GotSUD)
        {
            SetupCommand();          // Implement setup command
            GotSUD = FALSE;          // Clear SETUP flag
        }

        // check for and handle suspend.
        // NOTE: Idle mode stops the processor clock.  There are only two
        // ways out of idle mode, the WAKEUP pin, and detection of the USB
        // resume state on the USB bus.  The timers will stop and the
        // processor will not wake up on any other interrupts.
        if (Sleep)
        {
            if(WDF_Suspend())
            { 
                 Sleep = FALSE;     // Clear the "go to sleep" flag.  Do it here to
                                    // prevent any race condition between wakeup and the next sleep.
                 do
                 {
                     EZUSB_Susp();         // Place processor in idle mode.
                 }
                 while(!Rwuen && EZUSB_EXTWAKEUP());
		        // above.  Must continue to go back into suspend if the host has disabled remote wakeup
                 // and the wakeup was caused by the external wakeup pin.

                 // 8051 activity will resume here due to USB bus or Wakeup# pin activity.
                 EZUSB_Resume();   // If source is the Wakeup# pin, signal the host to Resume.
                 WDF_Resume();
            }
        }
    }
}

// Device request parser
void SetupCommand(void)
{
    void   *dscr_ptr;

    switch(SETUPDAT[1])
    {
    case SC_GET_DESCRIPTOR:                  // *** Get Descriptor
	if(WDF_GetDescriptor())
	    switch(SETUPDAT[3])         
	    {
	    case GD_DEVICE:            // Device
		SUDPTRH = MSB(pDeviceDscr);
		SUDPTRL = LSB(pDeviceDscr);
		break;
	    case GD_DEVICE_QUALIFIER:            // Device Qualifier
		SUDPTRH = MSB(pDeviceQualDscr);
		SUDPTRL = LSB(pDeviceQualDscr);
		break;
	    case GD_CONFIGURATION:         // Configuration
		SUDPTRH = MSB(pConfigDscr);
		SUDPTRL = LSB(pConfigDscr);
		break;
	    case GD_OTHER_SPEED_CONFIGURATION:  // Other Speed Configuration
		SUDPTRH = MSB(pOtherConfigDscr);
		SUDPTRL = LSB(pOtherConfigDscr);
		break;
	    case GD_STRING:            // String
		if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2]))
		{
		    SUDPTRH = MSB(dscr_ptr);
		    SUDPTRL = LSB(dscr_ptr);
		}
		else 
		    EZUSB_STALL_EP0();   // Stall End Point 0
		break;
	    default:            // Invalid request
		EZUSB_STALL_EP0();      // Stall End Point 0
	    }
	break;
    case SC_GET_INTERFACE:                  // *** Get Interface
        WDF_GetInterface(SETUPDAT[3]);
        break;
    case SC_SET_INTERFACE:                  // *** Set Interface
        WDF_SetInterface(SETUPDAT[3], SETUPDAT[2]);
        break;
    case SC_SET_CONFIGURATION:               // *** Set Configuration
        WDF_SetConfiguration(SETUPDAT[2]);
        break;
    case SC_GET_CONFIGURATION:               // *** Get Configuration
        WDF_GetConfiguration();
        break;
    case SC_GET_STATUS:                  // *** Get Status
        if(WDF_GetStatus())
        {
            switch(SETUPDAT[0])
            {
            case GS_DEVICE:            // Device
                EP0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr;
                EP0BUF[1] = 0;
                EP0BCH = 0;
                EP0BCL = 2;
                break;
            case GS_INTERFACE:         // Interface
                EP0BUF[0] = 0;
                EP0BUF[1] = 0;
                EP0BCH = 0;
                EP0BCL = 2;
                break;
            case GS_ENDPOINT:         // End Point
                EP0BUF[0] = *(BYTE xdata *) epcs(SETUPDAT[4]) & bmEPSTALL;
                EP0BUF[1] = 0;
                EP0BCH = 0;
                EP0BCL = 2;
                break;
            default:            // Invalid Command
                EZUSB_STALL_EP0();      // Stall End Point 0
            }
        }
        break;
    case SC_CLEAR_FEATURE:                  // *** Clear Feature
        if(WDF_ClearFeature())
        {
            switch(SETUPDAT[0])
            {
            case FT_DEVICE:            // Device
                if(SETUPDAT[2] == 1)
                    Rwuen = FALSE;       // Disable Remote Wakeup
                else
                    EZUSB_STALL_EP0();   // Stall End Point 0
                break;
            case FT_ENDPOINT:         // End Point
                if(SETUPDAT[2] == 0)
                {
                    *(BYTE xdata *) epcs(SETUPDAT[4]) &= ~bmEPSTALL;
                    EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] );
                }
                else
                    EZUSB_STALL_EP0();   // Stall End Point 0
                break;
            }
        }
        break;
    case SC_SET_FEATURE:                  // *** Set Feature
        if(WDF_SetFeature())
        {
            switch(SETUPDAT[0])
            {
            case FT_DEVICE:            // Device
                if(SETUPDAT[2] == 1)
                    Rwuen = TRUE;      // Enable Remote Wakeup
                else if(SETUPDAT[2] == 2)
                    // Set Feature Test Mode.  The core handles this request.  However, it is
                    // necessary for the firmware to complete the handshake phase of the
                    // control transfer before the chip will enter test mode.  It is also
                    // necessary for FX2 to be physically disconnected (D+ and D-)
                    // from the host before it will enter test mode.
                    break;
       	       else
                    EZUSB_STALL_EP0();   // Stall End Point 0
                break;
            case FT_ENDPOINT:         // End Point
                *(BYTE xdata *) epcs(SETUPDAT[4]) |= bmEPSTALL;
		       break;
            default:
                EZUSB_STALL_EP0();      // Stall End Point 0
            }
        }
        break;
    default:                     // *** Invalid Command
        if(!WDF_VendorCmnd())
            EZUSB_STALL_EP0();            // Stall End Point 0
    }

    // Acknowledge handshake phase of device request
    EP0CS |= bmHSNAK;
}

// Wake-up interrupt handler
void resume_isr(void) interrupt WKUP_VECT
{
    EZUSB_CLEAR_RSMIRQ();
}

⌨️ 快捷键说明

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