📄 f32x_usb_isr.c
字号:
void BulkOrInterruptOut(PEP_STATUS pEpOutStatus)
{
UINT uBytes;
BYTE bTemp = 0;
BYTE bCsrL, bCsrH;
UWRITE_BYTE(INDEX, pEpOutStatus->bEp); // Index to current endpoint
UREAD_BYTE(EOUTCSRL, bCsrL);
UREAD_BYTE(EOUTCSRH, bCsrH);
// Make sure this endpoint is not halted
if (pEpOutStatus->bEpState != EP_HALTED)
{
// Handle STALL condition sent
if (bCsrL & rbOutSTSTL)
{
// Clear Send Stall, Sent Stall, and data toggle
UWRITE_BYTE(EOUTCSRL, rbOutCLRDT);
}
// Read received packet
if(bCsrL & rbOutOPRDY)
{
// Get packet length
UREAD_BYTE(EOUTCNTL, bTemp); // Low byte
uBytes = (UINT)bTemp & 0x00FF;
UREAD_BYTE(EOUTCNTH, bTemp); // High byte
uBytes |= (UINT)bTemp << 8;
if (M_State == ST_IDLE_DEV)
{
FIFORead(0x02, uBytes, &Buffer);
}
else
{
FIFORead(0x02, uBytes, (BYTE*)(&TempStorage[BlockIndex]));
}
// Clear out-packet-ready
UWRITE_BYTE(INDEX, pEpOutStatus->bEp);
UWRITE_BYTE(EOUTCSRL, 0);
}
}
}
//-----------------------------------------------------------------------------
// BulkOrInterruptIn
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) PEP_STATUS pEpOutStatus
// 2) BYTE * DataToWrite
// 3) UINT NumBytes
//
// - Places DataToWrite on the IN FIFO
// - Sets Packet Ready Bit
//-----------------------------------------------------------------------------
void BulkOrInterruptIn (PEP_STATUS pEpInStatus, BYTE * DataToWrite,
UINT NumBytes)
{
BYTE bCsrL, bCsrH;
UWRITE_BYTE(INDEX, pEpInStatus->bEp); // Index to current endpoint
UREAD_BYTE(EINCSRL, bCsrL);
UREAD_BYTE(EINCSRH, bCsrH);
// Make sure this endpoint is not halted
if (pEpInStatus->bEpState != EP_HALTED)
{
// Handle STALL condition sent
if (bCsrL & rbInSTSTL)
{
UWRITE_BYTE(EINCSRL, rbInCLRDT); // Clear Send Stall and Sent Stall,
// and clear data toggle
}
// If a FIFO slot is open, write a new packet to the IN FIFO
if (!(bCsrL & rbInINPRDY))
{
pEpInStatus->uNumBytes = NumBytes;
pEpInStatus->pData = (BYTE*)DataToWrite;
// Write <uNumBytes> bytes to the <bEp> FIFO
FIFOWrite(pEpInStatus->bEp, pEpInStatus->uNumBytes,
(BYTE*)pEpInStatus->pData);
BytesToWrite -= NumBytes;
ReadIndex += NumBytes;
BlocksWrote++;
// Set Packet Ready bit (INPRDY)
UWRITE_BYTE(EINCSRL, rbInINPRDY);
// Check updated endopint status
//UREAD_BYTE(EINCSRL, bCsrL);
}
}
}
//-----------------------------------------------------------------------------
// USBReset
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// - Initialize the global Device Status structure (all zeros)
// - Resets all endpoints
//-----------------------------------------------------------------------------
void USBReset ()
{
BYTE i, bPower = 0;
BYTE * pDevStatus;
// Reset device status structure to all zeros (undefined)
pDevStatus = (BYTE *)&gDeviceStatus;
for (i=0;i<sizeof(DEVICE_STATUS);i++)
{
*pDevStatus++ = 0x00;
}
// Set device state to default
gDeviceStatus.bDevState = DEV_DEFAULT;
// REMOTE_WAKEUP_SUPPORT and SELF_POWERED_SUPPORT
// defined in file "usb_desc.h"
gDeviceStatus.bRemoteWakeupSupport = REMOTE_WAKEUP_SUPPORT;
gDeviceStatus.bSelfPoweredStatus = SELF_POWERED_SUPPORT;
// Reset all endpoints
// Reset Endpoint0
gEp0Status.bEpState = EP_IDLE; // Reset Endpoint0 state
gEp0Status.bEp = 0; // Set endpoint number
gEp0Status.uMaxP = EP0_MAXP; // Set maximum packet size
// Reset Endpoint1 IN
gEp1InStatus.bEpState = EP_HALTED; // Reset state
gEp1InStatus.uNumBytes = 0; // Reset byte counter
// Reset Endpoint2 OUT
gEp2OutStatus.bEpState = EP_HALTED; // Reset state
gEp2OutStatus.uNumBytes = 0; // Reset byte counter
// Get Suspend enable/disable status. If enabled, prepare temporary
// variable bPower.
if (SUSPEND_ENABLE)
{
bPower = 0x01; // Set bit0 (Suspend Enable)
}
// Get ISO Update enable/disable status. If enabled, prepare temporary
// variable bPower.
if (ISO_UPDATE_ENABLE)
{
bPower |= 0x80; // Set bit7 (ISO Update Enable)
}
UWRITE_BYTE(POWER, bPower);
}
//-----------------------------------------------------------------------------
// Page_Erase
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) BYTE* Page_Address
//
// Erases the page of FLASH located at Page_Address
//-----------------------------------------------------------------------------
void Page_Erase (BYTE* Page_Address) small
{
BYTE EA_Save; // Used to save state of global
// interrupt enable
BYTE xdata *pwrite; // xdata pointer used to generate movx
EA_Save = EA; // Save current EA
EA = 0; // Turn off interrupts
pwrite = (BYTE xdata *)(Page_Address); // Set write pointer to Page_Address
PSCTL = 0x03; // Enable flash erase and writes
FLKEY = 0xA5; // Write flash key sequence to FLKEY
FLKEY = 0xF1;
*pwrite = 0x00; // Erase flash page using a
// write command
PSCTL = 0x00; // Disable flash erase and writes
EA = EA_Save; // Restore state of EA
}
//-----------------------------------------------------------------------------
// USBReset
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) BYTE* PageAddress
//
// Writes data to the page of FLASH located at PageAddress
//-----------------------------------------------------------------------------
void Page_Write (BYTE* PageAddress) small
{
BYTE EA_Save; // Used to save state of global
// interrupt enable
BYTE xdata *pwrite; // Write Pointer
BYTE xdata *pread; // Read Pointer
UINT x; // Counter for 0-512 bytes
pread = (BYTE xdata *)(TempStorage);
EA_Save = EA; // Save EA
EA = 0; // Turn off interrupts
pwrite = (BYTE xdata *)(PageAddress);
PSCTL = 0x01; // Enable flash writes
for(x = 0; x<FLASH_PAGE_SIZE; x++) // Write 512 bytes
{
FLKEY = 0xA5; // Write flash key sequence
FLKEY = 0xF1;
*pwrite = *pread; // Write data byte to flash
pread++; // Increment pointers
pwrite++;
}
PSCTL = 0x00; // Disable flash writes
EA = EA_Save; // Restore EA
}
//-----------------------------------------------------------------------------
// State_Machine
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Determine new state and act on current state
//-----------------------------------------------------------------------------
void State_Machine(void)
{
switch (M_State)
{
case
ST_WAIT_DEV: // Stay in Wait State
break;
case
ST_IDLE_DEV: // Stay in Idle State
break;
case ST_RX_SETUP:
Receive_Setup(); // Decode host Setup Message
break;
case ST_RX_FILE:
Receive_File(); // Receive File data from host
break;
case ST_TX_ACK:
M_State = ST_RX_FILE; // Ack complete, continue RX data
break;
case ST_TX_FILE: // Send file data to host
if(BytesToWrite > MAX_BLOCK_SIZE)
{
BulkOrInterruptIn(&gEp1InStatus, (BYTE*)(ReadIndex),MAX_BLOCK_SIZE);
//BytesToWrite -= MAX_BLOCK_SIZE;
//ReadIndex += MAX_BLOCK_SIZE;
// Try to write a second packet to the fifo here
if(BytesToWrite > MAX_BLOCK_SIZE)
{
BulkOrInterruptIn(&gEp1InStatus,
(BYTE*)(ReadIndex),MAX_BLOCK_SIZE);
}
else
{
BulkOrInterruptIn(&gEp1InStatus,
(BYTE*)(ReadIndex),BytesToWrite);
}
}
else
{
BulkOrInterruptIn(&gEp1InStatus, (BYTE*)(ReadIndex),BytesToWrite);
//BytesToWrite = 0;
//ReadIndex += BytesToWrite;
}
//BlocksWrote++;
if ((BlocksWrote%8) == 0)
{
Led2 = ~Led2;
}
if (BlocksWrote == NumBlocks)
{
Led2 = 0;
}
break;
default:
M_State = ST_ERROR; // Unknown State, stay in Error State
break;
}
}
//-----------------------------------------------------------------------------
// Receive_Setup
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Determines whether a read or write request has been received
// Initializes variables for either a read or write operation
//
//-----------------------------------------------------------------------------
void Receive_Setup(void)
{
if (Buffer[0] == READ_MSG) // Check See if Read File Setup
{
PageIndex = 0; // Reset Index
NumBlocks = LengthFile[2]; // Read NumBlocks from flash stg
NumBlocks = (NumBlocks > MAX_NUM_BLOCKS)? MAX_NUM_BLOCKS: NumBlocks;
Buffer[0] = SIZE_MSG; // Send host size of transfer message
Buffer[1] = LengthFile[1];
Buffer[2] = LengthFile[0];
BulkOrInterruptIn(&gEp1InStatus, &Buffer, 3);
M_State = ST_TX_FILE; // Go to TX data state
BlocksWrote = 0;
BytesToWrite = BytesToRead;
ReadIndex = PageIndices[0];
Led2 = 1;
}
else // Otherwise assume Write Setup Packet
{
BytesToRead = Buffer[1] + 256*Buffer[2];
NumBlocks = (BYTE)(BytesToRead/MAX_BLOCK_SIZE); // Find NumBlocks
if (NumBlocks > MAX_NUM_BLOCKS) // State Error if transfer too big
{
M_State = ST_ERROR;
}
else
{
if (BytesToRead % MAX_BLOCK_SIZE)
{
NumBlocks++; // Increment NumBlocks
// for last partial block
}
TempStorage[0].Piece[0] = Buffer[2];
TempStorage[0].Piece[1] = Buffer[1];
TempStorage[0].Piece[2] = NumBlocks;
// Write Values to Flash
Page_Erase(LengthFile); // Store file data to flash
Page_Write(LengthFile);
PageIndex = 0; // Reset Index
BlockIndex = 0;
BlocksRead = 0;
Led1 = 1;
M_State = ST_RX_FILE; // Go to RX data state
}
}
}
//-----------------------------------------------------------------------------
// Receive_Setup
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Increments BlockRead and BlockIndex
// After every 8 packets or at the end of the transfer, sends a handshake
// signal to the host (0xFF)
// Sets the state of the device
//
//-----------------------------------------------------------------------------
void Receive_File(void)
{
BlocksRead++; // Increment
BlockIndex++;
// If multiple of 8 or last packet, disable interrupts,
// write page to flash, reset packet index, enable interrupts
// Send handshake packet 0xFF to host after FLASH write
if ((BlockIndex == (BLOCKS_PR_PAGE)) || (BlocksRead == NumBlocks))
{
Page_Erase((BYTE*)(PageIndices[PageIndex]));
Page_Write((BYTE*)(PageIndices[PageIndex]));
PageIndex++;
Led1 = ~Led1;
BlockIndex = 0;
Buffer[0] = 0xFF;
// Place Handshake packet (0xFF) on the OUT FIFO
BulkOrInterruptIn (&gEp1InStatus, (BYTE*)&Buffer, 1);
}
// Go to Idle state if last packet has been received
if (BlocksRead == NumBlocks)
{
M_State = ST_IDLE_DEV;
Led1 = 0;
}
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -