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

📄 eeprom.c

📁 cy68013a USB2.0 highspeed mass storage source code
💻 C
字号:
//-----------------------------------------------------------------------------
//   File:      eeprom.c
//   Contents:   EEPROM update firmware source.  (Write only)
//
//   indent 3.  NO TABS!
//
//   Copyright (c) 2002 Cypress Semiconductor
//
// $Workfile: eeprom.c $
// $Date: 3/30/05 2:38p $
// $Revision: 2 $
//-----------------------------------------------------------------------------
#include "fx2.h"
#include "fx2regs.h"
#include "atapi.h"
#include "globals.h"

void EEWaitForStop();
bit EEWaitForAck();
static void EEStartAndAddr();
extern void WaitForEEPROMWrite();
///////////////////////////////////////////////////////////////////////////////////////

// Write the entire EEPROM
bit EEPROMWrite(WORD len, WORD addr)
{
   WORD i;
   
   for (addr = 0; addr < len && addr < dataTransferLen; addr += wPacketSize)
      {
      // Wait for host to send data
      while(EP2468STAT & bmEP2EMPTY)       
         ;

      // Write the data from the USB buffer to the EEPROM
      for (i = 0; i < wPacketSize && addr + i < len; i+= EEPROM_PAGE_SIZE)
         {
         if (EEPROMWriteBlock(addr+i, EP2FIFOBUF+i, EEPROM_PAGE_SIZE))
            return(1);
         }

      // Give up the buffer
      EP2BCL = 0x80;     
      }
   dataTransferLen = 0;
   return(0);
}
// Write up to one page of data to the EEPROM.
// Returns 0 on success, 1 on failure
// Normally called within a while() loop so that errors are retried:
// while (EEPROMWriteBlock(....))
//    ;
bit EEPROMWriteBlock(WORD addr, BYTE xdata * ptr, BYTE len)
{
   // Make sure the i2c interface is idle
   EEWaitForStop();
   
   // write the START bit and i2c device address
   EEStartAndAddr();

   if(EEWaitForAck())
      return(1);

   // write the eeprom offset
   if (addr > 0x100) 
      {
      I2DAT = MSB(addr);
      if(EEWaitForAck())
         return(1);
      }
   I2DAT = LSB(addr);

   // If the EEPROM doesn't respond, set the STOP bit to idle the bus, then return error
   if(EEWaitForAck())
      {
      I2CS |= bmSTOP;	//	; Set the STOP bit
      EEWaitForStop();
      return(1);
      }

   // Write the data block
   for(; len != 0; len--)
   {
      I2DAT = *ptr++;
      if(EEWaitForDone())
         return(1);
   }	
   I2CS |= bmSTOP;
   WaitForEEPROMWrite();
   return 0;
}

void EEStartAndAddr()
{
      I2CS = bmSTART;
      I2DAT = eepromAddr << 1;
}

// 0x2e in assembly, less than 0x20 with compiler optimization!!
void WaitForEEPROMWrite()
{
   EEWaitForStop();
waitForBusy:
	EEStartAndAddr();

   EEWaitForDone();
   I2CS |= bmSTOP;	//	; Set the STOP bit
   EEWaitForStop();

   if (!(I2CS & bmACK))  // If no ACK, try again.
      goto waitForBusy;
}

void EEWaitForStop()
{
   // Data should not be written to I2CS or I2DAT until the STOP bit returns low.
   while (I2CS & bmSTOP)
      ;
}

// Returns 0 on success, 1 on failure
bit EEPROMRead(WORD addr, WORD length, BYTE xdata *buf)
{
   BYTE i;

   // Make sure the i2c interface is idle
   EEWaitForStop();
   
   // write the START bit and i2c device address
   EEStartAndAddr();

   if(EEWaitForAck())
      return(1);

   // write the eeprom offset
   if (addr > 0x100) 
     {
     I2DAT = MSB(addr);
     if(EEWaitForAck())
        return(1);
     }
   I2DAT = LSB(addr);

   // If the EEPROM doesn't respond, set the STOP bit to idle the bus, then return error
   if(EEWaitForAck())
      {
      I2CS |= bmSTOP;	//	; Set the STOP bit
      EEWaitForStop();
      return(1);
      }

   I2CS = bmSTART;

   // send the read command
   I2DAT = (eepromAddr << 1) | 0x01;
   if(EEWaitForDone())
      return(1);

   // read dummy byte
   i = I2DAT;
   if(EEWaitForDone())
      return(1);

   for (i=0; i < (length - 1); i++)
   {
      *(buf+i) = I2DAT;
      if(EEWaitForDone())
         return(1);
   }
   
   I2CS = bmLASTRD;
   if(EEWaitForDone())
      return(1);

   *(buf+i) = I2DAT;
   if(EEWaitForDone())
      return(1);

   I2CS = bmSTOP;

   i = I2DAT;
   return(0);
}


// Return 0 for ok, 1 for error
bit EEWaitForDone()
{
   BYTE i;

   while (!((i = I2CS) & 1))  // Poll the done bit
      ;
   if (i & bmBERR)
      return 1;
   else
      return 0;
}

// Return 0 for ok, 1 for error
// Same as wait for done, but checks for ACK as well
bit EEWaitForAck()
{
   BYTE i;

   while (!((i = I2CS) & 1))  // Poll the done bit
      ;
   if (i & bmBERR)
      return 1;
   else if (!(i & bmACK))
      return 1;
   else
      return 0;
}

⌨️ 快捷键说明

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