Hi
LM4F232 on-chip EEPROM is not supporting byte read/write operations (supports only word read/write) I did modify EEPROMProgram() function to support byte write operations. i.e. read complete word and then append required bytes and then write back.
works fine when I debug step by step but it hangs in EEPROM busy check while loop on Run/Go command. i.e. EEPROM_EEDONE_WORKING flag stays at ‘1. I am not sure why it happens and how can modify below code to avoid this. Flash write error appear on reprogramming chip so I have to erase memory using LM flash programmer to reprogram again.
Using CodeRed IDE () and Red Probe + debugger.
Can you please help to find any missing steps.
typedef enum EEPROM_PROGRAM_TYPE
{
WRITE_DATA_BYTES = 0,
FILL_CONSTANT_DATA
}EEPROM_PROGRAM_TYPE;
SysCtlPeripheralEnable(S
// init code
SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0);
EEPROMInit();
UINT32 EEPROMProgram(UINT8 *pucData, UINT32 ulAddress, UINT32 ulCount,
EEPROM_PROGRAM_TYPE type, UINT8 fillDataByte)
{
UINT32 ulStatus = 0;
UINT16 numberOfBytesWritten = 0; // initialize number of bytes written count to zero
UINT16 startWordAlignOffset = (UINT16)(ulAddress % (UINT16)4); // get word align offset byte count
UINT16 numberOfWordsToWrite = (UINT16)((ulCount + (startWordAlignOffset) + (UINT32)3) / (UINT16)4);
UINT8 tempWord[4];
UINT16 index;
// Check parameters in a debug build.
ASSERT(pucData);
ASSERT(ulAddress < SIZE_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
ASSERT((ulAddress + ulCount) <= SIZE_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
// comment this because code is modified to support byte write operations
//ASSERT((ulAddress & 3) == 0);
//ASSERT((ulCount & 3) == 0);
// word align incoming address
ulAddress = (ulAddress & 0xFFFFFFFC);
// Make sure the EEPROM is idle before we start.
do
{
// Read the status.
ulStatus = (HWREG(EEPROM_EEDONE) & (0x0000013D));
}
while(ulStatus & EEPROM_EEDONE_WORKING);
// Set the block and offset appropriately to program the first word.
HWREG(EEPROM_EEBLOCK) = EEPROMBlockFromAddr(ulAddress);
HWREG(EEPROM_EEOFFSET) = OFFSET_FROM_ADDR(ulAddress);
// Write each word in turn.
while(numberOfWordsToWrite)
{
// This is a workaround for a silicon problem on Blizzard rev A. We
// need to do this before every word write to ensure that we don't
// have problems in multi-word writes that span multiple flash sectors.
if(CLASS_IS_BLIZZARD && REVISION_IS_A0)
{
EEPROMSetSectorMask(ulAddress);
ulAddress += 4;
}
// read current data stored at this address without incrementing address
*((UINT32*)(&tempWord[0])) = HWREG(EEPROM_EERDWR);
// read offset bytes but make sure we not reading more than request numberOfBytesWritten
for(index = startWordAlignOffset; (index < (UINT16)4) && (numberOfBytesWritten < ulCount); index++)
{
if(type == WRITE_DATA_BYTES)
{
// incoming data from offset address (in case its not word aligned
// then we should not over write other bytes
tempWord[index] = pucData[numberOfBytesWritten];
}
else
{
// fill constant data
tempWord[index] = fillDataByte;
}
numberOfBytesWritten++;
}
// Write the next word through the autoincrementing register.
HWREG(EEPROM_EERDWRINC) = *((UINT32*)(&tempWord[0]));
// Wait for the write to complete.
do
{
// Read the status.
ulStatus = (HWREG(EEPROM_EEDONE) & (0x0000013D));
}
while(ulStatus & EEPROM_EEDONE_WORKING);
// Make sure we completed the write without errors. Note that we
// must check this per-word because write permission can be set per
// block resulting in only a section of the write not being performed.
if(ulStatus & (EEPROM_EEDONE_NOPERM | EEPROM_EEDONE_INVPL))
{
// An error was reported that would prevent the values from
// being written correctly.
if(CLASS_IS_BLIZZARD && REVISION_IS_A0)
{
EEPROMClearSectorMask();
}
return(ulStatus);
}
// Move on to the next word.
numberOfWordsToWrite--;
startWordAlignOffset = 0;
// Do we need to move to the next block? This is the case if the
// offset register has just wrapped back to 0.
if(HWREG(EEPROM_EEOFFSET) == 0)
{
HWREG(EEPROM_EEBLOCK) += 1;
}
}
// Clear the sector protection bits to prevent possible problems when
// programming the main flash array later.
if(CLASS_IS_BLIZZARD && REVISION_IS_A0)
{
EEPROMClearSectorMask();
}
// Return the current status to the caller.
return(HWREG(EEPROM_EEDONE));
}