📄 fw_epmg.c
字号:
}
else
{
// Data or Status phase
if(fw_controlData.state == FW_STATE_START)
{
if( AT91F_UDP_EpStatus( USBDEV_BASE_UDP, FW_EP_CTRL ) & USBDEV_UDP_TXCOMP ) // Data sent to host
{
// Send the next packet
_i = fw_writeEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount,
min(FW_EP0_MAXPACKET_SIZE,(fw_controlData.wLength - fw_controlData.wCount)));
if((_i == 0) && (fw_controlData.wLength - fw_controlData.wCount != 0))
{
}
else
{
if((fw_controlData.wLength - fw_controlData.wCount) < FW_EP0_MAXPACKET_SIZE) /* No more Data to transmit */
{
fw_controlData.state = FW_STATE_END;
fw_controlData.pData = NULL;
}
fw_controlData.wCount += _i;
}
}
if( AT91F_UDP_EpStatus( USBDEV_BASE_UDP, FW_EP_CTRL ) & USBDEV_UDP_RX_DATA_BK0 ) // Data received
{
USHORT _Read = 0;
/* if the size of the transfer is longer than the max packet */
if( _i >= FW_EP0_MAXPACKET_SIZE)
{
_Read = fw_readEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount);
if (_Read == 0)
{
// End of SetupPhase
goto EOSP;
}
fw_controlData.wCount += FW_EP0_MAXPACKET_SIZE;
}
/* last read */
else
{
if( _i != 0)
{
_Read=fw_readEndpoint(FW_EP_CTRL, fw_controlData.pData + fw_controlData.wCount);
if (_Read == 0)
{
// End of SetupPhase
goto EOSP;
}
fw_controlData.wCount += _i;
EOSP: fw_controlData.wLength = 0;
fw_controlData.wCount = 0;
fw_controlData.state = FW_STATE_END;
fw_controlData.pData = NULL;
}
}
}
}
else // received a OUT status phase
{
if( AT91F_UDP_EpStatus( USBDEV_BASE_UDP, FW_EP_CTRL ) & USBDEV_UDP_RX_DATA_BK0 )
{
if (fw_readEndpoint(FW_EP_CTRL,_buff)==0)
{
// receive a NULL packet, Status Phase
}
}
}
}
}
/*****************************************************************
*
* ROUTINE fw_mainRxDone
*
*-----------------------------------------------------------------
*
* Purpose :
* when something is received on main EP, put the data in the TBs
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_TB : array of the buffer IDs
* fw_writeTB : TB currently used by the firmware
*
*****************************************************************/
void fw_mainRxDone(void)
{
ULONG _len = 0;
structTB *_TB,**_nextTB;
_nextTB = fw_writeTB + 1;
if(_nextTB > (fw_TB + (FW_TB_NUM - 1)))
{
_nextTB = fw_TB;
}
/* Check if two TB are marked not valid to overwrite data */
if(!(fw_writeTB[0][0].status & FW_VBIT) && !(_nextTB[0][0].status & FW_VBIT))
{
/* Read the bytes received */
_len = fw_readEndpoint(FW_EP_BULK_OUT, databuffer);
_TB = fw_writeTB[0];
/* Check if we effectively received data */
if(_len != 0)
{
_len = fw_writeRxData(_len,databuffer);
}
else
{
if(_TB->length == 0)
{
/* If the len received is 0 and the TB is empty get out of the function,
not to fill an empty TB */
return;
}
}
}
/* if we must use the TB pool and it's full */
else
{
/* Some data have been received and we can't write */
/* So set a flag to retry the reception later */
fw_deviceState |= FW_DS_TB_FULL | FW_DS_RX;
TRACE_ERROR( "TB FULL\n\r");
}
/* Check if two TB are marked valid */
if((fw_writeTB[0][0].status & FW_VBIT) || (_nextTB[0][0].status & FW_VBIT))
{
/* disable interrupt if we can't receive next time */
AT91F_UDP_DisableIt( USBDEV_BASE_UDP, AT91C_UDP_EPINT2 ); // EP_BULK_OUT
/* some data have been received and we can't write */
/* So set a flag to retry the reception later */
fw_deviceState |= FW_DS_RX;
}
else
{
/* enable interrupt we can receive next time */
AT91F_UDP_EnableIt( USBDEV_BASE_UDP, AT91C_UDP_EPINT2 ); // EP_BULK_OUT
}
}
/*****************************************************************
*
* ROUTINE fw_mainTxDone
*
*-----------------------------------------------------------------
*
* Purpose :
* called when something is transmitted by main EP,
* pick data in the IN FIFO and transmit it
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_fifoId : ID of the IN FIFO
* fw_deviceState : bit1 = 1 when TX on EP2
*
*****************************************************************/
void fw_mainTxDone(void)
{
UCHAR i;
if(fw_fifoId.NbOctetsLibres != (fw_fifoId.last - fw_fifoId.first))
{
for( i=0; i<FW_MAIN_EP_MAXPACKET_SIZE; i++ )
{
TxBuffer[i] = 0;
}
// Get the data out of the fifo and put them in the endpoint buffer
fw_lastTxPacket = po_rngBufGet(&fw_fifoId,(char*)TxBuffer,FW_MAIN_EP_MAXPACKET_SIZE);
fw_lastTxPacket = fw_writeEndpoint(FW_EP_BULK_IN,TxBuffer,fw_lastTxPacket);
// Test if the FIFO is only 20% full
if( (fw_deviceState & FW_DS_FIFO_FULL) && (po_rngNBytes(&fw_fifoId) < FW_IN_FIFO_EMPTY) )
{
fw_deviceState &= ~FW_DS_FIFO_FULL;
}
}
else
{
// End of the transfer
fw_deviceState &= ~FW_DS_TX;
USB_TX = 1;
/* if the last packet is a full packet we must send a zero length packet */
// TODO
//if(fw_fifoId.NbOctetsLibres == 0)
//{
// fw_singleTransmit(0, 0);
//}
}
}
/*****************************************************************
*
* ROUTINE fw_writeRxData
*
*-----------------------------------------------------------------
*
* Purpose :
* write data in a valid TB
*
* Input parameters : length : length of data to write
* dataBuffer : data to write
*
* Output parameters : NONE
*
* Global data : fw_TB : array of the buffer IDs
* fw_writeTB : TB currently used by the firmware
*
*****************************************************************/
int fw_writeRxData(int length,UCHAR *dataBuffer)
{
structTB *_TB;
ULONG _i = 0;
long *_sizeTB,*_indexTB;
_TB = fw_writeTB[0];
_indexTB =&_TB->index; /* pointer to the current write position */
_sizeTB = &_TB->length; /* pointer to the size field */
/* check if the current TB was Empty */
if(_TB->status & FW_EBIT)
{
_TB->status &= ~FW_EBIT;
}
/* if the TB isn't large enough pass to the next TB */
if(length > (FW_TB_SIZE - *_sizeTB) )
{
fw_writeTB++;
if(fw_writeTB > (fw_TB + (FW_TB_NUM - 1)))
{
fw_writeTB = fw_TB;
}
/* fill the current TB */
_i = FW_TB_SIZE - (*_sizeTB);
po_memcpy(&_TB->data[(*_indexTB)],dataBuffer,_i);
*_sizeTB = FW_TB_SIZE;
*_indexTB = 0;
/* validate the TB */
_TB->status |= FW_VBIT;
USB_RX++;
/* put the other data in the next TB */
_TB = fw_writeTB[0];
_indexTB = &_TB->index;
_sizeTB = &_TB->length;
if(!(_TB->status & FW_VBIT))
{
fw_writeTB++;
if(fw_writeTB > (fw_TB + (FW_TB_NUM - 1)))
{
fw_writeTB = fw_TB;
}
po_memcpy(&_TB->data[(*_indexTB)],(char*)(dataBuffer + _i),(length - _i));
*_sizeTB = (length - _i);
*_indexTB = 0;
_TB->status |= FW_VBIT;
USB_RX++;
/* call the driver to update the actual data in the valid TBs
* TB is full */
}
else
{
/* we lose data */
length = _i;
}
/* check if the current TB was Empty */
if(_TB->status & FW_EBIT)
{
_TB->status &= ~FW_EBIT;
}
}
else
{
fw_writeTB++;
if(fw_writeTB > (fw_TB + (FW_TB_NUM - 1)))
{
fw_writeTB = fw_TB;
}
po_memcpy(&_TB->data[*_indexTB],(char*)dataBuffer,length);
*_sizeTB = length;
*_indexTB = 0;
_TB->status |= FW_VBIT;
USB_RX++;
}
return length;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -