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

📄 periph.c

📁 Cy68013的应用——USB2.0接口转IDE、CF卡接口
💻 C
📖 第 1 页 / 共 2 页
字号:
            // switch to PIO0
            else 
            {
               mymemmovexx(&GPIF_WAVE_DATA, (BYTE xdata *) WaveDataPioUDMA, 8 + 4);
               mymemmovexx(&(GPIF_WAVE_DATA) + 32, (BYTE xdata *) WaveDataPioUDMA+32, 8 + 4);
            }
   
         }
      }
   }

   // 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 entire EEPROM
      EEPROMWrite(dataTransferLenLSW);
      sendUSBS(USBS_PASSED);
      }

   else if (directionIn || !dataTransferLen)
      {
      currentState = RECEIVED_IN_CMD;
      if (bScsi)
         sendUSBS(generalSCSIInCommand());
      else
         sendUSBS(generalIDEInCommand());
      }
   else
       {
       currentState = RECEIVED_OUT_CMD;
       if (bScsi)
           sendUSBS(generalSCSIOutCommand());
       else
           sendUSBS(generalIDEOutCommand());
       }
   currentState = WAIT_FOR_CBW;
}   



void sendUSBS(BYTE passOrFail)
{
   bit done = 0;
   
   // generalIDEx/generalSCSIx command returns here with passOrFail status bit
   // which is re-cast as the error byte of CSW

   while (!done)
   {
      if( (!(EP8CS & bmEPFULL)) && (!(EP8CS  & bmEPSTALL)))      // Wait for an available buffer
      {

         // Eliminate any data in the OUT endpoint or FIFO
         // This can happen in the Ho > Dn and Ho > Do cases.
         ResetAndArmEp2();

         // If we're in phase error, STALL the OUT endpoint to make sure the host resets us (and the drive)
         if (passOrFail == USBS_PHASE_ERROR)
            {
            EP2CS = bmEPSTALL;
            phaseErrorState = 1;
            }

         // Fill the buffer & send the data back to the host
         AUTOPTRL2 = LSB(EP8FIFOBUF);

         XAUTODAT2 = 'U';        // Believe it or not, this is pretty efficient!
         XAUTODAT2 = 'S';
         XAUTODAT2 = 'B';
         XAUTODAT2 = 'S';

         XAUTODAT2 = MSB(cbwTagLow);
         XAUTODAT2 = LSB(cbwTagLow);
         XAUTODAT2 = MSB(cbwTagHi);
         XAUTODAT2 = LSB(cbwTagHi);

         // have to store LSB first
         XAUTODAT2 = ((BYTE *)&dataTransferLen)[3];    // "Residue"
         XAUTODAT2 = ((BYTE *)&dataTransferLen)[2];    // "Residue"
         XAUTODAT2 = ((BYTE *)&dataTransferLen)[1];    // "Residue"
         XAUTODAT2 = ((BYTE *)&dataTransferLen)[0];    // "Residue"
         
         XAUTODAT2 = passOrFail;                 // Status
         EP8BCH = 0;
         EP8BCL = 13;
         done = 1;
      }
   }

   // Stall the IN endpoint if we're in phase error state.
   if (phaseErrorState)
      {
      while( !(EP8CS & bmEPEMPTY) )
         ;
      EP8CS = bmEPSTALL;
      }

}   

void failedIn()
{
   // Stall if the host is still expecting data.  Make sure
   // endpoint is empty before doing the stall.
   if (dataTransferLen)
      {
      if (!bShortPacketSent && (SHORT_PACKET_BEFORE_STALL))
         {
         while( !(EP8CS & bmEPEMPTY) )
            ;
         EP8BCH = 0;    // Terminate with NULL packet, then STALL.  This 
         EP8BCL = 0;    // addresses an issue with the current EHCI driver (1/02)
         }

      while( !(EP8CS & bmEPEMPTY) )
         ;

      EP8CS = bmEPSTALL; // TPM
      }
}

bit waitForBusyBit()
{
    BYTE driveStatus;

    do
    {
        driveStatus = readATAPI_STATUS_REG();
    }
    while((driveStatus & (ATAPI_STATUS_BUSY_BIT)));    // Do-while
    
    // Some drives clear the busy bit asynchronously.  Read the reg one more time to be sure.
    driveStatus = readATAPI_STATUS_REG();

    if ((driveStatus & ATAPI_STATUS_ERROR_BIT))
        return(USBS_FAILED);
    else
        return(USBS_PASSED);
}   

void mymemmovexx(BYTE xdata * dest, BYTE xdata * src, WORD len)
{
    while (len--)
    {
        *dest++ = *src++;
    }
}    

void mymemmove(BYTE data * dest, BYTE data * src, BYTE len)
{
    while (len--)
    {
        *dest++ = *src++;
    }
}    

// Wait for interrupt from the drive.
// Clears the interrupt source on the drive, the INT0 is level triggered, so it clears automagically .
// 
// Returns:
//      USBS_FAILED -- Timeout
bit waitForIntrq(BYTE timeoutEnable)
{
   WORD timeoutCtr = PROCESS_CBW_TIMEOUT_RELOAD;

   while (timeoutCtr)
      {
      #if REVC_4611_BOARD
      WAKEUPCS = bmWU | bmDPEN;     //  Disable wakeup from the INTRQ pin.  Only wake on D+
      if (!(WAKEUPCS & 0x40))
         break;

      #else
      if (IOA & 1)
         break;
      #endif

      timeoutCtr -= timeoutEnable;                  
      }

   if (!timeoutCtr)
      return(USBS_FAILED);
   
   return(USBS_PASSED);
}


//-----------------------------------------------------------------------------
// USB Interrupt Handlers
//   The following functions are called by the USB interrupt jump table.
//-----------------------------------------------------------------------------


// Setup Data Available Interrupt Handler
void ISR_Sudav(void) interrupt 0
{
   EZUSB_IRQ_CLEAR();
   INT2CLR = bmSUDAV;         // Clear SUDAV IRQ
   SetupCommand();
}


void ISR_Ures(void) interrupt 0
{
   // whenever we get a USB reset, we should revert to full speed mode
   pConfigDscr = pFullSpeedConfigDscr;
   ((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR;
   pOtherConfigDscr = pHighSpeedConfigDscr;
   ((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR;
   wPacketSize = FS_BULK_PACKET_SIZE;
   EP8FIFOPFH = 0x80;
   EP8FIFOPFL = 0x60;

   EP8AUTOINLENH = MSB(wPacketSize);
   EP8AUTOINLENL = LSB(wPacketSize);


   FIFORESET = 8;
   
   ResetAndArmEp2();

   // clear the stall and busy bits that may be set
   EP2CS = 0;     // set EP2OUT to empty and clear stall
   EP8CS = 0;     // set EP8OUT to empty and clear stall

   // Initialize USB variables to make chapter 9 happy
   AlternateSetting = Configuration = 0;

   EZUSB_IRQ_CLEAR();   
   INT2CLR = bmURES;        // Clear URES IRQ
   
   if (currentState != UNCONFIGURED)
   {
      EA = 0;
      // force a soft reset after the iret.
      softReset();
   }

}

void ISR_Susp(void) interrupt 0
{
   Sleep = 1;
   EZUSB_IRQ_CLEAR();
   INT2CLR = bmSUSP;
}

void ISR_Highspeed(void) interrupt 0
{
   if (EZUSB_HIGHSPEED())
   {
      pConfigDscr = pHighSpeedConfigDscr;
      ((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR;
      pOtherConfigDscr = pFullSpeedConfigDscr;
      ((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR;
      wPacketSize = HS_BULK_PACKET_SIZE;
      EP8FIFOPFH = 0x89;
      EP8FIFOPFL = 0x90;
   }

   EP8AUTOINLENH = MSB(wPacketSize);
   EP8AUTOINLENL = LSB(wPacketSize);


   EZUSB_IRQ_CLEAR();
   INT2CLR = bmHSGRANT;
}


#define FW_STRETCH_VALUE_5 5

void ResetAndArmEp2()
{
   // adjust stretch to allow for synchronization delay.  We are about
   // to do several back to back writes to registers that require a
   // synchroniztion delay.  Increasing stretch allows us to meet
   // the delay requirement.  See "Synchroniztion Delay" in the Technical
   // Reference Manual for more information
   // Set the stretch to 5
   CKCON = (CKCON&(~bmSTRETCH)) | 5;

   FIFORESET = 2;

   // we're quad-buffered, so we need to arm EP2 four times
   EP2BCL = 0x80;
   EP2BCL = 0x80;
   EP2BCL = 0x80;
   EP2BCL = 0x80;

   // Reset the stretch to 0
   CKCON = (CKCON&(~bmSTRETCH)) | FW_STRETCH_VALUE;
}

BYTE checkCBW()
{
   // Check for "USBC"
   if ( *((DWORD xdata *)EP2FIFOBUF) != *((DWORD xdata *) usbcString))
      {
      return(USBS_FAILED);
      }
   else
      {
      if (EP2BC != 31)
          // Error -- Stall the endpoint
         return(USBS_FAILED);
      }
   return(USBS_PASSED);
}

⌨️ 快捷键说明

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