📄 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"
#include "u_com_fp.h"
#include "u_usb_fp.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
* Control
* :
* :
* : control_state Control
*
*****************************************************************************/
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]();
}
/*****************************************************************************
*
* :
*
* :
* :
* : usb_flag USB
* control_state Control
* req_tran_cnt
*
*****************************************************************************/
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 */
/* */
if(rEP0SETUP_0 & 0x80){
rEP0Control_BP.INxOUT = 1;
}else{
rEP0Control_BP.INxOUT = 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;
}
}
/*****************************************************************************
*
* :
* : FIFO
* :
* :
* : actual_tran_cnt
* tran_start_addr
* control_state Control
* control_result Control
*
*****************************************************************************/
void ControlDataSet(void)
{
int i;
if( usb_flag.ReplyDescriptor ){
/* Descriptor */
usb_flag.ReplyDescriptor = 0; /* Descriptor */
rEP0IntEnb_BP.EnIN_TranACK = 0; /* IN_TranACK */
/* Descriptor */
rDescAdrs_H = DWORD2BYTE_LH((DWORD)tran_start_addr);
rDescAdrs_L = DWORD2BYTE_LL((DWORD)tran_start_addr);
/* Descriptor */
rDescSize_H = WORD2BYTE_H(actual_tran_cnt);
rDescSize_L = WORD2BYTE_L(actual_tran_cnt);
rEP0Control_BP.ReplyDescriptor = 1;
}else{
/* Descriptor */
if( actual_tran_cnt >= max_pkt_size_0 ){
/* MaxPacketSize */
/*
* MaxPacketSizeFIFO
* MaxPacketSize
* maxPacketSize
*/
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{
/* MaxPacketSize */
/*
* FIFO
*
*/
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;
}
/*****************************************************************************
*
* :
* : Control
* :
* :
* : control_result Control
* retry_cnt
* control_state Control
* actual_tran_cnt
* req_tran_cnt
* total_tran_cnt
* ep0_int_stat EP0
*
*****************************************************************************/
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) ){
/* MaxPacketSize */
control_state = CTRL_STS_START;
}else{
/* MaxPacketSize */
rEP0ControlIN_BP.EnShortPkt = 1;
}
}
}
}else{
if( control_result == EP0_IN_ERR ){
/* IN_TranErr */
control_result = NO_RESULT;
if( rEP0ControlIN_BP.ForceSTALL == 1 ){
/* ForceSTALL */
panic(7);
}
#ifdef DEBUG_PRINT
EP0INErrorCount++;
#endif
}else{
if( control_result == DESCRIPTOR_CMP ){
/* Descriptor */
/* */
actual_tran_cnt = MKWORD(rDescSize_H, rDescSize_L);
retry_cnt_0 = 0;
rEPnControl_BP.EP0FIFO_Clr = 1;
if( actual_tran_cnt == req_tran_cnt ){
/* 1OUT_TranNAK */
/* */
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; /* OUT_TranNAK */
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;
}
}
}
}
}
}
}
/*****************************************************************************
*
* :
* : Control
* :
* :
* : control_result Control
* retry_cnt
* control_state Control
* actual_tran_cnt
* ep0_int_stat EP0
*
*****************************************************************************/
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 ){
/* ForceSTALL */
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; /* IN_TranNAK */
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;
}
}
}
}
}
}
/*****************************************************************************
*
* :
* : FIFO
* :
* :
* : actual_tran_cnt
* total_tran_cnt
* tran_start_addr
* control_state Control
*
*****************************************************************************/
void ControlDataGet(void)
{
int i;
WORD fifo_remain;
control_result = NO_RESULT;
rCPU_JoinRd = 0x00;
fifo_remain = MKWORD(rEPnRdRemain_H, rEPnRdRemain_L);
if( fifo_remain == 0 ){
/* FIFOEmpty */
if( actual_tran_cnt ){
/* */
if( total_tran_cnt == actual_tran_cnt ){
/* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -