📄 usb_isr.c
字号:
if (ControlReg & rbSTSTL) // If last packet was a sent stall, reset
{ // STSTL bit and return EP0 to idle state
POLL_WRITE_BYTE(E0CSR, 0);
Ep_Status0 = EP_IDLE;
return;
}
if (ControlReg & rbSUEND) // SUEND bit is asserted after status stage by SIE
{ // or when SIE receives early SETUP
POLL_WRITE_BYTE(E0CSR, rbSSUEND); // Serviced Setup End bit and return to EP_IDLE
Ep_Status0 = EP_IDLE;
}
if (Ep_Status0 == EP_IDLE) // If Endpoint 0 is in idle mode
{
if (ControlReg & rbOPRDY) // Make sure that EP 0 has an Out Packet ready from host
{ // although if EP0 is idle, this should always be the case
// Fifo_Read(FIFO_EP0, 8, (BYTE *)&Setup);
// FIFO_Read_generic(FIFO_EP0, 8, (BYTE *)&Setup);
FIFO_Read_idata(FIFO_EP0, 8, (BYTE idata *)&Setup);
// FIFO_Read_pdata(FIFO_EP0, 8, (BYTE pdata *)&Setup);
// FIFO_Read_xdata(FIFO_EP0, 8, (BYTE xdata *)&Setup);
// Get Setup Packet off of Fifo
#if defined BIG_ENDIAN
// As the USB custom, multi-byte number is LSB first - little endian
Setup.wValue.i = ((UINT)Setup.wValue.c[1] << 8) | Setup.wValue.c[0];
Setup.wIndex.i = ((UINT)Setup.wIndex.c[1] << 8) | Setup.wIndex.c[0];
Setup.wLength.i = ((UINT)Setup.wLength.c[1] << 8) | Setup.wLength.c[0];
#endif // end of BIG_ENDIAN
setup_handled = FALSE;
USB_request_callback = NULL;
switch ( Setup.bmRequestType & DRT_MASK ) // Device Request Type
{
case DRT_STD: // Standard device request
Standard_Device_Request();
break;
case DRT_CLASS: // class specific request
Class_Request();
break;
/*
case DRT_VENDOR: // vendor request
Vendor_Request();
break;
*/
default:
break;
}
if ( setup_handled )
TempReg = rbSOPRDY; // Tell to SIE that the setup is handled
else {
TempReg = rbSDSTL; // Return STALL to the host
Ep_Status0 = EP_STALL; // Put the endpoint in stall status
}
send_eq_requested = (DataSize == Setup.wLength.i); // get this flag before DataSize
// is reduced in TX cycle
POLL_WRITE_BYTE(INDEX, 0); // Assure the indexed registers are accessed correctly
POLL_WRITE_BYTE(E0CSR, TempReg);
}
} // end of EP_IDLE
if ( Ep_Status0 == EP_TX ) // See if the endpoint has data to transmit to host
{
if ( !(ControlReg & rbINPRDY) ) // Make sure you don't overwrite last packet
{
POLL_READ_BYTE( E0CSR, ControlReg );
// Read control register
if ( (!(ControlReg & rbSUEND)) && (!(ControlReg & rbOPRDY)) )
// Check to see if Setup End or Out Packet received, if so
// do not put any new data on FIFO
{
TempReg = rbINPRDY; // Add In Packet ready flag to E0CSR bitmask
// Break Data into multiple packets if larger than Max Packet
if (DataSize >= EP0_PACKET_SIZE)
{ // The data size to send in this cycle is
// just EP0_PACKET_SIZE
// Fifo_Write( FIFO_EP0, EP0_PACKET_SIZE, (BYTE *)DataPtr );
FIFO_Write_generic( FIFO_EP0, EP0_PACKET_SIZE, (BYTE *)DataPtr );
DataPtr += EP0_PACKET_SIZE; // Advance data pointer
DataSize -= EP0_PACKET_SIZE; // Decrement data size
if ( send_eq_requested && (DataSize == 0) ) // In this case, no need to send ZLP,
{ // finish TX immediately
TempReg |= rbDATAEND;
Ep_Status0 = EP_IDLE;
}
} else { // The data size to send in this cycle is
// smaller than EP0_PACKET_SIZE or zero (ZLP)
// Fifo_Write( FIFO_EP0, (BYTE)DataSize, (BYTE *)DataPtr );
FIFO_Write_generic( FIFO_EP0, (BYTE)DataSize, (BYTE *)DataPtr );
TempReg |= rbDATAEND;
Ep_Status0 = EP_IDLE;
}
POLL_WRITE_BYTE(E0CSR, TempReg); // Write mask to E0CSR
}
}
} // end of EP_TX
if (Ep_Status0 == EP_RX) // See if endpoint should receive
{
BYTE dataCount;
POLL_READ_BYTE( E0CSR, ControlReg ); // Read control register
if ( ControlReg & rbOPRDY ) // Verify packet was received
{
TempReg = rbSOPRDY;
POLL_READ_BYTE( E0CNT, dataCount ); // get data bytes on the FIFO
// Fifo_Read( FIFO_EP0, dataCount, (BYTE*)DataPtr );
FIFO_Read_generic( FIFO_EP0, dataCount, (BYTE*)DataPtr );
// Empty the FIFO
// FIFO must be read out just the size it has,
// otherwize the FIFO pointer on the SIE goes out of synch.
DataPtr += dataCount; // Advance the pointer
if ( DataSize > dataCount ) // Update the scheduled number to be received
DataSize -= dataCount;
// Meet the end of the data stage
else {
if ( (DataSize == dataCount)
&& USB_request_callback
&& (*USB_request_callback)() )
{
TempReg |= rbDATAEND; // Signal end of data stage
Ep_Status0 = EP_IDLE; // Set Endpoint to IDLE
} else {
TempReg = rbSDSTL; // Signal STALL on the data stage
Ep_Status0 = EP_STALL; // Put the endpoint in stall status
}
}
POLL_WRITE_BYTE ( E0CSR, TempReg );
}
} // end of EP_RX
}
//-----------------------------------------------------------------------------
// Fifo_Read
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) BYTE addr : target address
// 2) BYTE uNumBytes : number of bytes to unload
// 3) BYTE * pData : read data destination
//
// Read from the selected endpoint FIFO
//
//-----------------------------------------------------------------------------
/*
void Fifo_Read(BYTE addr, BYTE uNumBytes, BYTE * pData)
{
BYTE idx;
while(USB0ADR & 0x80); // Wait for BUSY->'0'
USB0ADR = addr | 0xC0; // Set address
// Set auto-read and initiate first read
// Read <NumBytes> from the selected FIFO
for ( idx = 0; idx < uNumBytes; idx++ ) {
while(USB0ADR & 0x80); // Wait for BUSY->'0' (read complete)
pData[ idx ] = USB0DAT;
}
USB0ADR = 0; // Clear auto-read
}
*/
//-----------------------------------------------------------------------------
// Fifo_Write
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) BYTE addr : target address
// 2) BYTE uNumBytes : number of bytes to unload
// 3) BYTE * pData : location of source data
//
// Write to the selected endpoint FIFO
//
//-----------------------------------------------------------------------------
/*
void Fifo_Write(BYTE addr, BYTE uNumBytes, BYTE * pData)
{
BYTE idx;
while(USB0ADR & 0x80); // Wait for BUSY->'0'
USB0ADR = (addr & 0x3F); // Set address (mask out bits7-6)
// Write <NumBytes> to the selected FIFO
for ( idx = 0; idx < uNumBytes; idx++ ) {
while(USB0ADR & 0x80); // Wait for BUSY->'0' (write complete)
USB0DAT = pData[ idx ];
}
}
*/
//-----------------------------------------------------------------------------
// POLL_READ_BYTE, POLL_WRITE_BYTE
//-----------------------------------------------------------------------------
// When the macros are not defined, provide them as functions
//-----------------------------------------------------------------------------
#if defined( POLL_READ_BYTE_DEF )
BYTE POLL_READ_BYTE_FUNC( BYTE addr )
{
while( USB0ADR & 0x80 );
USB0ADR = (0x80 | addr);
while( USB0ADR & 0x80 );
return USB0DAT;
}
#endif
#if !defined( POLL_WRITE_BYTE )
void POLL_WRITE_BYTE( BYTE addr, BYTE dt )
{
while(USB0ADR & 0x80);
USB0ADR = addr;
USB0DAT = dt;
}
#endif
//-----------------------------------------------------------------------------
// Handle_Out1
//-----------------------------------------------------------------------------
// Handle out packet on Endpoint 1
//-----------------------------------------------------------------------------
#ifdef ENABLE_EP1_OUT_INTERRUPT
/*
static void Handle_Out1(void)
{
}
*/
#endif
//-----------------------------------------------------------------------------
// Handle_Out2
//-----------------------------------------------------------------------------
// Handle out packet on Endpoint 2
//-----------------------------------------------------------------------------
#ifdef ENABLE_EP2_OUT_INTERRUPT
/*
static void Handle_Out2(void)
{
}
*/
#endif
//-----------------------------------------------------------------------------
// Handle_Out3
//-----------------------------------------------------------------------------
// Handle out packet on Endpoint 3
//-----------------------------------------------------------------------------
#ifdef ENABLE_EP3_OUT_INTERRUPT
/*
static void Handle_Out3(void)
{
}
*/
#endif
//-----------------------------------------------------------------------------
// Handle_In1
//-----------------------------------------------------------------------------
// Handle in packet on Endpoint 1
//-----------------------------------------------------------------------------
#ifdef ENABLE_EP1_IN_INTERRUPT
/*
static void Handle_In1(void)
{
}
*/
#endif
//-----------------------------------------------------------------------------
// Handle_In2
//-----------------------------------------------------------------------------
// Handle in packet on Endpoint 2
//-----------------------------------------------------------------------------
#ifdef ENABLE_EP2_IN_INTERRUPT
/*
static void Handle_In2(void)
{
}
*/
#endif
//-----------------------------------------------------------------------------
// Handle_In3
//-----------------------------------------------------------------------------
// Handle in packet on Endpoint 3
//-----------------------------------------------------------------------------
#ifdef ENABLE_EP3_IN_INTERRUPT
/*
static void Handle_In3(void)
{
}
*/
#endif
//-----------------------------------------------------------------------------
// Handle_SOF
//-----------------------------------------------------------------------------
// Handle SOF interrupt
// SOF interrupt is evoked in 1 ms interval, when enabled
// When the device is connected to USB bus, this interrupt synchronizes to SOF
// When the device is not connected, the USB engine automatically generates the interval
//-----------------------------------------------------------------------------
#ifdef ENABLE_SOF_INTERRUPT
/*
static void Handle_SOF(void)
{
}
*/
#endif
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -