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

📄 usbctrltrf.c

📁 PIC18F4550_Cdc PIC18F4550_Cdc
💻 C
字号:
/*********************************************************************
 * FileName:        usbctrltrf.c
 ********************************************************************/
#include <p18cxxx.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"

#pragma udata
byte ctrl_trf_state;                // Control Transfer State
byte ctrl_trf_session_owner;        // Current transfer session owner
POINTER pSrc;                       // Data source pointer
POINTER pDst;                       // Data destination pointer
WORD wCount;                        // Data counter
byte short_pkt_status;              // Flag used by Control Transfer Read

void USBCtrlTrfSetupHandler(void);
void USBCtrlTrfOutHandler(void);
void USBCtrlTrfInHandler(void);

#pragma code
/******************************************************************************
 * Function:        void USBCtrlEPService(void)
 * PreCondition:    USTAT is loaded with a valid endpoint address.
 * Input:           None
 * Output:          None
 *****************************************************************************/
byte USBCtrlEPService(void)
{
    if(USTAT == EP00_OUT)
    {
        UIRbits.TRNIF = 0;
        if(ep0Bo.Stat.PID == SETUP_TOKEN)           // EP0 SETUP
            USBCtrlTrfSetupHandler();
        else                                        // EP0 OUT
            USBCtrlTrfOutHandler();
    }
    else if(USTAT == EP00_IN)            	        // EP0 IN
    {
        UIRbits.TRNIF = 0;
        USBCtrlTrfInHandler();
    }
    else
    {
        return 0;           // Return '0', if not an EP0 transaction
    }
    return 1;               // Return '1', if TRNIF has been cleared

}

/******************************************************************************
 * Function:        void USBCtrlTrfSetupHandler(void)
 * PreCondition:    SetupPkt buffer is loaded with valid USB Setup Data
 * Input:           None
 * Output:          None
 * Side Effects:    None
 *****************************************************************************/
void USBCtrlTrfSetupHandler(void)
{
    byte i;
    if(ep0Bi.Stat.UOWN != 0)
        ep0Bi.Stat._byte = _UCPU;           // Compensate for after a STALL
    short_pkt_status = SHORT_PKT_NOT_USED;
    ctrl_trf_state = WAIT_SETUP;
    ctrl_trf_session_owner = MUID_NULL;     // Set owner to NULL
    wCount._word = 0;
    USBCheckStdRequest();                   // See system\usb9\usb9.c

    for(i=0;i < (sizeof(ClassReqHandler)/sizeof(pFunc));i++)
    {
        if(ctrl_trf_session_owner != MUID_NULL)break;
        ClassReqHandler[i]();               // See autofiles\usbdsc.c
    }
    USBCtrlEPServiceComplete();
}

/******************************************************************************
 * Function:        void USBCtrlTrfOutHandler(void)
 * PreCondition:    None
 * Input:           None
 * Output:          None
 *****************************************************************************/
void USBCtrlTrfOutHandler(void)
{
    if(ctrl_trf_state == CTRL_TRF_RX)
    {
        USBCtrlTrfRxService();
        if(ep0Bo.Stat.DTS == 0)
            ep0Bo.Stat._byte = _USIE|_DAT1|_DTSEN;
        else
            ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN;
    }
    else    
        USBPrepareForNextSetupTrf();

}

/******************************************************************************
 * Function:        void USBCtrlTrfInHandler(void)
 * PreCondition:    None
 * Input:           None
 * Output:          None
 *****************************************************************************/
void USBCtrlTrfInHandler(void)
{
    mUSBCheckAdrPendingState();         // Must check if in ADR_PENDING_STATE

    if(ctrl_trf_state == CTRL_TRF_TX)
    {
        USBCtrlTrfTxService();
        if(short_pkt_status == SHORT_PKT_SENT)
        {
            ep0Bi.Stat._byte = _USIE|_BSTALL;
        }
/*******************************************************************/
        else
        {
            if(ep0Bi.Stat.DTS == 0)
                ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
            else
                ep0Bi.Stat._byte = _USIE|_DAT0|_DTSEN;
        }
    }
    else 
        USBPrepareForNextSetupTrf();
}

/******************************************************************************
 * Function:        void USBCtrlTrfTxService(void)
 * PreCondition:    pSrc, wCount, and usb_stat.ctrl_trf_mem are setup properly.
 * Input:           None
 * Output:          None
 *****************************************************************************/
void USBCtrlTrfTxService(void)
{
    WORD byte_to_send;
    if(wCount._word < EP0_BUFF_SIZE)
    {
        byte_to_send._word = wCount._word;
        if(short_pkt_status == SHORT_PKT_NOT_USED)
        {
            short_pkt_status = SHORT_PKT_PENDING;
        }
        else if(short_pkt_status == SHORT_PKT_PENDING)
        {
            short_pkt_status = SHORT_PKT_SENT;
        }//end if
/*******************************************************************/
    }
    else
        byte_to_send._word = EP0_BUFF_SIZE;
    ep0Bi.Stat.BC9 = 0;
    ep0Bi.Stat.BC8 = 0;
    ep0Bi.Stat._byte |= MSB(byte_to_send);
    ep0Bi.Cnt = LSB(byte_to_send);
    wCount._word = wCount._word - byte_to_send._word;

    pDst.bRam = (byte*)&CtrlTrfData;        // Set destination pointer

    if(usb_stat.ctrl_trf_mem == _ROM)       // Determine type of memory source
    {
        while(byte_to_send._word)
        {
            *pDst.bRam = *pSrc.bRom;
            pDst.bRam++;
            pSrc.bRom++;
            byte_to_send._word--;
        }//end while(byte_to_send._word)
    }
    else // RAM
    {
        while(byte_to_send._word)
        {
            *pDst.bRam = *pSrc.bRam;
            pDst.bRam++;
            pSrc.bRam++;
            byte_to_send._word--;
        }//end while(byte_to_send._word)
    }//end if(usb_stat.ctrl_trf_mem == _ROM)

}//end USBCtrlTrfTxService

/******************************************************************************
 * Function:        void USBCtrlTrfRxService(void)
 * PreCondition:    pDst and wCount are setup properly.
 *                  pSrc is always &CtrlTrfData
 *                  usb_stat.ctrl_trf_mem is always _RAM.
 *                  wCount should be set to 0 at the start of each control
 *                  transfer.
 * Input:           None
 * Output:          None
 *****************************************************************************/
void USBCtrlTrfRxService(void)
{
    WORD byte_to_read;

    MSB(byte_to_read) = 0x03 & ep0Bo.Stat._byte;    // Filter out last 2 bits
    LSB(byte_to_read) = ep0Bo.Cnt;
    wCount._word = wCount._word + byte_to_read._word;

    pSrc.bRam = (byte*)&CtrlTrfData;

    while(byte_to_read._word)
    {
        *pDst.bRam = *pSrc.bRam;
        pDst.bRam++;
        pSrc.bRam++;
        byte_to_read._word--;
    }//end while(byte_to_read._word)

}//end USBCtrlTrfRxService

/******************************************************************************
 * Function:        void USBCtrlEPServiceComplete(void)
 * PreCondition:    None
 * Input:           None
 * Output:          None
 *****************************************************************************/
void USBCtrlEPServiceComplete(void)
{
    UCONbits.PKTDIS = 0;
/*******************************************************************/

    if(ctrl_trf_session_owner == MUID_NULL)
    {
        ep0Bo.Cnt = EP0_BUFF_SIZE;
        ep0Bo.ADR = (byte*)&SetupPkt;

        ep0Bo.Stat._byte = _USIE|_BSTALL;
        ep0Bi.Stat._byte = _USIE|_BSTALL;
    }
    else    
    {
        if(SetupPkt.DataDir == DEV_TO_HOST)
        {
            if(SetupPkt.wLength < wCount._word)
                wCount._word = SetupPkt.wLength;
            USBCtrlTrfTxService();
            ctrl_trf_state = CTRL_TRF_TX;
            ep0Bo.Cnt = EP0_BUFF_SIZE;
            ep0Bo.ADR = (byte*)&SetupPkt;
            ep0Bo.Stat._byte = _USIE;           // Note: DTSEN is 0!
            ep0Bi.ADR = (byte*)&CtrlTrfData;
            ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
        }
        else   
        {
            ctrl_trf_state = CTRL_TRF_RX;
            ep0Bi.Cnt = 0;
            ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
            ep0Bo.Cnt = EP0_BUFF_SIZE;
            ep0Bo.ADR = (byte*)&CtrlTrfData;
            ep0Bo.Stat._byte = _USIE|_DAT1|_DTSEN;
        }
    }

}

/******************************************************************************
 * Function:        void USBPrepareForNextSetupTrf(void)
 * PreCondition:    None
 * Input:           None
 * Output:          None
 *****************************************************************************/
void USBPrepareForNextSetupTrf(void)
{
    if((ctrl_trf_state == CTRL_TRF_RX) &&
       (UCONbits.PKTDIS == 1) &&
       (ep0Bo.Cnt == sizeof(CTRL_TRF_SETUP)) &&
       (ep0Bo.Stat.PID == SETUP_TOKEN) &&
       (ep0Bo.Stat.UOWN == 0))
    {
        unsigned char setup_cnt;
        ep0Bo.ADR = (byte*)&SetupPkt;
        for(setup_cnt = 0; setup_cnt < sizeof(CTRL_TRF_SETUP); setup_cnt++)
        {
            *(((byte*)&SetupPkt)+setup_cnt) = *(((byte*)&CtrlTrfData)+setup_cnt);
        }//end for
    }
/*******************************************************************/
    else
    {
        ctrl_trf_state = WAIT_SETUP;            // See usbctrltrf.h
        ep0Bo.Cnt = EP0_BUFF_SIZE;              // Defined in usbcfg.h
        ep0Bo.ADR = (byte*)&SetupPkt;
        ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN|_BSTALL;  // Added #F1
        ep0Bi.Stat._byte = _UCPU;               // Should be removed
    }

}

⌨️ 快捷键说明

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