📄 u_control.c
字号:
/******************************************************************************
* File name : control.c
* Module name : Control transfer module
* Author : Hiromichi.Kondo
*----------------------------------------------------------------------------
* $Id: control.c,v 1.3 2003/05/16 06:53:43 9551619 Exp $
*****************************************************************************/
#include "u_value.h"
#include "u_ram_data.h"
#include "u_rom_data.h"
#include "u_regNikka.h"
/*--- Function Prototype ---------------------------------------------------*/
void ControlTransfer(void);
void ControlRequest(void);
void ControlDataSet(void);
void ControlDataSend(void);
void ControlDataRcv(void);
void ControlDataGet(void);
#if 1
void FIFOReadProc(BYTE *p);
#endif
void ControlParaUpdate(void);
void AcceptDevSpecCmdCheck(void);
void ControlStatusStart(void);
void ControlStatusEnd(void);
void TestModeProc(void);
/*****************************************************************************
* control_tbl
*****************************************************************************/
void (*const control_tbl[])() = {
ControlRequest,
ControlDataSet,
ControlDataSend,
ControlDataRcv,
ControlDataGet,
ControlParaUpdate,
ControlStatusStart,
ControlStatusEnd
};
void ControlTransfer(void)
{
if (control_state >= CTRL_IDLE)
panic(6);
/* control_state */
control_tbl[control_state]();
}
/*****************************************************************************
* ControlRequest
*****************************************************************************/
void ControlRequest(void)
{
int ret;
usb_flag.Init = 0; /* */
usb_flag.USBReqRcvd = 0; /* USB */
rEPnControl_BP.EP0FIFO_Clr = 1;
rEP0ControlIN_BP.EnShortPkt = 0; /* EnShortPkt = 0 */
rEP0IntStat = rEP0IntStat; /* */
rEP0IntEnb_BP.EnIN_TranACK = 1; /* IN_TranACK */
rMainIntStat = 0x01; /* RcvEP0SETUP = 0 */
rEP0Control_BP.INxOUT = ((rEP0SETUP_0 & 0x80) ? 1 : 0);
req_tran_cnt = MKWORD(rEP0SETUP_7,rEP0SETUP_6);
switch(rEP0SETUP_0 & 0x60)
{
case STANDARD_REQUEST:
ret = StandardRequest();
break;
case CLASS_REQUEST:
ret = ClassRequest();
break;
case VENDOR_REQUEST:
ret = VendorRequest();
break;
default:
ret = REQUEST_ERROR;
break;
}
if (ret == REQUEST_OK)
{
if(req_tran_cnt != 0)
{
if(rEP0Control_BP.INxOUT)
{
control_state = CTRL_DATA_SET;
}
else
{
rEP0ControlOUT_BP.ForceNAK = 0;
control_state = CTRL_DATA_GET;
}
}
else
{
control_state = CTRL_STS_START;
}
}
else
{
/* STALL */
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}
}
/*****************************************************************************
* ControlDataSet
*****************************************************************************/
void ControlDataSet(void)
{
int i;
if( usb_flag.ReplyDescriptor )
{
/* Descriptor */
usb_flag.ReplyDescriptor = 0; /* Descriptor */
rEP0IntEnb_BP.EnIN_TranACK = 0; /* IN_TranACK */
rDescAdrs_H = DWORD2BYTE_LH((DWORD)tran_start_addr);
rDescAdrs_L = DWORD2BYTE_LL((DWORD)tran_start_addr);
rDescSize_H = WORD2BYTE_H(actual_tran_cnt);
rDescSize_L = WORD2BYTE_L(actual_tran_cnt);
rEP0Control_BP.ReplyDescriptor = 1;
}
else
{
if( actual_tran_cnt >= max_pkt_size_0 )
{
rCPU_JoinWr = 0x00;
rEnEPnFIFO_Access_BP.EnEPnFIFO_Wr = 1;
for( i=max_pkt_size_0; i>0; i--)
{
rEPnFIFOforCPU = *tran_start_addr;
tran_start_addr++;
}
rEnEPnFIFO_Access_BP.EnEPnFIFO_Wr = 0;
actual_tran_cnt -= max_pkt_size_0;
}
else
{
rCPU_JoinWr = 0x00;
rEnEPnFIFO_Access_BP.EnEPnFIFO_Wr = 1;
for( i=actual_tran_cnt; i>0; i-- )
{
rEPnFIFOforCPU = *tran_start_addr;
tran_start_addr++;
}
rEnEPnFIFO_Access_BP.EnEPnFIFO_Wr = 0;
actual_tran_cnt = 0;
rEP0ControlIN_BP.EnShortPkt = 1;
}
}
control_state = CTRL_DATA_SEND;
control_result = NO_RESULT;
rEP0ControlIN_BP.ForceNAK = 0;
}
/*****************************************************************************
* ControlDataSend
*****************************************************************************/
void ControlDataSend(void)
{
if( control_result == EP0_IN_ACK )
{
/* IN_TranACK */
control_result = NO_RESULT;
retry_cnt_0 = 0;
if( actual_tran_cnt )
{
control_state = CTRL_DATA_SET;
}
else
{
if( req_tran_cnt == total_tran_cnt )
{
control_state = CTRL_STS_START;
}
else
{
if( total_tran_cnt & (max_pkt_size_0 - 1) )
{
control_state = CTRL_STS_START;
}
else
{
rEP0ControlIN_BP.EnShortPkt = 1;
}
}
}
}
else
{
if( control_result == EP0_IN_ERR )
{
/* IN_TranErr */
control_result = NO_RESULT;
if( rEP0ControlIN_BP.ForceSTALL == 1 )
panic(7);
#ifdef DEBUG_PRINT
EP0INErrorCount++;
#endif
}
else
{
if( control_result == DESCRIPTOR_CMP )
{
actual_tran_cnt = MKWORD(rDescSize_H, rDescSize_L);
retry_cnt_0 = 0;
rEPnControl_BP.EP0FIFO_Clr = 1;
if( actual_tran_cnt == req_tran_cnt )
{
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}
else
{
control_state = CTRL_STS_START;
}
}
else
{
if( usb_flag.USBReqRcvd )
{
/* SETUP */
control_state = CTRL_REQ_CHECK;
}
else
{
if( rEP0IntStat_BP.OUT_TranNAK ){
/* OUT_TranNAK */
rEP0IntStat = 0x04;
retry_cnt_0++;
if( retry_cnt_0 > MAX_RETRY_CNT )
{
/* FIFO */
actual_tran_cnt = retry_cnt_0 = 0;
rEPnControl_BP.EP0FIFO_Clr = 1;
control_state = CTRL_STS_START;
}
}
}
}
}
}
}
/*****************************************************************************
* ControlDataRcv
*****************************************************************************/
void ControlDataRcv(void)
{
if( control_result == EP0_OUT_ACK )
{
/* OUT_TranACK */
control_result = NO_RESULT;
retry_cnt_0 = 0;
control_state = CTRL_DATA_GET;
}
else
{
if( control_result == EP0_OUT_ERR )
{
/* OUT_TranErr */
if( rEP0ControlOUT_BP.ForceSTALL == 1 )
panic(8);
#ifdef DEBUG_PRINT
EP0OUTErrorCount++;
#endif
}
else
{
if( usb_flag.USBReqRcvd )
{
/* SETUP */
control_state = CTRL_REQ_CHECK;
}
else
{
if( rEP0IntStat_BP.IN_TranNAK )
{
/* IN_TranNAK */
rEP0IntStat = 0x08;
retry_cnt_0++;
if( retry_cnt_0 > MAX_RETRY_CNT )
{
/* FIFO */
actual_tran_cnt = retry_cnt_0 = 0;
rEPnControl_BP.EP0FIFO_Clr = 1;
control_state = CTRL_STS_START;
}
}
}
}
}
}
/*****************************************************************************
* ControlDataGet
*****************************************************************************/
void ControlDataGet(void)
{
int i;
int fifo_remain;
control_result = NO_RESULT;
rCPU_JoinRd = 0x00;
fifo_remain = MKWORD(rEPnRdRemain_H, rEPnRdRemain_L);
if( fifo_remain == 0 )
{
if( actual_tran_cnt )
{
control_state = ((total_tran_cnt == actual_tran_cnt) ? \
CTRL_DATA_RCV : CTRL_PARA_UPDATE);
}
else
{
control_state = CTRL_STS_START;
}
}
else
{
if( actual_tran_cnt < fifo_remain )
{
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}
else
{
rCPU_JoinRd = 0x00;
rEnEPnFIFO_Access_BP.EnEPnFIFO_Rd = 1;
for( i=fifo_remain; i>0; i-- )
{
*tran_start_addr = rEPnFIFOforCPU;
tran_start_addr++;
}
rEnEPnFIFO_Access_BP.EnEPnFIFO_Rd = 0;
actual_tran_cnt -= fifo_remain;
if( actual_tran_cnt )
{
rEP0ControlOUT_BP.ForceNAK = 0;
control_state = CTRL_DATA_RCV;
}
else
{
control_state = CTRL_PARA_UPDATE;
}
}
}
}
/*****************************************************************************
* ControlParaUpdate
*****************************************************************************/
void ControlParaUpdate(void)
{
switch(rEP0SETUP_1)
{
case TEST_EP0_OUT:
if( actual_tran_cnt )
{
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}
else
{
control_state = CTRL_STS_START;
}
break;
case ACCEPT_DEV_SPC_CMD:
/* Accept Device-Specific Command */
AcceptDevSpecCmdCheck();
break;
default:
/* */
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}
}
/*****************************************************************************
* AcceptDevSpecCmdCheck
*****************************************************************************/
void AcceptDevSpecCmdCheck(void)
{
int i;
if( protocol_phase == DATA_PHASE )
{
if( usb_wk_data[0] == 0x1D && usb_wk_data[1] == 0x04 )
{
/* CBI Reset */
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}
else
{
/* CBI Reset */
protocol_phase = COMMAND_PHASE; /* */
int_in_state = INT_IN_IDLE; /* InterruptINIDLE */
for( i=0; i<12; i++ )
cmd_block[i] = usb_wk_data[i];
device_flag.RcvCommand = 1; /* */
control_state = CTRL_STS_START;
if( cmd_status == COMMAND_FAILED )
{
/* FAILED */
rEPaControl_BP.ForceSTALL = 0;
rEPbControl_BP.ForceSTALL = 0;
}
}
}
else
{
if( protocol_phase == STATUS_PHASE )
{
protocol_phase = COMMAND_PHASE;
int_in_state = INT_IN_IDLE; /* InterruptINIDLE */
}
for( i=0; i<12; i++ )
cmd_block[i] = usb_wk_data[i];
device_flag.RcvCommand = 1; /* */
control_state = CTRL_STS_START;
if( cmd_status == COMMAND_FAILED )
{
/* FAILED */
rEPaControl_BP.ForceSTALL = 0;
rEPbControl_BP.ForceSTALL = 0;
}
}
}
/*****************************************************************************
* ControlStatusStart
*****************************************************************************/
void ControlStatusStart(void)
{
rEP0IntStat = rEP0IntStat;
if( rEP0Control_BP.INxOUT )
{
/* (IN) */
rEP0Control_BP.INxOUT = 0;
rEP0ControlOUT_BP.ForceNAK = 0;
}
else
{
/* (OUT) */
if( usb_flag.Address )
{
/* Address */
usb_flag.Address = 0; /* Address */
rUSB_Address_BP.AutoSetAddress = 1; /* Auton Set Address */
}
rEP0Control_BP.INxOUT = 1;
rEP0ControlIN_BP.ForceNAK = 0;
rEP0ControlIN_BP.EnShortPkt = 1;
}
control_result = NO_RESULT;
control_state = CTRL_STS_END;
}
/*****************************************************************************
* ControlStatusEnd
*****************************************************************************/
void ControlStatusEnd(void)
{
int fifo_remain;
if( control_result == EP0_IN_ACK || control_result == EP0_OUT_ACK )
{
/* IN_TranACKOUT_TranACK */
control_result = NO_RESULT;
retry_cnt_0 = 0;
rCPU_JoinRd = 0x00;
fifo_remain = MKWORD(rEPnRdRemain_H, rEPnRdRemain_L);
if( fifo_remain != 0)
{
/* FIFOEmpty */
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}
else
{
if( usb_flag.TestMode )
{
/* TestMode */
usb_flag.TestMode = 0; /* TestMode */
TestModeProc(); /* TestMode */
}
}
control_state = CTRL_IDLE;
}
else
{
if( control_result == EP0_IN_ERR || control_result == EP0_OUT_ERR )
{
/* IN_TranErrOUT_TranErr */
control_result = NO_RESULT;
if( control_result == EP0_IN_ERR )
{
if( rEP0ControlIN_BP.ForceSTALL == 1 )
panic(9);
#ifdef DEBUG_PRINT
EP0INErrorCount++;
#endif
}
else
{
if( rEP0ControlOUT_BP.ForceSTALL == 1 )
panic(10);
#ifdef DEBUG_PRINT
EP0OUTErrorCount++;
#endif
}
}
else
{
if(usb_flag.USBReqRcvd)
{
/* SETUP */
control_state = CTRL_REQ_CHECK;
}
else
{
if( rEP0Control_BP.INxOUT )
{
if( rEP0IntStat_BP.OUT_TranNAK )
{
/* OutTranNAK */
retry_cnt_0 = 0;
rEP0Control_BP.INxOUT = 0;
if( req_tran_cnt != 0 && actual_tran_cnt == 0 )
{
/* Zero Length */
rEP0ControlOUT_BP.ForceNAK = 0;
control_state = CTRL_DATA_GET;
}
else
{
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}
}
}
else
{
/* OUT */
if( rEP0IntStat_BP.IN_TranNAK )
{
/* INTranNAK */
retry_cnt_0 = 0;
rEP0Control_BP.INxOUT = 1;
if( actual_tran_cnt )
{
rEP0ControlIN_BP.ForceSTALL = 1;
rEP0ControlOUT_BP.ForceSTALL = 1;
control_state = CTRL_IDLE;
}else{
/* Zero Length */
rEP0ControlIN_BP.ForceNAK = 0;
rEP0ControlIN_BP.EnShortPkt = 1;
control_state = CTRL_DATA_SEND;
}
}
}
}
}
}
}
/*****************************************************************************
* TestModeProc
*****************************************************************************/
void TestModeProc(void)
{
rMainIntEnb = 0x00;
rSIE_IntEnb = 0x00;
rEPrIntEnb = 0x00;
rDMA_IntEnb = 0x00;
rFIFO_IntEnb = 0x00;
if( rUSB_Test_BP.Test_J || rUSB_Test_BP.Test_K )
{
/* Test_J Test_k */
rXcvrControl_BP.OpMode = 0x02; /* Disable Bitstuffing and NRZI encoding) */
}
rUSB_Control_BP.EnAutoNego = 0; /* AutoNego */
rUSB_Control_BP.DisBusDetect = 1; /* */
rUSB_Test_BP.EnUSB_Test = 1; /* TestMode */
/* VBUS */
do
{
if( VBUSCheck() == 0 ) break;
}while( 1 );
/* VBUS TestModeOFFAttach */
rUSB_Test_BP.EnUSB_Test = 0; /* TestMode */
rXcvrControl_BP.OpMode = 0x01; /* Non Drive */
rXcvrControl_BP.RpuEnb = 0;
rUSB_Control_BP.ActiveUSB = 0; /* USB */
#ifdef DEBUG_PRINT
for (;;){
DebugProc();
}
#else
for (;;)
;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -