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

📄 ctrlreq.c

📁 FS7805 使用APLIF的demoFS7805 使用APLIF的demo
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
* File:     CtrlReq.C
* Contents: Firmware frameworks task dispatcher and device request parser source
*
* $Date:    04/06/06    Kimi    v0.1
* $Date:    04/25/06    Kimi    v0.2
* $Date:    04/30/06    Kimi    v0.3
* $Date:    01/23/07    Kevin   v0.4
* Copyright (c) 2006 Fameg, Inc. All rights reserved
*********************************************************************************************************
*/

#include "fs7805.h"
#include "fs7805regs.h"
#include "dscr.h"

#define USB_STALL_EP0() EP0RXCS = EP0RXCS | bmRX0_SESTALL;  \
                        EP0TXCS = EP0TXCS | bmTX0_SESTALL

/*
*********************************************************************************************************
*                                       VARIABLE PROTOTYPES
*********************************************************************************************************
*/
static  INT8U SetupData[8], PacketSize;
static  INT8U AlternateSetting;
static  BOOLEAN HighSpeed;
static  INT8U EnterSuspend = 0;
/*
*********************************************************************************************************
*                                       FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static  void  DR_ClearFeature (void);
static  void  DR_GetConfiguration (void);
static  void  DR_GetDescriptor (void);
static  void  DR_GetInterface (void);
static  void  DR_GetStatus (void);
static  void  DR_SetAddress (void);
static  void  DR_SetConfiguration (void);
static  void  DR_SetFeature (void);
static  void  DR_SetInterface (void);
static  void  GD_DeviceDscr (void);
static  void  GD_DeviceQualDscr (void);
static  void  GD_ConfigDscr (void);
static  void  GD_OtherConfigDscr (void);
static  void  GD_String (void);
static  void  SetupCommand (void);

/*
*********************************************************************************************************
*                                             USB_INT_ISR
*
* Description: Interrupt Service Routine
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/
void  USB_INT_ISR (void) interrupt 5
{
    if (STINT & bmIDLE3MSINT)                          // idle interrupt
    {
        if (EnterSuspend++)
        {
            USBGCTRL        = USBGCTRL | bmSUSPEND;
        }
        STINT           = STINT & (~bmIDLE3MSINT);
    }

    if (STINT & bmRESUMEIE)                            // resume interrupt
    {
        STINT           = STINT & (~bmRESUMEIE);
    }

    if (STINT & bmUSBRSTINT)                           // reset interrupt
    {
        while (!(USBGCTRL & bmHS_DETECTED));           // detect USB speed
        HighSpeed       = USBGCTRL & bmSPEED;
        if (HighSpeed)                                 // High speed
        {
            PacketSize  = 64;
        }
        else                                           // Full speed
        {
            PacketSize  = 64;
        }
        STINT           = STINT & (~bmUSBRSTINT);
    }

    if ((EPINT & bmRX0INT) && ((EP0RXTKN & bmEP0_SETUP) | (EP0RXTKN & bmEP0_SETUPOW)))
    {                                                  // enquire the EP0 RX setup interrupt
        EP0RXTKN        = EP0RXTKN & (~bmEP0_SETUP) & (~bmEP0_SETUPOW);
        SetupCommand();                                // Parse command
    }

    if ((EPINT & bmRX0INT) && (EP0RXTKN & bmEP0_OUT))  // out packet
    {
        EP0RXTKN        = EP0RXTKN & (~bmEP0_OUT);
    }

#ifndef ISOCHRONOUS
    if ((EPINT & bmEP2INT) && (EP2CS & bmEP_ACK))
    {
        EPINT   = EPINT & (~bmEP2INT);                 // Clear EP2 interrupt
        OutData = TRUE;
    }
    else
    {
        EPINT   = EPINT & (~bmEP2INT);                 // Clear EP2 interrupt
    }
#else
    if (EPINT & bmEP2INT)
    {
        EPINT   = EPINT & (~bmEP2INT);                 // Clear EP2 interrupt
        OutData = TRUE;
    }
#endif

#ifndef ISOCHRONOUS
    if ((EPINT & bmEP1INT) && (EP1CS & bmEP_ACK))
    {
        EPINT   = EPINT & (~bmEP1INT);                 // Clear EP1 interrupt
        InData  = TRUE;
    }
    else
    {
        EPINT   = EPINT & (~bmEP1INT);                 // Clear EP1 interrupt
    }
#else
    if (EPINT & bmEP1INT)
    {
        EPINT   = EPINT & (~bmEP1INT);                 // Clear EP1 interrupt
        InData  = TRUE;
    }
#endif
}


/*
*********************************************************************************************************
*                                             SETUPCOMMAND
*
* Description: Parse command function
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/
void  SetupCommand (void)
{
    INT8U   i, count;

    count   = EP0RXCNT;
    if (count == 8)
    {
        for (i = 0; i < 8; i++)                        // Receive data
        {
            SetupData[i]    = EP0RXDAT;
        }

        switch (SetupData[1])                          // Parse
        {
            case SC_GET_STATUS:
                DR_GetStatus();
                break;
            case SC_CLEAR_FEATURE:
                DR_ClearFeature();
                break;
            case SC_SET_FEATURE:
                DR_SetFeature();
                break;
            case SC_SET_ADDRESS:
                DR_SetAddress();
                break;
            case SC_GET_DESCRIPTOR:
                DR_GetDescriptor();
                break;
            case SC_GET_CONFIGURATION:
                DR_GetConfiguration();
                break;
            case SC_SET_CONFIGURATION:
                DR_SetConfiguration();
                break;
            case SC_GET_INTERFACE:
                DR_GetInterface();
                break;
            case SC_SET_INTERFACE:
                DR_SetInterface();
                break;
            default:
                USB_STALL_EP0();                       // Send STALL
                break;
        }
    }
    EP0RXCS     = EP0RXCS | bmRX0_EN;
}
/*$PAGE*/

/*
*********************************************************************************************************
*                                             DR_GETSTATUS
*
* Description: Get status command
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/
void  DR_GetStatus (void)
{
    switch (SetupData[0])
    {
        case GS_DEVICE:
            EP0TXDAT    = (Rwuen << 1) | Selfpwr;
            break;
        case GS_INTERFACE:
            EP0TXDAT    = 0;
            break;
        case GS_ENDPOINT:
            switch (SetupData[4] & 0x0F)
            {
                case bmEP1MAP:
                    EP0TXDAT    = (EP1CS & bmEP_SESTALL) >> 1;
                    break;
                case bmEP2MAP:
                    EP0TXDAT    = (EP2CS & bmEP_SESTALL) >> 1;
                    break;
                default:
                    USB_STALL_EP0();                   // Send STALL
                    return;
            }
            break;
        default:
            USB_STALL_EP0();                           // Send STALL
            return;
    }
    EP0TXDAT    = 0;
    EP0TXCNT    = 2;
    EP0TXCS     = EP0TXCS | bmTX0_EN;
    while (EP0TXCS & bmTX0_EN);
}
/*$PAGE*/

/*
*********************************************************************************************************
*                                             DR_CLEARFEATURE
*
* Description: Clear feature
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/
void  DR_ClearFeature (void)
{
    switch (SetupData[0])
    {
        case FT_DEVICE:
            if (SetupData[2] == 1)
            {
                Rwuen       = FALSE;
            }
            else
            {
                USB_STALL_EP0();
                return;
            }
            break;
        case FT_ENDPOINT:
            if (SetupData[2] == 0)
            {
                switch (SetupData[4] & 0x0F)
                {
                    case bmEP1MAP:
                        EP1CS       = EP1CS & (~bmEP_SESTALL) | bmEP_CLRTOG;
                        break;
                    case bmEP2MAP:
                        EP2CS       = EP2CS & (~bmEP_SESTALL) | bmEP_CLRTOG;
                        break;
                    default:
                        USB_STALL_EP0();
                        return;
                }
            }
            else
            {
                USB_STALL_EP0();
                return;
            }
            break;
        default:
            USB_STALL_EP0();                           // Send STALL
            return;
    }
    EP0TXCNT    = 0;
    EP0TXCS     = EP0TXCS | bmTX0_EN;
    while (EP0TXCS & bmTX0_EN);
}
/*$PAGE*/

/*
*********************************************************************************************************
*                                             DR_SETFEATURE
*
* Description: Set feature
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/
void  DR_SetFeature (void)
{
    switch (SetupData[0])
    {
        case FT_DEVICE:
            if (SetupData[2] == 1)
            {
                Rwuen   = TRUE;
            }
            else if (SetupData[2] == 2)
            {
                break;
            }
            else
            {
                USB_STALL_EP0();
                return;
            }
            break;
        case FT_ENDPOINT:
            if (SetupData[2] == 0)
            {
                switch (SetupData[4] & 0x0F)
                {
                    case bmEP1MAP:
                        EP1CS       = EP1CS | bmEP_SESTALL;
                        break;
                    case bmEP2MAP:
                        EP2CS       = EP2CS | bmEP_SESTALL;
                        break;
                    default:
                        USB_STALL_EP0();
                        return;
                }
            }
            else
            {
                USB_STALL_EP0();
                return;
            }
            break;
        default:
            USB_STALL_EP0();                           // Send STALL
            return;
    }
    EP0TXCNT    = 0;
    EP0TXCS     = EP0TXCS | bmTX0_EN;
    while (EP0TXCS & bmTX0_EN);
}
/*$PAGE*/

/*
*********************************************************************************************************
*                                             DR_SETADDRESS
*
* Description: Set address
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/
void  DR_SetAddress (void)
{
    EP0TXCNT    = 0;                                   // Write data length
    EP0TXCS     = EP0TXCS | bmTX0_EN;                  // Enable TX
    while (EP0TXCS & bmTX0_EN);                        // Wait complete
    if (EP0TXCS & bmTX0_ACK)
    {
        USBFADDR    = SetupData[2];                    // Set address
    }
}
/*$PAGE*/

/*
*********************************************************************************************************
*                                             DR_GETDESCRIPTOR
*
* Description: Get descriptor
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/
void  DR_GetDescriptor (void)
{
    switch (SetupData[3])
    {
        case GD_DEVICE:
            GD_DeviceDscr();
            break;
        case GD_CONFIGURATION:
            if (HighSpeed)
            {
                GD_ConfigDscr();
            }
            else
            {
                GD_OtherConfigDscr();
            }
            break;
        case GD_STRING:
            GD_String();
            break;

⌨️ 快捷键说明

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