📄 f320_usb_common.c
字号:
// transmit mode without sending a zero length packet
ControlReg |= rbDATAEND;
Ep_Status[0] = EP_IDLE;
}
POLL_WRITE_BYTE (E0CSR, ControlReg);
}
}
}
if (Ep_Status[0] == EP_RX) // See if endpoint should receive
{
POLL_READ_BYTE(E0CSR, ControlReg);
if (ControlReg & rbOPRDY) // Verify packet was received
{
ControlReg = rbSOPRDY;
if (DataSize >= EP0_PACKET_SIZE)
{
FIFO_Read (FIFO_EP0, EP0_PACKET_SIZE, (BYTE *)DataPtr);
DataPtr += EP0_PACKET_SIZE;
DataSize -= EP0_PACKET_SIZE;
DataSent += EP0_PACKET_SIZE;
}
else
{
FIFO_Read (FIFO_EP0, DataSize, (BYTE *)DataPtr);
ControlReg |= rbDATAEND;
Ep_Status[0] = EP_IDLE;
}
if (DataSent == Setup.wLength.i)
{
ControlReg |= rbDATAEND;
Ep_Status[0] = EP_IDLE;
}
if ((Ep_Status[0] == EP_IDLE) && (Setup.bRequest == SET_REPORT))
{
Handle_Set_Report ();
}
if (Ep_Status[0] != EP_STALL) POLL_WRITE_BYTE (E0CSR, ControlReg);
}
}
}
//-----------------------------------------------------------------------------
// Usb_Suspend
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Power down all hardware and halt oscillator when suspend signalling present.
//
//-----------------------------------------------------------------------------
void Usb_Suspend (void) using USB_REGISTER_BANK
{
// Power Down Stuff
P2MDOUT = 0x00; // Port 2 pins set open-drain
P3MDOUT = 0x00; // Port 3 pins set open-drain
USB0XCN &= ~0x43; // Suspend USB Transceiver
CLKSEL = USB_INT_OSC_DIV_2; // USB Clock now uses int osc / 2
CLKMUL = 0x00; // Disable Clock Multiplier
REG0CN |= 0x10; // Voltage regulator in low power mode
OSCICN |= 0x20; // Force internal oscillator suspend
// Power Up Stuff
REG0CN &= ~0x10; // Voltage Regulator in full-power mode
CLKMUL = 0x00; // Reset CLKMUL SFR
CLKMUL |= 0x80; // Enable clock multiplier
Delay_USB (); // Delay for clock multiplier to begin
CLKMUL |= 0xC0; // Initialize the clock multiplier
while (!(CLKMUL & 0x20)); // Wait for multiplier to lock
CLKSEL = SYS_4X_DIV_2; // Restore Clksel SFR
USB0XCN = (USB0XCN & 0xFC) | 0x40; // Enable USB Transceiver
P2MDOUT = 0x0C; // Port 2 pins 2, 3 set push-pull
P3MDOUT = 0x01; // Port 3 pin 1 set push-pull
}
//-----------------------------------------------------------------------------
// Fifo_Read
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// adr - target address
// uNumBytes - number of bytes to read
// pData - destination for read data
//
// Read data from selected endpoint FIFO.
//
//-----------------------------------------------------------------------------
void FIFO_Read (BYTE adr, UINT uNumBytes, BYTE* pData) using USB_REGISTER_BANK
{
data UINT i;
if (uNumBytes) // Check if >0 bytes requested,
{
USB0ADR = (adr); // Set address
USB0ADR |= 0xC0; // Set auto-read and initiate
// first read
// Unload <NumBytes> from the selected FIFO
for (i=0;i<uNumBytes-1;i++)
{
while (USB0ADR & 0x80); // Wait for BUSY->'0' (data ready)
pData[i] = USB0DAT; // Copy data byte
}
USB0ADR = 0; // Clear auto-read
while (USB0ADR & 0x80); // Wait for BUSY->'0' (data ready)
pData[i] = USB0DAT; // Copy data byte }
}
//-----------------------------------------------------------------------------
// Fifo_Write
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// adr - target address
// uNumBytes - number of bytes to write
// pData - location of source data
//
// Writes data to selected endpoint FIFO.
//
//-----------------------------------------------------------------------------
void FIFO_Write (BYTE adr, UINT uNumBytes, BYTE* pData) using USB_REGISTER_BANK
{
data UINT i;
if (uNumBytes) // If >0 bytes requested,
{
while (USB0ADR & 0x80); // Wait for BUSY->'0'
// (register available)
USB0ADR = (adr); // Set address (mask out bits7-6)
// Write <NumBytes> to the selected FIFO
for (i=0;i<uNumBytes;i++)
{
USB0DAT = pData[i];
while (USB0ADR & 0x80); // Wait for BUSY->'0' (data ready)
} }
}
//-----------------------------------------------------------------------------
// Fifo_Purge
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : Index - which endpoint to purge
//
// Purges one packet from the selected endpoint in FIFO.
//
//-----------------------------------------------------------------------------
void FIFO_Purge (BYTE Index) using USB_REGISTER_BANK
{
POLL_WRITE_BYTE (INDEX, Index); // Set index
// Flush IN Fifo
POLL_WRITE_BYTE (EINCSR1, rbInFLUSH);
}
//-----------------------------------------------------------------------------
// Force_Stall
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Sends a procedural stall to the host.
//
//-----------------------------------------------------------------------------
void Force_Stall (void) using USB_REGISTER_BANK
{
POLL_WRITE_BYTE (INDEX, 0);
POLL_WRITE_BYTE (E0CSR, rbSDSTL); // Set the send stall bit
Ep_Status[0] = EP_STALL; // Put the endpoint in stall state
}
//-----------------------------------------------------------------------------
// Delay_USB
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Used for a 500 microsecond pause during hardware configuration.
// There are two identical versions of this routine, one for the main program
// and another for the USB interrupt. This version is for the USB interrupt.
// (assuming 24 MHz system clock)
//
//-----------------------------------------------------------------------------
void Delay_USB (void) using USB_REGISTER_BANK
{
data volatile int x;
for (x = 0;x < 500;x)
x++;
}
//-----------------------------------------------------------------------------
// IsochronousTimer_Start
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine confiures Timer 0 to run at System Clock / 48, and
// enables the Timer 0 interrupt.
//
//-----------------------------------------------------------------------------
void IsochronousTimer_Start(void)
{
TCON |= 0x10;
TMOD |= 0x01;
CKCON |= 0x02;
IE |= 0x02;
}
//-----------------------------------------------------------------------------
// IsochronousTimer_Reset
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine resets the Timer 0 registers to 0.
//
//-----------------------------------------------------------------------------
void IsochronousTimer_Reset(void)
{
TH0 = 0;
TL0 = 0;
}
//-----------------------------------------------------------------------------
// IsochronousTimer_Stop
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine disables Timer 0.
//
//-----------------------------------------------------------------------------
void IsochronousTimer_Stop(void)
{
TCON &= ~0x10;
}
//-----------------------------------------------------------------------------
// Timer0_InterruptServiceRoutine
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This interrupt is serviced whenever Timer 0 overflows. It turns off
// the Isochrnonous data stream, then stops the isochronous time-out timer.
//
//-----------------------------------------------------------------------------
void Timer0_InterruptServiceRoutine(void) interrupt 1
{
Turn_Off_Stream();
IsochronousTimer_Stop();
TF0 = 0;
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -