📄 usbisr.c
字号:
#include "InsUsb.h"
extern SYS_INFORMATION data sSysInformation;
extern unsigned char xdata mEp0OutBuffer[EP0_OUT_BUFFER_SIZE];
extern unsigned char data mEp1OutBuffer[EP1_OUT_BUFFER_SIZE]; //store led status
extern unsigned char xdata mRamBuffer[RAM_BUFFER_SIZE];
extern void D12AcknowledgeSetup(void);
extern unsigned char D12ReadInterruptRegister(void);
extern unsigned char D12ReadLastTransactionStatus(unsigned char bEndpointIndex);
extern unsigned char D12ReadBuffer(unsigned char bEndpointIndex, unsigned int bExpectedLength,unsigned char * pBuffer);
extern void D12WriteBuffer(unsigned char bEndpointIndex,unsigned char bLength, unsigned char * pBuffer);
extern void D12SetEndpointStatus(unsigned char bEndpointIndex, unsigned char bStalled);
//
//*************************************************************************//
// Paremeter:
// In : None
// Out: None
// Function:
// USB standard request and vendor/class request is impleemnted by control
// transfer.Every control transfer contains three stage: setup stage,data
// stage(optional) and status stage.At setup stage,we will receive a setup packet,
// it must be 8 byte and the meaning of setup packet please reference USB
// specification.
// For control-in transfer,there must has a data stage.At this stage,we must
// write data to PDIUSBD12 endpoint0-in buffer,and when received IN token,
// those data will be transmit to host by PDIUSBD12 automatically.At last when
// we received an OUT token from host,control-in transfer complete.
// For control-out transfer,there may be has a data stage or no.If it has no data
// stage,we can simply set device or interface or endpoint status according request,
// but if it has a data stage,we must receive those data,and deal with them.
// At last,if we receive a IN token,return zero length to host and control-out
// transfer complete.
void Ep0Out(void) //Control OUT transaction process
{
unsigned char data bLastTransactionStatus;
unsigned char data bDataLength;
unsigned char xdata * data pBuffer ;
//after ReadLastTransactionStatus,
//D12 will clear corresponding interrupt register flag bit automatically
bLastTransactionStatus = D12ReadLastTransactionStatus(D12_READ_LAST_TRANSACTION_STATUS_CONTROL_OUT);
#ifndef _INT_MODE_
#ifdef _Debug_
printf("Ep0Out last status is 0x%x\n",(unsigned int)(bLastTransactionStatus));
#endif
#endif
if (bLastTransactionStatus & D12_SETUP_PACKET_MASK) //if received a setup packet
{
//read buffer,save SETUP data to sSysInformation.sUsbDeviceRequest
bDataLength = D12ReadBuffer(D12_SELECT_ENDPOINT_CONTROL_OUT, USB_SETUP_PACKET_LENGTH,&sSysInformation.sUsbDeviceRequest.bmRequestType);
sSysInformation.sUsbDeviceRequest.wValue = WORD_SWAP(sSysInformation.sUsbDeviceRequest.wValue);
sSysInformation.sUsbDeviceRequest.wIndex = WORD_SWAP(sSysInformation.sUsbDeviceRequest.wIndex);
sSysInformation.sUsbDeviceRequest.wLength = WORD_SWAP(sSysInformation.sUsbDeviceRequest.wLength);
sSysInformation.sUsbSetUpDealwith.wRemaindLength = sSysInformation.sUsbDeviceRequest.wLength;
D12AcknowledgeSetup(); // Acknowledge setup
sSysInformation.bSetup = TRUE; //after received a setup packet,set flag
//if it is a control-in transfer
if (sSysInformation.sUsbDeviceRequest.bmRequestType & USB_ENDPOINT_DIRECTION_MASK)
sSysInformation.bUsbStatus = TRANSMIT;
//else it is control-out
else
{
//Interface Studio USB1.1 develop board support control-out transfer with data
//stage.This firmware will save data to mEp0OutBuffer,which size is 128 byte,
//and user should assure data length of control-out transfer no more than it,else
//firmware will stall endpoint0.The meaning of received data should be interpreted by
//user,as a demo,firmware demenstrate how to deal with SetDeviceSerialNumber request,
//which is a vendor defined request;other control-out transfer will be resvered for
//user to determine how to deal with them.
if (sSysInformation.sUsbDeviceRequest.wLength > EP0_OUT_BUFFER_SIZE)
{
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
//For contro-out transfer,it may be has data stage or no data stage.
//Whichever we should return status stage only after we had completed the required
//operation.So we set bControOutCommandIsPending and bControlOutDataComplete flags
// to help we judge whether the data is received.
else
{
sSysInformation.bUsbStatus = RECEIVE;
sSysInformation.sUsbSetUpDealwith.bControlOutDataComplete = FALSE;
sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending = TRUE;
}
}
}
//if endpoint0-out received a packet which is not a setup packet
else
{
if (sSysInformation.bUsbStatus == RECEIVE)
{
if (sSysInformation.sUsbSetUpDealwith.wRemaindLength>0)
{
pBuffer = &mEp0OutBuffer + \
(sSysInformation.sUsbDeviceRequest.wLength-sSysInformation.sUsbSetUpDealwith.wRemaindLength);
bDataLength = D12ReadBuffer(D12_SELECT_ENDPOINT_CONTROL_OUT,sSysInformation.sUsbSetUpDealwith.wRemaindLength, pBuffer);
if (bDataLength == D12_BUFFER_LENGTH_ERROR)
{
//D12_BUFFER_LENGTH_ERROR shows received data length is longer than expected length,
//this is a serious error,so we stall control endpoint
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
else
{
//get remaind data length
sSysInformation.sUsbSetUpDealwith.wRemaindLength -= bDataLength;
//if remaind data length is 0, current data stage of control-out transfer
//will be finished.
if (sSysInformation.sUsbSetUpDealwith.wRemaindLength<=0)
{
sSysInformation.sUsbSetUpDealwith.bControlOutDataComplete = TRUE;
}
}
}
else //unexpected out packet,we should stall control endpoint
{
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
}
else if (sSysInformation.bUsbStatus == TRANSMIT)
{
//If remaind data length is zero and current status is TRANSMIT,
//it shows data stage of control-in transfer will be finished
//For control-in transfer,Host will send a zero length out packet to device
//as status stage which flags control-in transfer is finished.see 8.5.2.1
if (sSysInformation.sUsbSetUpDealwith.wRemaindLength<=0)
{
sSysInformation.bUsbStatus = IDLE;
}
else
{
//this is an unexpected OUT packet,so we should stall endpoint0
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
}
else //if IDLE state
{
//this is an unexpected OUT packet,so we should stall endpoint0
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
}
}
//
//*************************************************************************
// Paremeter:
// In : None
// Out: None
// Function:
// All control-in transfer has a data stage.This function will check whether
// there are remaind data should transfer to host.
// Anaother case is,a control-out transfer expect a IN token as status stage
// to complete this transfer.
void Ep0In(void)
{
unsigned char data bLastTransactionStatus;
unsigned char data bDataLength;
unsigned char data i;
bLastTransactionStatus = D12ReadLastTransactionStatus(D12_READ_LAST_TRANSACTION_STATUS_CONTROL_IN); // Clear interrupt flag
#ifndef _INT_MODE_
#ifdef _Debug_
printf("Ep0In last status is 0x%x\n",(unsigned int)(bLastTransactionStatus));
#endif
#endif
//for a control-out transfer,a IN token flags this transfer is finished.
if ((sSysInformation.bUsbStatus == RECEIVE) && \
(!sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending))
{
sSysInformation.bUsbStatus = IDLE;
}
//else if a previous control-in transfer has not completed yet
else if (sSysInformation.bUsbStatus == TRANSMIT)
{
if (sSysInformation.sUsbSetUpDealwith.wRemaindLength >= D12_EP0_MAX_PACKET_SIZE)
bDataLength = D12_EP0_MAX_PACKET_SIZE;
else
{
bDataLength = sSysInformation.sUsbSetUpDealwith.wRemaindLength;
}
if (bDataLength >0)
{
D12_COMMAND_ADDRESS = D12_SELECT_ENDPOINT_CONTROL_IN; //select endpoint,the optional read one byte is not read
D12_COMMAND_ADDRESS = D12_WRITE_BUFFER_SELECTED_ENDPOINT; //write endpoint buffer
D12_DATA_ADDRESS = 0; //first byte is reserved,should wirte 0x00
D12_DATA_ADDRESS = bDataLength; //the second byte is the data length that will be write to buffer
#ifndef _INT_MODE_
#ifdef _Debug_
printf("Write buffer:");
#endif
#endif
for(i=0; i<bDataLength; i++)
{
D12_DATA_ADDRESS = *sSysInformation.sUsbSetUpDealwith.pDataSourceAddress;
#ifndef _INT_MODE_
#ifdef _Debug_
printf("%x,",(unsigned int)(*sSysInformation.sUsbSetUpDealwith.pDataSourceAddress));
#endif
#endif
sSysInformation.sUsbSetUpDealwith.pDataSourceAddress++;
}
#ifndef _INT_MODE_
#ifdef _Debug_
printf("\n");
#endif
#endif
D12_COMMAND_ADDRESS = D12_VALIDATE_BUFFER_SELECTED_ENDPOINT; //validate buffer
sSysInformation.sUsbSetUpDealwith.wRemaindLength -= bDataLength;
}
}
else
{
//this is an unexpected IN packet,so we should stall endpoint0
CONTROL_ENDPOINT_STALL //set control endpoint stall
}
}
//
//*************************************************************************
// Paremeter:
// In : None
// Out: None
// Function:
// This firmware use endpoint1-ou as a interrupt endpoint to control
// eight LED status.When data received,we save it to mEp1OutBuffer,
// and interpret it as LED status.Note we refresh LED status in main
// program loop.
void Ep1Out(void) //endpoint1 OUT transaction process
{
unsigned char data bLastTransactionStatus;
unsigned char bDataLength;
bLastTransactionStatus = D12ReadLastTransactionStatus(D12_READ_LAST_TRANSACTION_STATUS_ENDPOINT1_OUT);
bDataLength = D12ReadBuffer(D12_SELECT_ENDPOINT_ENDPOINT1_OUT, EP1_OUT_BUFFER_SIZE,&mEp1OutBuffer);
}
//
//*************************************************************************
// Paremeter:
// In : None
// Out: None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -