
LPC2129 - Flash as EEPROM, garbage output
I'm trying to use code from AN11008, using FLASH as EEPROM, modified to store a single, short text file. I think my read functions work properly, but writing to EEPROM seems to fail. I'm having trouble wrapping my head around all of this, so I would really appreciate any help. All functions return properly, but the output is garbled relative to the data input. I know that the read function works, but I am not sure about the storage.
It had been throwing a few errors re: casting pointers in the SetVariableRecord function, but I think I've solved all of those. In testing, I continue to get garbage output files.
Thank you for your help in advance.
/ **** Main file **** /
// Read SD into EEPROM if not already there
f_open(&SD_file_handle, SD_CONFIG_FILENAME, FA_READ);
size = f_size(&SD_file_handle);
if(size<=CONFIG_FILE_SIZE){
debug_printf("* SD writing to EEPROM\n");
f_read(&SD_file_handle, buffer, size, (UINT *)&bytesWritten);
FLASH_WriteConfig(buffer, size);
}
If the file is not present, we recreate it and populate it:
// If file not found, read EEPROM, create the file, and populate it
if ( !FLASH_GetConfig(buffer, CONFIG_FILE_SIZE) ) { } // Error
else { // Create file and populate
f_open(&SD_file_handle, SD_CONFIG_FILENAME, FA_CREATE_NEW | FA_WRITE | FA_READ);
f_write(&SD_file_handle, buffer, CONFIG_FILE_SIZE, (UINT *) &bytesWritten);
}
/ **** Modified Flash_NVOL - Refers to methods in iap.c**** /
// No sector addressing, since we only want to store one (long) variable
#define SECTOR_NUM 17 //last sector
#define SECTOR_STARTADDR 0x0003E000
#define SECTOR_SIZE 0x2000 //8KB
#define CONFIG_FILE_SIZE 126
typedef struct _Variable_Record {
uint8_t Flags; // flags indicate variable status
uint8_t Data[CONFIG_FILE_SIZE]; // variable data
uint8_t Checksum; // 2's complement checksum of id and data
}__attribute__((packed)) VARIABLE_RECORD;
// Write configuration record
int FLASH_WriteConfig(uint8_t *pValue, uint8_t Size) {
VARIABLE_RECORD VarRec, *pConfig;
uint8_t i;
// check if the config size is acceptable
if (Size > CONFIG_FILE_SIZE || Size == 0)
return -1;
// get current value for config and compare with new value
pConfig = FindLastValidConfig();
if (pConfig != NULL) {
for (i = 0; i < Size; i++) {
if (pValue[i] != pConfig->Data[i])
break;
}
// if new value is the same as the current value then no need to store
// the new value
if (i == Size)
return 0;
}
// get an empty location to store the new config
pConfig = FindFirstEmptyRecord();
if (pConfig == NULL)
return -2;
// assemble variable record
VarRec.Flags = 0xAA;
for (i = 0; i < Size; i++)
VarRec.Data[i] = pValue[i];
VarRec.Checksum = ComputeChecksum(&VarRec);
// store record in sector
if (SetVariableRecord(&VarRec, pConfig->Data)!=0)
return -3;
return 0;
}
// Store the record
static int SetVariableRecord(VARIABLE_RECORD *pVarSrc, uint8_t *pDst) {
uint16_t Byte;
uint8_t Buffer[512];
//uint16_t Offset = pDst - SECTOR_STARTADDR;
VARIABLE_RECORD *pTmpVarRec;
unsigned long Result, tmp;
uint16_t i;
for (i = 0; i < 512; i++)
Buffer[i] = 0xFF;
// Get offset of destination address in 512 byte segment
pTmpVarRec = (VARIABLE_RECORD *) (Buffer + ((int)pDst % 512));
// copy variable record
*pTmpVarRec = *pVarSrc;
for (Byte = 0; Byte < CONFIG_FILE_SIZE; Byte++)
pTmpVarRec->Data[Byte] = pVarSrc->Data[Byte];
// prepare sector
DISABLEIRQ
Result = IAP_PrepareSec(SECTOR_NUM, SECTOR_NUM);
ENABLEIRQ
if (Result != IAP_STA_CMD_SUCCESS)
return -1;
// write to sector
DISABLEIRQ
Result = IAP_CopyRAMToFlash(*pDst - ((int)*pDst % 512), *Buffer, 512);
ENABLEIRQ
if (Result != IAP_STA_CMD_SUCCESS)
return -2;
// verify
DISABLEIRQ
Result = IAP_Compare(*pDst, *pVarSrc->Data, sizeof(VARIABLE_RECORD), &tmp);
ENABLEIRQ
if (Result != IAP_STA_CMD_SUCCESS)
return -3;
return 0;
}
// Read the record
int FLASH_GetConfig(uint8_t *pDst, uint8_t Size) {
VARIABLE_RECORD *pConfig;
uint8_t i;
// check if the destination buffer size is acceptable
if (Size < CONFIG_FILE_SIZE)
return -1;
// get current value for config
pConfig = FindLastValidConfig();
if (pConfig == NULL)
return -2;
for (i = 0; i < CONFIG_FILE_SIZE; i++)
pDst[i] = pConfig->Data[i];
return 0;
}
/ **** Methods in iap.c, tested good with other code **** /
extern unsigned long IAP_PrepareSec(unsigned long StartSecNum, unsigned long EndSecNum);
extern unsigned long IAP_CopyRAMToFlash(unsigned long dst, unsigned long src, unsigned long number);
extern unsigned long IAP_EraseSec(unsigned long StartSecNum, unsigned long EndSecNum);
extern unsigned long IAP_BlankChkSec(unsigned long StartSecNum, unsigned long EndSecNum, unsigned long * pResult);
extern unsigned long IAP_ReadParID(unsigned long * PartID);
extern unsigned long IAP_ReadBootVer(unsigned long * MajorVer, unsigned long * MinorVer);
extern unsigned long IAP_Compare(unsigned long dst, unsigned long src, unsigned long number, unsigned long *offset);
extern void IAP_ReinvokeISP(void);
