📄 fw.c
字号:
//-----------------------------------------------------------------------------
// File: fw.c
// Contents: Firmware frameworks task dispatcher and device request parser
// source.
//
// indent 3. NO TABS!
//
// Copyright (c) 2001 Cypress Semiconductor
//
// $Workfile: fw.c $
// $Date: 7/25/02 12:40p $
// $Revision: 31 $
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "fx2regs.h"
#include "gpif.h"
#include "atapi.h"
#include "custom.h"
#include "globals.h"
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
#define DELAY_COUNT 0x9248*8L // Delay for 8 sec at 24Mhz, 4 sec at 48
// USB constants
// Class specific setup commands
#define SC_BOMS_RESET (0x21) // Hard/soft depends on wValue field 0 = hard
//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
void SetupCommand(void);
void TD_Init(void);
void TD_Poll(void);
//BOOL TD_Suspend(void);
//BOOL TD_Resume(void);
void DisconAndWaitForVbus();
//-----------------------------------------------------------------------------
// Code
//-----------------------------------------------------------------------------
// Task dispatcher
void main(void)
{
BYTE j;
// if we are hung up in a GPIF transfer, abort it. How could this happen? If
// we ended up here after a USB Reset or a MSC Reset, it is possible that the
// GPIF is hung waiting for a transfer that will never complete.
abortGPIF(); // TPM: Unconditionally abort
TD_Init();
EZUSB_IRQ_ENABLE(); // Enable USB interrupt (INT2)
EZUSB_ENABLE_RSMIRQ(); // Wake-up interrupt
INTSETUP |= (bmAV2EN); // Enable INT 2 autovectoring
USBIE |= bmSUDAV | bmSUSP | bmURES | bmHSGRANT; // Enable selected interrupts
Sleep = 0;
noFlashMedia = 1;
// if there is a CF device, increment our deviceCount so that any detected
// ATA/ATAPI devices get assigned to LUN1
#if COMPACT_FLASH
deviceCount++;
#endif
// Allow customization of startup. This macro contains an IF statement
// DO NOT PUT A SEMICOLON after this command.
CUSTOM_SKIP_ID_DEVICE_IF()
if (ATA_ENABLED)
{
resetATAPIDevice();
// keep searching for ATA/ATAPI device until we find at least one
while (!(LunBits[0] || LunBits[1]))
{
for (j=deviceCount;j<MAX_LUN;j++)
{
// Clearing ActiveLunBits clears the bMasterSlaveBit (i.e. we will search for the master the next time
// through this loop)
ActiveLunBits = 0;
bMasterSlave = j;
detectSCSIvsATA();
if (bDevicePresent)
{
LunBits[deviceCount] = ActiveLunBits;
deviceCount++;
}
}
}
for (j=0;j<deviceCount;j++)
{
ActiveLunBits = LunBits[j];
if (bDevicePresent)
{
ATAPIIdDevice();
mymemmove((BYTE *)&DeviceConfigData[j],(BYTE *)&ActiveLunConfigData, sizeof(DEVICE_CONFIG_DATA));
LunBits[j] = ActiveLunBits;
}
}
}
#if COMPACT_FLASH
ActiveLunBits = 0;
bDevicePresent = 1;
bCompactFlash = 1;
bMasterSlave = 0; // CF is always the master
LunBits[0] = ActiveLunBits;
#endif
// wait to enable interrupts until we have completed device identification. why?
// because there is certain information that we won't have until after we have
// detected the drives. Specifically, we may be getting a serial number from
// the drive and we also need to detect how many drives there are so we can respond
// to the GET MAX LUN request correctly.
EA = 1; // Enable 8051 interrupts
TR0 = 1; // Make sure that the timer ISR runs at once. This will take care of the ATA_ENABLE line
// CompactFlash hasn't loaded it's waves yet. Force gear shift on first msg.
currentLunNum = 0xff;
// Renumerate if necessary. Do this by checking the renum bit. If it
// is already set, there is no need to renumerate. The renum bit will
// already be set if this firmware was loaded from an eeprom or if we
// have already been through this code once and we are here again
// because of a USB Reset.
if(!(USBCS & bmRENUM))
{
EZUSB_Discon(TRUE); // renumerate -- Note this is a special version of DISCON for us. It does NOT reconnect
}
// This macro allows customization before we connect to the USB bus.
CUSTOM_WAIT_BEFORE_CONNECT()
#if !VBUS_DETECT
// unconditionally re-connect. If we loaded from eeprom we are
// disconnected and need to connect. If we just renumerated this
// is not necessary but doesn't hurt anything
USBCS &=~bmDISCON;
#endif
CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE; // Set stretch to 0 (after renumeration)
// complete the handshake phase of any pending SETUP transfer.
// The only time this should happen is after a MSC Reset. We want
// to go through all of the EP init code before handshaking the status
// phase of the MSC Reset.
EP0CS |= bmHSNAK;
// Task Dispatcher
while(TRUE) // Main Loop
{
#if BUS_POWERED
if (Sleep)
{
Sleep = 0;
// If we have already touched IFCONFIG, need to drive the ports to a known value
// This helps suspend with CompactFlash. We must check before touching IFCONFIG
// because we briefly sleep on startup and we don't want to turn the GPIF on until
// we are configured by the host.
if (IFCONFIG & 0x3)
{
IFCONFIG = IFCONFIG_DEFAULT & ~3; // Turn off GPIF control of ports B and D.
IOD = IOB = 0;
OEB = OED = 0xff;
EZUSB_Susp(); // Place processor in idle mode.
OEB = OED = 0;
IFCONFIG = IFCONFIG_DEFAULT;
}
else
EZUSB_Susp(); // Place processor in idle mode.
}
#endif
TD_Poll();
}
}
// Standard requests are
#define STANDARD(x) (x | (SETUP_STANDARD_REQUEST<<8))
#define CLASS(x) (x | (SETUP_CLASS_REQUEST << 8))
// Device request parser
void SetupCommand(void)
{
if ((SETUPDAT[0] & SETUP_MASK) == SETUP_STANDARD_REQUEST)
{
switch(SETUPDAT[1])
{
case SC_GET_DESCRIPTOR: // *** Get Descriptor
switch(SETUPDAT[3])
{
case GD_DEVICE: // Device
SUDPTRH = MSB(pDeviceDscr);
SUDPTRL = LSB(pDeviceDscr);
break;
case GD_DEVICE_QUALIFIER: // Device Qualifier
// if high-speed is disabled, we are supposed to STALL this request
if (!CT1)
{
// high-speed is enabled, return the device qualifier
SUDPTRH = MSB(pDeviceQualDscr);
SUDPTRL = LSB(pDeviceQualDscr);
}
else
{
// high-speed is disabled, STALL this request
EZUSB_STALL_EP0();
}
break;
case GD_CONFIGURATION: // Configuration
SUDPTRH = MSB(pConfigDscr);
SUDPTRL = LSB(pConfigDscr);
break;
case GD_OTHER_SPEED_CONFIGURATION: // Other Speed Configuration
// fx2bug - need to support multi other configs
SUDPTRH = MSB(pOtherConfigDscr);
SUDPTRL = LSB(pOtherConfigDscr);
break;
case GD_STRING: // String
{
void *dscr_ptr;
dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2]);
SUDPTRH = MSB(dscr_ptr);
SUDPTRL = LSB(dscr_ptr);
break;
}
#if BUS_POWERED
case GD_HID: // Get-Descriptor: HID
SUDPTRH = MSB(pHIDDscr);
SUDPTRL = LSB(pHIDDscr);
break;
case GD_REPORT: // Get-Descriptor: Report
{
/*
Note: A HID report does not have a length field which the SIE can read to determine how many
bytes to send using the Setup Data Pointer. Therefore we need to 'manually' send the data.
We have limited our report size to less than 64 bytes.
*/
BYTE j;
AUTOPTR1H = MSB(pHIDReportDscr);
AUTOPTR1L = LSB(pHIDReportDscr);
for(j=0;j<64;j++)
EP0BUF[j]=XAUTODAT1;
EP0BCH = 0;
EP0BCL = (WORD)&HIDReportDscrEndOffset-(WORD)&HIDReportDscrOffset; // arm the IN transfer
break;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -