⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 periph.c

📁 cypress的usb接ata源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#pragma NOIV               // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
//   File:      periph.c
//   Contents:   Hooks required to implement USB peripheral function.
//
//   Copyright (c) 1997 AnchorChips, Inc. All rights reserved
//
// $Archive: /USB/atapifx2/software/periph.c $
// $Date: 1/23/02 9:36a $
// $Revision: 58 $
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "fx2regs.h"
#include "gpif.h"
#include "atapi.h"

extern BOOL   Sleep;
extern BOOL   Rwuen;
extern BOOL   Selfpwr;

void clearResetLine();
void clearResetLine();

WORD cbwTagLow;          // Tag from the most recent CBW packet
WORD cbwTagHi;
BYTE currentState;

DWORD dataTransferLen;
DWORD driveCapacity;
bit scsi;

BYTE xdata SCSIInquiryData[44];
BYTE code SCSIInquiryDataSource[44] = 
{
0x00,           //= Device class
//0x0e,           // Device class RBC
0x00,           //= RMB bit is set by inquiry data
0x00,           //
0x01,           //= Data format = 1
0x00,           //= Additional length   (changed to 0 from 0x75)
0x00, 0x00, 0x00,   //
0x43, 0x79, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, // = Manufacturer "Cypress "
0x41, 0x54, 0x41, 0x50, 0x49, 0x20, 0x52, 0x65, 0x66, 0x20, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, // = Product(MS Ref Design)
0x30, 0x31, 0x2E, 0x30, // = Revision
0x30, 0x39, 0x2F, 0x32, 0x34, 0x2F, 0x39, 0x38, // = Vendor unique (chopped off)

};

//-----------------------------------------------------------------------------
// Task Dispatcher hooks
//   The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------

void TD_Init(void)             // Called once at startup
{
   // set the CPU clock to 48MHz
   CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ;
   WRITEDELAY();

   // set the slave FIFO interface to 48MHz
   IFCONFIG |= 0x40;
   WRITEDELAY();

   // init state/reset variables
   currentState = UNCONFIGURED;

   initUSB();                 // configure output ports and endpoint params
   mymemmovexx(&GPIF_WAVE_DATA, (BYTE xdata *) WaveDataPio0, 64);          // load wave forms in memory
   mymemmovexx(SCSIInquiryData, (BYTE xdata *) SCSIInquiryDataSource, sizeof(SCSIInquiryDataSource));

   resetATAPIDevice();

   if (SCSITestUnitReady())
      SCSITestUnitReady();


   ATAPIIdDevice();        // Get serial number

   if (SCSITestUnitReady())
      SCSITestUnitReady();

   intrfcSubClass = USB_MS_SCSI_TRANSPARENT_SUBCLASS;  // IDE devices are treated as transparent SCSI.  Normally would use RBC, but it's not in Microsoft's INF file.
   if (scsi) 
   {
      SCSIInquiryToATAPI();            // Set intrfcSubClass to tell Zip and MO from CD-ROM
   }
}


char const code usbcString[] = "USBC";
void TD_Poll(void)             // Called repeatedly while the device is idle
{
   WORD    count = 0;

   // check EP2 EMPTY(busy) bit in EP2468STAT (SFR), core set's this bit when FIFO is empty
   if(!(EP2CS & bmEPEMPTY))   
      { 
      // Check for "USBC"
      if ( *((DWORD xdata *)EP2FIFOBUF) != *((DWORD xdata *) usbcString))
         {
         // error -- Stall the endpoint no matter what
         EP2CS = bmEPSTALL;
         }
      else
         {
         if (EP2BC < EP2FIFOBUF[CBW_CBW_LEN]+CBW_DATA_START)
            {
             // Error -- Stall the endpoint
            EP2CS = bmEPSTALL;
            }
         else            
            {
            // Good packet, forward to the device.
            processCBW();  
            }
         }
      }
}


//-----------------------------------------------------------------------------
// Support functions for specific device
//-----------------------------------------------------------------------------

void initUSB(void)
{

   PORTACFG = 0x01;       // set up PORTA for port I/O  
   OEA = 0xBE;            // PORTA is all output except PA.0(INTRQ) AND PA.6(DASP#)
   OUTATAPI = ATAPI_IDLE_VALUE;  // includes RESET line PA.0

   // Make Interrupt 0 level triggered
   IT0 = 0;

   //CPUCS = 0x0c;        // set clock to 24MHz.      
   IFCONFIG = 0x8A | bmGSTATE;      // b7=0: use FCLK pin to clock FIFO, GPIF; =1: use internal 30/48 MHz clock(=30)
   CPUCS = 0x14;        // set clock to 48MHz.      
   //IFCONFIG = 0xcA;      // b7=0: use FCLK pin to clock FIFO, GPIF; =1: use internal 30/48 MHz clock(=48)
   FIFOPINPOLAR = 0x00;    // ff pin is active low

   PINFLAGSAB = 0x00;    // FLAGA PF for FIFO selected by FIFOADR[1..0]
   PINFLAGSCD = 0x00;    // FLAGB FF for FIFO selected by FIFOADR[1..0]

   // Set up interrupt parameter
//   INTSETUP |= bmINT4;  // Allow FIFO and GPIF interrupts

   // GPIF and CTL configuration
   GPIFCTLCFG = 0x00;   // 
   GPIFIDLECTL = 0x77;  // x111x111 - CTL3 not enabled
                        // ||||||||_CTL0 = 1 during idle
                        // |||||||__CTL1 = 1 during idle
                        // ||||||___CTL2 = 1 during idle
                        // ||||_____CTL0 output enable
                        // |||______CTL1 output enable
                        // ||_______CTL2 output enable
                        // 
   GPIFIDLECS = 0;      // tristate data bus during idle interval
   GPIFWFSELECT = (2 << 6) | (3 << 4) | (0 << 2) | (1);    // Single write is 2, Single read is 3, write is 0, Read is waveform 1 

   // Endpoint initialization
   EP2CFG = 0xA0;           // ep2 is valid BULK OUT 512 quad buffered
   EP2FIFOCFG = 0x05;       // WORDWIDE=1M MANUAL
   EP2FIFOPFH = 0x00;       // PF=0 when BC > PF -> Decis=0 (1 byte in FIFO)
   EP2FIFOPFL = 0x00;       // PF and BC refer to the current pkt -> PKTSTAT=0
   EP2GPIFPFSTOP = 0;       // Do not stop on PF

   EP8CFG = 0xE0;          // ep8 is valid BULK IN 512 double buffered
   EP8FIFOCFG = 0x05;      // set EP8:  0x05=MANUAL, 0x0D=AUTOIN

   // mark all unused endpoints invalid - setting each reg to 0x22 instead of just clearing
   // the valid bit to save code space.  0x22 basically sets all of these endpoints to 
   // not valid, bulk, double 512 buffered.
   EP1OUTCFG = EP1INCFG = EP4CFG = EP6CFG = 0x22;

   // disbable Auto Arm
   REVCTL |= bmNOAUTOARM;

   // arm the OUT endpoint.  By default OUT endpoints come up unarmed.
   ResetAndArmEp2();

}



// Stalls EP2OUT endpoint.
void stallEP2OUT()
{
   // Check to see if stall is needed.  If it is, STALL the endpoint.
   // After we have set the STALL, make sure we didn't get the last packet while we were STALLing.
   WORD x;

   if (EP2468STAT & bmEP2EMPTY)
      x = 0;
   else
      x = EP2FIFOBCL + (EP2FIFOBCH << 8) + EP2BC;

//   if (dataTransferLen > ((x + 1) & 0xfffe))     // Round up to allow for odd xfer lengths
   if (dataTransferLen > x)     

   {
      EP2CS |= bmEPSTALL;

      EZUSB_Delay(100);

      if (EP2CS & bmEPSTALL)
         x=1234;

      // If the host has already cleared the STALL, the EP will be empty here, but we will drop safely through the if()
      if (EP2468STAT & bmEP2EMPTY)
         x = 0;
      else
         x = EP2FIFOBCL + (EP2FIFOBCH << 8) + EP2BC;
   
      if (dataTransferLen > x)     
         {
         ResetAndArmEp2();    // Stall no longer needed
         EP2CS = 0;           // Clear stall bit
         }
   }
}   

void processCBW()
{
   // Save the tag for use in the response
   cbwTagLow = *((WORD volatile xdata*)(EP2FIFOBUF+CBW_TAG));
   cbwTagHi =  *((WORD volatile xdata*)(EP2FIFOBUF+CBW_TAG+2));

   // Get the length (convert from little endian)
   *(((BYTE *) &dataTransferLen)+3) = (EP2FIFOBUF+CBW_DATA_TRANSFER_LEN_LSB)[0];  // "Residue"
   *(((BYTE *) &dataTransferLen)+2) = (EP2FIFOBUF+CBW_DATA_TRANSFER_LEN_LSB)[1];  // "Residue"
   *(((BYTE *) &dataTransferLen)+1) = (EP2FIFOBUF+CBW_DATA_TRANSFER_LEN_LSB)[2];  // "Residue"
   *(((BYTE *) &dataTransferLen)+0) = (EP2FIFOBUF+CBW_DATA_TRANSFER_LEN_LSB)[3];  // "Residue"

//   writePIO8(ATAPI_NULL_REG, dataTransferLenLSW);

   // Our personal "firmware update" command
   if (EP2FIFOBUF[0xf] == 0xfb && !(EP2FIFOBUF[CBW_FLAGS] & CBW_FLAGS_DIR_BIT))
      {
      // relinquish control of the bulk buffer occupied by the CBW
      EP2BCL = 0x80;     

      // Write the EEPROM
      EEPROMWrite(dataTransferLenLSW);
      sendUSBS(USBS_PASSED);
      }
   else if (EP2FIFOBUF[0xf] == 0xfa && (EP2FIFOBUF[CBW_FLAGS] & CBW_FLAGS_DIR_BIT))
      {
      extern BYTE code StringDscr3;
      BYTE len = (&StringDscr3)[0]<<1;

      len = max(len, dataTransferLenLSW);

      // relinquish control of the bulk buffer occupied by the CBW
      EP2BCL = 0x80;     

      mymemmovexx(EP8FIFOBUF, (char xdata *)(&StringDscr3)+2, len);
      waitForInBuffer();
      EP8BCH = 0; 
      EP8BCL = len; 
      sendUSBS(USBS_PASSED);
      }
   else if (EP2FIFOBUF[CBW_FLAGS] & CBW_FLAGS_DIR_BIT || !dataTransferLen)
      {
      currentState = RECEIVED_IN_CMD;
      if (scsi)
         sendUSBS(generalSCSIInCommand());
      else
         sendUSBS(generalIDEInCommand());
      }
   else
       {
       currentState = RECEIVED_OUT_CMD;
       if (scsi)
           sendUSBS(generalSCSIOutCommand());
       else
           sendUSBS(generalIDEOutCommand());
       }
   currentState = WAIT_FOR_CBW;
}   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -