📄 usbctrltrf.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 + -