📄 eeprom.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 + -