📄 fw_epmg.c
字号:
// ----------------------------------------------------------------------------
// ATMEL Microcontroller Software Support - ROUSSET -
// ----------------------------------------------------------------------------
// DISCLAIMER: CONDITIONS AS PER SIGNED LIMITED LICENSE AGREEMENT (AT91
// SOFTWARE AND USER DOCUMENTATION)
// ALL SOFTWARE IS PROVIDED AS IS, WITH ALL FAULTS, AND WITH NO WARRANTY
// WHATSOEVER. ATMEL EXPRESSLY DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED,
// OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.
// ----------------------------------------------------------------------------
// File Name : fw_epmg.c
// Object : EP management routines
// Creation : JCB 27/oct/2002
// Modif : JCB 18/feb/2005
// JCB 18/mar/2005 change the EP0 manage to suit
// with the first Get dev descript
// ----------------------------------------------------------------------------
#include "po_types.h"
#include "trace.h"
#include "fw_usb.h"
#include "po_kernel.h"
#include "ms_device.h"
#include "ms_rbc.h"
/*************************************************************************
USB protocol function pointer arrays
*************************************************************************/
/* Table 9-4. Standard Request Codes */
typedef void (*S_request) (void);
const S_request StandardDeviceRequest[] =
{
fw_getStatus, /* 0 */
fw_clearFeature, /* 1 */
fw_reserved, /* 2 */
fw_setFeature, /* 3 */
fw_reserved, /* 4 */
fw_setAddress, /* 5 */
fw_getDescriptor, /* 6 */
fw_reserved, /* 7 set_descriptor is not supported */
fw_getConfiguration, /* 8 */
fw_setConfiguration, /* 9 */
fw_getInterface, /* 10 */
fw_setInterface, /* 11 */
fw_reserved /* 12 synch_frame is not supported */
};
static UCHAR databuffer[2*FW_MAIN_EP_MAXPACKET_SIZE];
UCHAR TxBuffer[FW_MAIN_EP_MAXPACKET_SIZE];
/*****************************************************************
*
* ROUTINE fw_ep0RxDone
*
*-----------------------------------------------------------------
*
* Purpose :
* called when something is received on EP0
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_controlData : request to be processed
*
*****************************************************************/
void fw_ep0RxDone(void)
{
UCHAR _i = 0;
if(fw_IsSetupPacket(FW_EP_CTRL) != 0)
{
fw_controlData.wLength = 0;
fw_controlData.wCount = 0;
_i = fw_readEndpoint(FW_EP_CTRL,(UCHAR *)(&(fw_controlData.DeviceRequest)));
/* if the data are not valid */
if(_i != sizeof(FW_DEVICE_REQUEST))
{
fw_stallEp0();
return;
}
/* Acknowledge setup here to unlock in/out endp */
if(fw_controlData.DeviceRequest.bmRequestType & 0x80)
{
fw_changedir(FW_DEVICE_TO_HOST);
}
else
{
fw_changedir(FW_HOST_TO_DEVICE);
}
fw_acknowledgeSetup(FW_EP_CTRL);
fw_controlData.wLength = fw_controlData.DeviceRequest.wLength;
fw_controlData.wCount = 0;
fw_controlData.state = FW_STATE_START;
fw_deviceState |= FW_DS_SETUP;
}
else
{
if(fw_controlData.state == FW_STATE_START)
{
_i = fw_readEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount);
fw_controlData.wCount += _i;
if((_i != 0)
&& ((_i != FW_EP0_MAXPACKET_SIZE) || (fw_controlData.wCount >= fw_controlData.wLength)))
{
fw_writeEndpoint(FW_EP_BULK_IN, 0, 0); /* Send zero packet at the end */
fw_controlData.state = FW_STATE_END;
}
}
else
{
fw_controlData.state = FW_STATE_END;
}
}
}
/*****************************************************************
*
* ROUTINE fw_processCommand
*
*-----------------------------------------------------------------
*
* Purpose :
* called by the task when a setup packet is received
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_controlData : request to be processed
*
*****************************************************************/
void fw_processCommand(void)
{
UCHAR _type, _req;
if(fw_controlData.DeviceRequest.bmRequestType & 0x80)
{
fw_changedir(FW_DEVICE_TO_HOST);
}
else
{
fw_changedir(FW_HOST_TO_DEVICE);
}
_type = fw_controlData.DeviceRequest.bmRequestType & FW_USB_REQUEST_TYPE_MASK;
/* take only the first four bits of the request */
_req = fw_controlData.DeviceRequest.bRequest & FW_USB_REQUEST_MASK;
/* process the rigth command */
if (_type == FW_USB_STANDARD_REQUEST)
{
TRACE_DEBUG_L( "DeviceRequest:%d\n\r", _req );
(*StandardDeviceRequest[_req])();
/* fw_getStatus, fw_clearFeature, fw_reserved, fw_setFeature, */
/* fw_reserved, fw_setAddress, fw_getDescriptor, fw_reserved, */
/* fw_getConfiguration, fw_setConfiguration, fw_getInterface, */
/* fw_setInterface, fw_reserved */
}
else
{
if (_type == FW_USB_CLASS_REQUEST)
{
UCHAR _pBuff;
UCHAR _dataSize;
/* !!!! point entree driver: ms_classRequest */
if( USBMS_OK == ms_classRequest( fw_controlData.DeviceRequest, &_pBuff, &_dataSize ) )
{
if( _dataSize != 0 )
{
/* we suppose that answer is always shorter than 1 packet */
fw_singleTransmit( &_pBuff, _dataSize );
}
else
{
fw_singleTransmit(0,0);
}
}
else
{
fw_controlData.state = FW_STATE_END;
fw_stallEp0();
}
}
else
{
fw_controlData.state = FW_STATE_END;
fw_stallEp0();
}
}
}
/*****************************************************************
*
* ROUTINE fw_ep0TxDone
*
*-----------------------------------------------------------------
*
* Purpose :
* called when something is transmitted by EP0
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_controlData : request to be processed
*
*****************************************************************/
void fw_ep0TxDone(void)
{
USHORT _i = fw_controlData.wLength - fw_controlData.wCount;
/* if the command is not finish */
if( fw_controlData.state != FW_STATE_END)
{
/* if the size of the transfer is longer than the max packet */
if( _i >= FW_EP0_MAXPACKET_SIZE)
{
fw_writeEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount, FW_EP0_MAXPACKET_SIZE);
fw_controlData.wCount += FW_EP0_MAXPACKET_SIZE;
}
/* else if there are something to send */
else
{
if( _i != 0)
{
fw_writeEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount, _i);
fw_controlData.wCount += _i;
fw_controlData.state = FW_STATE_END;
fw_controlData.pData = NULL;
}
else
{
fw_writeEndpoint(FW_EP_CTRL, 0, 0); /* Send zero packet at the end */
fw_controlData.state = FW_STATE_END;
fw_controlData.pData = NULL;
}
}
}
}
/*****************************************************************
*
* ROUTINE fw_ep0RxTxDone
*
*-----------------------------------------------------------------
*
* Purpose :
* called when something must be handled on EP0
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_controlData : request to be processed
*
*****************************************************************/
void fw_ep0RxTxDone(void)
{
USHORT _i = fw_controlData.wLength - fw_controlData.wCount;
UCHAR _buff[8];
if(fw_IsSetupPacket(FW_EP_CTRL) != 0)
{
fw_controlData.wLength = 0;
fw_controlData.wCount = 0;
_i = fw_readEndpoint(FW_EP_CTRL,(UCHAR *)(&(fw_controlData.DeviceRequest)));
// if the data are not valid
if(_i == 0)
{
_i = fw_readEndpoint(FW_EP_CTRL,(UCHAR *)(&(fw_controlData.DeviceRequest)));
}
if(_i != sizeof(FW_DEVICE_REQUEST))
{
fw_acknowledgeSetup(FW_EP_CTRL);
return;
}
/* Acknowledge setup here to unlock in/out endp */
if(fw_controlData.DeviceRequest.bmRequestType & 0x80)
{
fw_changedir(FW_DEVICE_TO_HOST);
}
else
{
fw_changedir(FW_HOST_TO_DEVICE);
}
fw_acknowledgeSetup(FW_EP_CTRL);
fw_controlData.wLength = fw_controlData.DeviceRequest.wLength;
fw_controlData.wCount = 0;
fw_controlData.state = FW_STATE_START;
fw_deviceState |= FW_DS_SETUP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -